fix MITKRB5-SA-2006-001: multiple local privilege escalation vulnerabilities
authorTom Yu <tlyu@mit.edu>
Tue, 8 Aug 2006 19:26:40 +0000 (19:26 +0000)
committerTom Yu <tlyu@mit.edu>
Tue, 8 Aug 2006 19:26:40 +0000 (19:26 +0000)
* src/appl/gssftp/ftpd/ftpd.c (getdatasock, passive):
* src/appl/bsd/v4rcp.c (main):
* src/appl/bsd/krcp.c (main):
* src/appl/bsd/krshd.c (doit):
* src/appl/bsd/login.c (main):
* src/clients/ksu/main.c (sweep_up):
* src/lib/krb4/kuserok.c (kuserok): Check return values from
setuid() and related functions to avoid privilege escalation
vulnerabilities.  Fixes MITKRB5-SA-2006-001. [CVE-2006-3083,
VU#580124, CVE-2006-3084, VU#401660]

ticket: new
target_version: 1.5.1
tags: pullup

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@18420 dc483132-0cff-0310-8789-dd5450dbe970

src/appl/bsd/krcp.c
src/appl/bsd/krshd.c
src/appl/bsd/login.c
src/appl/bsd/v4rcp.c
src/appl/gssftp/ftpd/ftpd.c
src/clients/ksu/main.c
src/lib/krb4/kuserok.c

index 707985a5a873716ecc3b74feb32947414d66c640..9cf85ed37a3790304ce3e8be318c842b52a07c19 100644 (file)
@@ -620,7 +620,9 @@ int main(argc, argv)
                                   
                euid = geteuid();
                if (euid == 0) {
-                   (void) setuid(0);
+                   if (setuid(0)) {
+                       perror("rcp setuid 0"); errs++; exit(errs);
+                   }
                    if(krb5_seteuid(userid)) {
                        perror("rcp seteuid user"); errs++; exit(errs);
                    }
@@ -638,11 +640,17 @@ int main(argc, argv)
                  continue;
                rcmd_stream_init_normal();
 #ifdef HAVE_SETREUID
-               (void) setreuid(0, userid);
+               if (setreuid(0, userid)) {
+                   perror("rcp setreuid 0,user"); errs++; exit(errs);
+               }
                sink(1, argv+argc-1);
-               (void) setreuid(userid, 0);
+               if (setreuid(userid, 0)) {
+                   perror("rcp setreuid user,0"); errs++; exit(errs);
+               }
 #else
-               (void) setuid(0);
+               if (setuid(0)) {
+                 perror("rcp setuid 0"); errs++; exit(errs);
+               }
                if(seteuid(userid)) {
                  perror("rcp seteuid user"); errs++; exit(errs);
                }
index 02ab13235438172300284d5ae2759101c084bf2f..0989158c0a1f63c5825d6c683ebfb88733358edd 100644 (file)
@@ -1403,9 +1403,15 @@ void doit(f, fromp)
      * If we're on a system which keeps track of login uids, then
      * set the login uid. 
      */
-    setluid((uid_t) pwd->pw_uid);
+    if (setluid((uid_t) pwd->pw_uid) < 0) {
+       perror("setluid");
+       _exit(1);
+    }
 #endif /* HAVE_SETLUID */
-    (void) setuid((uid_t)pwd->pw_uid);
+    if (setuid((uid_t)pwd->pw_uid) < 0) {
+       perror("setuid");
+       _exit(1);
+    }
     /* if TZ is set in the parent, drag it in */
     {
       char **findtz = environ;
index a3cdef797c4ef7b834e57adf8624398a1818e722..861b9a57af8b883f5465f8cada3dc20666f4720c 100644 (file)
@@ -1648,7 +1648,10 @@ int main(argc, argv)
        }
 #endif /* HAVE_SETLUID */
 #ifdef _IBMR2
-    setuidx(ID_LOGIN, pwd->pw_uid);
+    if (setuidx(ID_LOGIN, pwd->pw_uid) < 0) {
+       perror("setuidx");
+       sleepexit(1);
+    };
 #endif
 
     /* This call MUST succeed */
index 2354a2c590f8889b0e9b11f19e4c1fed11c50d42..67bf87786ff1a52ae766944adfe22b00fcaf22ea 100644 (file)
@@ -436,7 +436,10 @@ int main(argc, argv)
                        kstream_set_buffer_mode (krem, 0);
 #endif /* KERBEROS && !NOENCRYPTION */
                        (void) response();
-                       (void) setuid(userid);
+                       if (setuid(userid)) {
+                           error("rcp: can't setuid(user)\n");
+                           exit(1);
+                       }
                        source(--argc, ++argv);
                        exit(errs);
 
@@ -452,7 +455,10 @@ int main(argc, argv)
                                krem = kstream_create_from_fd (rem, 0, 0);
                        kstream_set_buffer_mode (krem, 0);
 #endif /* KERBEROS && !NOENCRYPTION */
-                       (void) setuid(userid);
+                       if (setuid(userid)) {
+                           error("rcp: can't setuid(user)\n");
+                           exit(1);
+                       }
                        sink(--argc, ++argv);
                        exit(errs);
 
index 9a3639b3e4e70c3769f29c30384224982791b2f3..94b40dcc5be8c4cda68b19694208990c7355508f 100644 (file)
@@ -1367,7 +1367,9 @@ getdatasock(fmode)
                        goto bad;
                sleep(tries);
        }
-       (void) krb5_seteuid((uid_t)pw->pw_uid);
+       if (krb5_seteuid((uid_t)pw->pw_uid)) {
+               fatal("seteuid user");
+       }
 #ifdef IP_TOS
 #ifdef IPTOS_THROUGHPUT
        on = IPTOS_THROUGHPUT;
@@ -1377,7 +1379,9 @@ getdatasock(fmode)
 #endif
        return (fdopen(s, fmode));
 bad:
-       (void) krb5_seteuid((uid_t)pw->pw_uid);
+       if (krb5_seteuid((uid_t)pw->pw_uid)) {
+               fatal("seteuid user");
+       }
        (void) close(s);
        return (NULL);
 }
