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