COMMAND

    gpm

SYSTEMS AFFECTED

    Linux

PROBLEM

    Egmont Koblinger found  following.  The  problem applies to  every
    gpm version known, for example 1.18.1 and 1.19.0.  To exploit this
    problem, gpm-root must be running on a machine and the user  needs
    both login to that machine and physical access to the keyboard and
    mouse.

    gpm-root is a beautiful tool shipped in the gpm package.  It  pops
    up  beautiful  menus  based  on  each  user's own config file when
    Ctrl+Mousebutton is pressed on the console.

    When  the  user  selects  one  of  his/her  favourite utility from
    his/her own list, gpm-root starts this process with the group  and
    supplementary  groups  of  the  gpm-root  daemon.   gpm-root calls
    setuid() first  and setgid()  afterwards, hence  the later  one is
    unsuccessful.   The  authors   completely  forgot  about   calling
    initgroups().

SOLUTION

    Well,  in  1.19.0  version  README,  you  would  notice  following
    fragment:

        =========== MAINTAINANCE
        As of 1.19.0,  gpm is officially  unmaintained. I can't  do it
        any more, and nobody expressed interest in it.

    Here's quick patch:

    diff -u -r -N ../gpm-1.19.0.orig/doc/doc.gpm ./doc/doc.gpm
    --- ../gpm-1.19.0.orig/doc/doc.gpm	Mon Feb  7 23:34:00 2000
    +++ ./doc/doc.gpm	Thu Mar 23 14:37:43 2000
    @@ -1969,6 +1969,12 @@
             be broken by this daemon. Things should be sufficiently secure, but
             if you find a hole please tell me about it.

    +@item -r
    +        Always run commands as root instead of the user who owns the tty.
    +        Implies -u. This is useful for those system administrators who
    +        put menu entries to reboot or halt the system, start or stop
    +        xdm, change keyboard layout etc.
    +
     @item -D
             Do not automatically enter background operation when started,
             and log messages to the standard error stream, not the syslog
    diff -u -r -N ../gpm-1.19.0.orig/gpm-root.y ./gpm-root.y
    --- ../gpm-1.19.0.orig/gpm-root.y	Thu Oct  7 20:15:18 1999
    +++ ./gpm-root.y	Thu Mar 23 14:37:43 2000
    @@ -41,6 +41,7 @@
     #include <sys/syslog.h>
     #include <signal.h>         /* sigaction() */
     #include <pwd.h>            /* pwd entries */
    +#include <grp.h>            /* initgroups() */
     #include <sys/kd.h>         /* KDGETMODE */
     #include <sys/stat.h>       /* fstat() */
     #include <sys/utsname.h>    /* uname() */
    @@ -117,6 +118,7 @@
     int opt_mod     =  4;           /* control */
     int opt_buf     =  0;           /* ask the kernel about it */
     int opt_user    =  1;           /* allow user cfg files */
    +int opt_root    =  0;           /* run everything as root */



    @@ -447,6 +449,7 @@
     void f__fix(struct passwd *pass)
     {
       setgid(pass->pw_gid);
    +  initgroups(pass->pw_name, pass->pw_gid);
       setuid(pass->pw_uid);
       setenv("HOME",    pass->pw_dir, 1);
       setenv("LOGNAME", pass->pw_name,1);
    @@ -539,7 +542,7 @@
               return 1;

 	    case 0:
    -	  setuid(uid);
    +	  if (opt_root) uid=0;
 	      pass=getpwuid(uid);
 	      if (!pass) exit(1);
 	      f__fix(pass);
    @@ -926,6 +929,7 @@
       printf("  Valid options are\n"
              "    -m <number-or-name>   modifier to use\n"
              "    -u                    inhibit user configuration files\n"
    +         "    -r                    run commands as root\n"
              "    -D                    don't auto-background and run as daemon\n"
              "    -V <verbosity-delta>  increase amount of logged messages\n"
              );
    @@ -971,12 +975,13 @@
       int opt;

       gpm_log_daemon = 1;
    -  while ((opt = getopt(argc, argv,"m:uDV::")) != -1)
    +  while ((opt = getopt(argc, argv,"m:urDV::")) != -1)
         {
           switch (opt)
             {
             case 'm':  opt_mod=getmask(optarg, tableMod); break;
             case 'u':  opt_user=0; break;
    +        case 'r':  opt_root=1; opt_user=0; break;
             case 'D':  gpm_log_daemon = 0; break;
             case 'V':
               gpm_debug_level += (0 == optarg ? 1 : strtol(optarg, 0, 0));

    gpm-1.19.1 fixed  half of  the security  hole by  calling setuid()
    and  setgid()  at  the  right  place but not calling initgruops().
    gpm-1.19.2 is out there, which calls initgroups() correctly, fully
    fixing this security hole.   Therefore anyone running gpm-root  is
    highly  recommended  to  upgrade   to  gpm-1.19.2  or  apply   its
    setuid(), setgid() and initgruops() releated patches.

    For Turbo Linux:

        ftp://ftp.turbolinux.com/pub/updates/6.0/security/gpm-1.19.2-5.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/security/gpm-devel-1.19.2-5.i386.rpm
        ftp://ftp.turbolinux.com/pub/updates/6.0/SRPMS/gpm-1.19.2-5.src.rpm