@@ -2186,7 +2190,9 @@ passive()
                (void) krb5_seteuid((uid_t)pw->pw_uid);
                goto pasv_error;
        }
-       (void) krb5_seteuid((uid_t)pw->pw_uid);
+       if (krb5_seteuid((uid_t)pw->pw_uid)) {
+               fatal("seteuid user");
+       }
        len = sizeof(pasv_addr);
        if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
                goto pasv_error;
index d6b001b7928cf3935fb0aff6afe0ac217dff333f..241aa76927530996dc2fb3d2259366df87f796e6 100644 (file)
@@ -892,9 +892,12 @@ static void sweep_up(context, cc)
     const char * cc_name;
     struct stat  st_temp;
 
-    krb5_seteuid(0);
-    krb5_seteuid(target_uid);
-    
+    if (krb5_seteuid(0) < 0 || krb5_seteuid(target_uid) < 0) {
+       com_err(prog_name, errno,
+               "while returning to source uid for destroying ccache");
+       exit(1);
+    }
+
     cc_name = krb5_cc_get_name(context, cc);
     if ( ! stat(cc_name, &st_temp)){
        if ((retval = krb5_cc_destroy(context, cc))){
index 32620db1ae858855017dd369658b9d9f64f08504..579128ed38e67f0b10a53c71789dbcfc14140fc3 100644 (file)
@@ -159,9 +159,11 @@ kuserok(kdata, luser)
         */
         if(getuid() == 0) {
          uid_t old_euid = geteuid();
-         seteuid(pwd->pw_uid);
+         if (seteuid(pwd->pw_uid) < 0)
+             return NOTOK;
          fp = fopen(pbuf, "r");
-         seteuid(old_euid);      
+         if (seteuid(old_euid) < 0)
+             return NOTOK;
          if ((fp) == NULL) {
            return(NOTOK);
          }