From 7b141abe9aa72db8c7243d4f0a30b87e59789579 Mon Sep 17 00:00:00 2001 From: Tom Yu Date: Tue, 8 Aug 2006 19:26:40 +0000 Subject: [PATCH] fix MITKRB5-SA-2006-001: multiple local privilege escalation vulnerabilities * 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 | 16 ++++++++++++---- src/appl/bsd/krshd.c | 10 ++++++++-- src/appl/bsd/login.c | 5 ++++- src/appl/bsd/v4rcp.c | 10 ++++++++-- src/appl/gssftp/ftpd/ftpd.c | 12 +++++++++--- src/clients/ksu/main.c | 9 ++++++--- src/lib/krb4/kuserok.c | 6 ++++-- 7 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/appl/bsd/krcp.c b/src/appl/bsd/krcp.c index 707985a5a..9cf85ed37 100644 --- a/src/appl/bsd/krcp.c +++ b/src/appl/bsd/krcp.c @@ -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); } diff --git a/src/appl/bsd/krshd.c b/src/appl/bsd/krshd.c index 02ab13235..0989158c0 100644 --- a/src/appl/bsd/krshd.c +++ b/src/appl/bsd/krshd.c @@ -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; diff --git a/src/appl/bsd/login.c b/src/appl/bsd/login.c index a3cdef797..861b9a57a 100644 --- a/src/appl/bsd/login.c +++ b/src/appl/bsd/login.c @@ -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 */ diff --git a/src/appl/bsd/v4rcp.c b/src/appl/bsd/v4rcp.c index 2354a2c59..67bf87786 100644 --- a/src/appl/bsd/v4rcp.c +++ b/src/appl/bsd/v4rcp.c @@ -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); diff --git a/src/appl/gssftp/ftpd/ftpd.c b/src/appl/gssftp/ftpd/ftpd.c index 9a3639b3e..94b40dcc5 100644 --- a/src/appl/gssftp/ftpd/ftpd.c +++ b/src/appl/gssftp/ftpd/ftpd.c @@ -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; diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c index d6b001b79..241aa7692 100644 --- a/src/clients/ksu/main.c +++ b/src/clients/ksu/main.c @@ -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))){ diff --git a/src/lib/krb4/kuserok.c b/src/lib/krb4/kuserok.c index 32620db1a..579128ed3 100644 --- a/src/lib/krb4/kuserok.c +++ b/src/lib/krb4/kuserok.c @@ -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); } -- 2.26.2