masqmail
changeset 331:e507c854a63e
Security fix! Correct handling of seteuid() return value
See Debian bug #638002, reported by John Lightsey.
When possible the (already available) set_euidgid() function is used.
Additionally, it is unnecessary to change the identity when writing
into an already open file descriptor.
This should fix the problem.
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Sat, 27 Aug 2011 16:19:07 +0200 |
parents | f899ca0835a8 |
children | 63efd381e27b |
files | src/log.c src/masqmail.c |
diffstat | 2 files changed, 36 insertions(+), 38 deletions(-) [+] |
line diff
1.1 --- a/src/log.c Wed Jul 13 10:30:52 2011 +0200 1.2 +++ b/src/log.c Sat Aug 27 16:19:07 2011 +0200 1.3 @@ -65,8 +65,9 @@ 1.4 uid_t saved_uid; 1.5 gid_t saved_gid; 1.6 1.7 - saved_gid = setegid(conf.mail_gid); 1.8 - saved_uid = seteuid(conf.mail_uid); 1.9 + if (!conf.run_as_user) { 1.10 + set_euidgid(conf.mail_uid, conf.mail_gid, &saved_uid, &saved_gid); 1.11 + } 1.12 1.13 filename = g_strdup_printf("%s/masqmail.log", conf.log_dir); 1.14 logfile = fopen(filename, "a"); 1.15 @@ -76,8 +77,9 @@ 1.16 } 1.17 g_free(filename); 1.18 1.19 - seteuid(saved_uid); 1.20 - setegid(saved_gid); 1.21 + if (!conf.run_as_user) { 1.22 + set_euidgid(saved_uid, saved_gid, NULL, NULL); 1.23 + } 1.24 } 1.25 1.26 #ifdef ENABLE_DEBUG 1.27 @@ -114,35 +116,26 @@ 1.28 va_copy(args_copy, args); 1.29 vfprintf(stdout, fmt, args_copy); 1.30 va_end(args_copy); 1.31 - fflush(stdout); /* is this necessary? */ 1.32 + fflush(stdout); /* in case output ends not with newline */ 1.33 } 1.34 1.35 pri &= ~LOG_VERBOSE; 1.36 - if (pri) { 1.37 - if (conf.use_syslog) 1.38 - vsyslog(pri, fmt, args); 1.39 - else { 1.40 - if (pri <= conf.log_max_pri) { 1.41 - FILE *file = logfile ? logfile : stderr; 1.42 - time_t now = time(NULL); 1.43 - struct tm *t = localtime(&now); 1.44 - gchar buf[24]; 1.45 - uid_t saved_uid; 1.46 - gid_t saved_gid; 1.47 + if (!pri) { 1.48 + return; 1.49 + } 1.50 + if (conf.use_syslog) 1.51 + vsyslog(pri, fmt, args); 1.52 + else if (pri <= conf.log_max_pri) { 1.53 + FILE *file = logfile ? logfile : stderr; 1.54 + time_t now = time(NULL); 1.55 + struct tm *t = localtime(&now); 1.56 + gchar buf[24]; 1.57 1.58 - saved_gid = setegid(conf.mail_gid); 1.59 - saved_uid = seteuid(conf.mail_uid); 1.60 + strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t); 1.61 + fprintf(file, "%s [%d] ", buf, getpid()); 1.62 1.63 - strftime(buf, 24, "%Y-%m-%d %H:%M:%S", t); 1.64 - fprintf(file, "%s [%d] ", buf, getpid()); 1.65 - 1.66 - vfprintf(file, fmt, args); 1.67 - fflush(file); 1.68 - 1.69 - seteuid(saved_uid); 1.70 - setegid(saved_gid); 1.71 - } 1.72 - } 1.73 + vfprintf(file, fmt, args); 1.74 + fflush(file); 1.75 } 1.76 } 1.77
2.1 --- a/src/masqmail.c Wed Jul 13 10:30:52 2011 +0200 2.2 +++ b/src/masqmail.c Sat Aug 27 16:19:07 2011 +0200 2.3 @@ -61,8 +61,10 @@ 2.4 sigterm_in_progress = 1; 2.5 2.6 if (pidfile) { 2.7 - uid_t uid; 2.8 - uid = seteuid(0); 2.9 + uid_t uid = geteuid(); 2.10 + if (seteuid(0) != 0) { 2.11 + logwrite(LOG_ALERT, "sigterm_handler: could not set euid to %d: %s\n", 0, strerror(errno)); 2.12 + } 2.13 if (unlink(pidfile) != 0) 2.14 logwrite(LOG_WARNING, "could not delete pid file %s: %s\n", pidfile, strerror(errno)); 2.15 seteuid(uid); /* we exit anyway after this, just to be sure */ 2.16 @@ -187,8 +189,7 @@ 2.17 conf.do_verbose = FALSE; 2.18 2.19 if (!conf.run_as_user) { 2.20 - seteuid(conf.orig_uid); 2.21 - setegid(conf.orig_gid); 2.22 + set_euidgid(conf.orig_uid, conf.orig_gid, NULL, NULL); 2.23 } 2.24 2.25 DEBUG(5) debugf("accepting smtp message on stdin\n"); 2.26 @@ -217,8 +218,7 @@ 2.27 } 2.28 2.29 if (!conf.run_as_user) { 2.30 - seteuid(conf.orig_uid); 2.31 - setegid(conf.orig_gid); 2.32 + set_euidgid(conf.orig_uid, conf.orig_gid, NULL, NULL); 2.33 } 2.34 2.35 DEBUG(5) debugf("accepting message on stdin\n"); 2.36 @@ -647,10 +647,15 @@ 2.37 */ 2.38 if ((strcmp(conf_file, CONF_FILE) != 0) && (conf.orig_uid != 0)) { 2.39 conf.run_as_user = TRUE; 2.40 - seteuid(conf.orig_uid); 2.41 - setegid(conf.orig_gid); 2.42 - setuid(conf.orig_uid); 2.43 - setgid(conf.orig_gid); 2.44 + set_euidgid(conf.orig_uid, conf.orig_gid, NULL, NULL); 2.45 + if (setgid(conf.orig_gid)) { 2.46 + logwrite(LOG_ALERT, "could not set gid to %d: %s\n", conf.orig_gid, strerror(errno)); 2.47 + exit(1); 2.48 + } 2.49 + if (setuid(conf.orig_uid)) { 2.50 + logwrite(LOG_ALERT, "could not set uid to %d: %s\n", conf.orig_uid, strerror(errno)); 2.51 + exit(1); 2.52 + } 2.53 } 2.54 2.55 conf.log_dir = LOG_DIR;