summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorJacek Masiulaniec <jacekm@cvs.openbsd.org>2010-05-23 18:44:15 +0000
committerJacek Masiulaniec <jacekm@cvs.openbsd.org>2010-05-23 18:44:15 +0000
commit763741ec316949089a253bc1c5318b108f11c9c2 (patch)
treea523d543e8a0ea95e32f290e713ff4b1d3cc2b06 /usr.sbin
parent0021a8c49b6242861e16f6fbd436c94cc632a4b8 (diff)
When executing external mda, call dup2, closefrom, and chdir before
setresuid because after dropping superuser privileges the process cannot be trusted to call these. Thanks to oga@, kettenis@, and nicm@ for confirming my paranoia.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/smtpd/smtpd.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index 39c0caf55e6..97c73c658aa 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.105 2010/05/21 08:45:02 jacekm Exp $ */
+/* $OpenBSD: smtpd.c,v 1.106 2010/05/23 18:44:14 jacekm Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -868,15 +868,19 @@ forkmda(struct smtpd *env, struct imsgev *iev, u_int32_t id,
#define error(m) { perror(m); _exit(1); }
if (seteuid(0) < 0)
- fatal("forkmda: cannot restore privileges");
- if (setgroups(1, &pw->pw_gid) ||
- setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
- setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
- fatal("forkmda: cannot drop privileges");
+ error("forkmda: cannot restore privileges");
+ if (chdir(pw->pw_dir) < 0 && chdir("/") < 0)
+ error("chdir");
if (dup2(pipefd[0], STDIN_FILENO) < 0 ||
dup2(allout, STDOUT_FILENO) < 0 ||
dup2(allout, STDERR_FILENO) < 0)
- fatal("forkmda: dup2");
+ error("forkmda: dup2");
+ if (closefrom(STDERR_FILENO + 1) < 0)
+ error("closefrom");
+ if (setgroups(1, &pw->pw_gid) ||
+ setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
+ setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
+ error("forkmda: cannot drop privileges");
if (setsid() < 0)
error("setsid");
if (signal(SIGPIPE, SIG_DFL) == SIG_ERR ||
@@ -885,10 +889,6 @@ forkmda(struct smtpd *env, struct imsgev *iev, u_int32_t id,
signal(SIGCHLD, SIG_DFL) == SIG_ERR ||
signal(SIGHUP, SIG_DFL) == SIG_ERR)
error("signal");
- if (chdir(pw->pw_dir) < 0 && chdir("/") < 0)
- error("chdir");
- if (closefrom(STDERR_FILENO + 1) < 0)
- error("closefrom");
/* avoid hangs by setting 5m timeout */
alarm(300);