Check return values from seteuid, prompted by MIT advisory.

Thanks to Tom Yu at MIT, and Michael Calmer and Marcus Meissner at SUSE.
Either of CVE-2006-3083 or CVE-2006-3084.


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17872 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2006-08-08 21:03:26 +00:00
parent 702b7b61f4
commit 7154d3b11d

View File

@@ -138,9 +138,9 @@ static int handleoobcmd(void);
static int checkuser (char *, char *); static int checkuser (char *, char *);
static int checkaccess (char *); static int checkaccess (char *);
static FILE *dataconn (const char *, off_t, const char *); static FILE *dataconn (const char *, off_t, const char *);
static void dolog (struct sockaddr *sa, int len); static void dolog (struct sockaddr *, int);
static void end_login (void); static void end_login (void);
static FILE *getdatasock (const char *); static FILE *getdatasock (const char *, int);
static char *gunique (char *); static char *gunique (char *);
static RETSIGTYPE lostconn (int); static RETSIGTYPE lostconn (int);
static int receive_data (FILE *, FILE *); static int receive_data (FILE *, FILE *);
@@ -835,7 +835,8 @@ static void
end_login(void) end_login(void)
{ {
seteuid((uid_t)0); if (seteuid((uid_t)0) < 0)
fatal("Failed to seteuid");
if (logged_in) if (logged_in)
ftpd_logwtmp(ttyline, "", ""); ftpd_logwtmp(ttyline, "", "");
pw = NULL; pw = NULL;
@@ -1208,14 +1209,15 @@ done:
} }
static FILE * static FILE *
getdatasock(const char *mode) getdatasock(const char *mode, int domain)
{ {
int s, t, tries; int s, t, tries;
if (data >= 0) if (data >= 0)
return (fdopen(data, mode)); return (fdopen(data, mode));
seteuid(0); if (seteuid(0) < 0)
s = socket(ctrl_addr->sa_family, SOCK_STREAM, 0); fatal("Failed to seteuid");
s = socket(domain, SOCK_STREAM, 0);
if (s < 0) if (s < 0)
goto bad; goto bad;
socket_set_reuseaddr (s, 1); socket_set_reuseaddr (s, 1);
@@ -1232,7 +1234,8 @@ getdatasock(const char *mode)
goto bad; goto bad;
sleep(tries); sleep(tries);
} }
seteuid(pw->pw_uid); if (seteuid(pw->pw_uid) < 0)
fatal("Failed to seteuid");
#ifdef IPTOS_THROUGHPUT #ifdef IPTOS_THROUGHPUT
socket_set_tos (s, IPTOS_THROUGHPUT); socket_set_tos (s, IPTOS_THROUGHPUT);
#endif #endif
@@ -1240,7 +1243,8 @@ getdatasock(const char *mode)
bad: bad:
/* Return the real value of errno (close may change it) */ /* Return the real value of errno (close may change it) */
t = errno; t = errno;
seteuid((uid_t)pw->pw_uid); if (seteuid((uid_t)pw->pw_uid) < 0)
fatal("Failed to seteuid");
close(s); close(s);
errno = t; errno = t;
return (NULL); return (NULL);
@@ -1271,7 +1275,7 @@ dataconn(const char *name, off_t size, const char *mode)
{ {
char sizebuf[32]; char sizebuf[32];
FILE *file; FILE *file;
int retry = 0; int domain, retry = 0;
file_size = size; file_size = size;
byte_count = 0; byte_count = 0;
@@ -1318,7 +1322,15 @@ dataconn(const char *name, off_t size, const char *mode)
if (usedefault) if (usedefault)
data_dest = his_addr; data_dest = his_addr;
usedefault = 1; usedefault = 1;
file = getdatasock(mode); /*
* Default to using the same socket type as the ctrl address,
* unless we know the type of the data address.
*/
domain = data_dest->sa_family;
if (domain == PF_UNSPEC)
domain = ctrl_addr->sa_family;
file = getdatasock(mode, domain);
if (file == NULL) { if (file == NULL) {
char data_addr[256]; char data_addr[256];
@@ -2006,12 +2018,15 @@ pasv(void)
0); 0);
socket_set_portrange(pdata, restricted_data_ports, socket_set_portrange(pdata, restricted_data_ports,
pasv_addr->sa_family); pasv_addr->sa_family);
seteuid(0); if (seteuid(0) < 0)
fatal("Failed to seteuid");
if (bind(pdata, pasv_addr, socket_sockaddr_size (pasv_addr)) < 0) { if (bind(pdata, pasv_addr, socket_sockaddr_size (pasv_addr)) < 0) {
seteuid(pw->pw_uid); if (seteuid(pw->pw_uid) < 0)
fatal("Failed to seteuid");
goto pasv_error; goto pasv_error;
} }
seteuid(pw->pw_uid); if (seteuid(pw->pw_uid) < 0)
fatal("Failed to seteuid");
len = sizeof(pasv_addr_ss); len = sizeof(pasv_addr_ss);
if (getsockname(pdata, pasv_addr, &len) < 0) if (getsockname(pdata, pasv_addr, &len) < 0)
goto pasv_error; goto pasv_error;
@@ -2050,12 +2065,15 @@ epsv(char *proto)
0); 0);
socket_set_portrange(pdata, restricted_data_ports, socket_set_portrange(pdata, restricted_data_ports,
pasv_addr->sa_family); pasv_addr->sa_family);
seteuid(0); if (seteuid(0) < 0)
fatal("Failed to seteuid");
if (bind(pdata, pasv_addr, socket_sockaddr_size (pasv_addr)) < 0) { if (bind(pdata, pasv_addr, socket_sockaddr_size (pasv_addr)) < 0) {
seteuid(pw->pw_uid); if (seteuid(pw->pw_uid))
fatal("Failed to seteuid");
goto pasv_error; goto pasv_error;
} }
seteuid(pw->pw_uid); if (seteuid(pw->pw_uid) < 0)
fatal("Failed to seteuid");
len = sizeof(pasv_addr_ss); len = sizeof(pasv_addr_ss);
if (getsockname(pdata, pasv_addr, &len) < 0) if (getsockname(pdata, pasv_addr, &len) < 0)
goto pasv_error; goto pasv_error;