From owner-freebsd-security@FreeBSD.ORG Fri Jun 4 12:54:45 2004 Return-Path: Delivered-To: freebsd-security@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2ACDB16A4CE for ; Fri, 4 Jun 2004 12:54:45 -0700 (PDT) Received: from sccrmhc12.comcast.net (sccrmhc12.comcast.net [204.127.202.56]) by mx1.FreeBSD.org (Postfix) with ESMTP id CF6A543D31 for ; Fri, 4 Jun 2004 12:54:44 -0700 (PDT) (envelope-from cristjc@comcast.net) Received: from blossom.cjclark.org (c-24-6-187-112.client.comcast.net[24.6.187.112]) by comcast.net (sccrmhc12) with ESMTP id <20040604195344012001oio6e>; Fri, 4 Jun 2004 19:53:44 +0000 Received: from blossom.cjclark.org (localhost. [127.0.0.1]) by blossom.cjclark.org (8.12.11/8.12.8) with ESMTP id i54JrdwE050425 for ; Fri, 4 Jun 2004 12:53:43 -0700 (PDT) (envelope-from cristjc@comcast.net) Received: (from cjc@localhost) by blossom.cjclark.org (8.12.11/8.12.11/Submit) id i54JrcfS050424 for freebsd-security@freebsd.org; Fri, 4 Jun 2004 12:53:38 -0700 (PDT) (envelope-from cristjc@comcast.net) X-Authentication-Warning: blossom.cjclark.org: cjc set sender to cristjc@comcast.net using -f Date: Fri, 4 Jun 2004 12:53:38 -0700 From: "Crist J. Clark" To: freebsd-security@freebsd.org Message-ID: <20040604195338.GA50275@blossom.cjclark.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="OgqxwSJOaUobr8KG" Content-Disposition: inline User-Agent: Mutt/1.4.2.1i X-URL: http://people.freebsd.org/~cjc/ Subject: syslogd(8) Dropping Privs X-BeenThere: freebsd-security@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: "Crist J. Clark" List-Id: Security issues [members-only posting] List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 Jun 2004 19:54:45 -0000 --OgqxwSJOaUobr8KG Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I made a quick change to syslogd(8) so that it can drop root privileges immediately after starting up. It opens up the log sockets (UNIX and network domains) and writes the PID files before dropping privs. It drops privs before openning log files and writing to users. Therefore, you would need to modify your log file permissions appropriately. As for writing to users, ttys generally are writeable by group tty. The UID chosen to run syslogd as should be in this group if this feature is desired. We haven't had many syslogd(8) vulnerabilities lately, but one less daemon running as root seems like a Good Thing. I do not see any drawbacks from a security point of view. The log files would have to be owned, or otherwise writeable, by this other user, but so what. Obviously, I may be missing something. Any interest in this? Let me know if you try it out and any successes or failures. Patches! CURRENT and RELENG_4 version attached. The documentation is included as a patch to the syslogd(8) man page. -- Crist J. Clark | cjclark@alum.mit.edu | cjclark@jhu.edu http://people.freebsd.org/~cjc/ | cjc@freebsd.org --OgqxwSJOaUobr8KG Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="syslogd.RELENG_4" Index: src/usr.sbin/syslogd/syslogd.8 =================================================================== RCS file: /ncvs/src/usr.sbin/syslogd/syslogd.8,v retrieving revision 1.22.2.16 diff -u -r1.22.2.16 syslogd.8 --- src/usr.sbin/syslogd/syslogd.8 12 Mar 2003 22:08:15 -0000 1.22.2.16 +++ src/usr.sbin/syslogd/syslogd.8 4 Jun 2004 19:51:55 -0000 @@ -48,6 +48,7 @@ .Op Fl m Ar mark_interval .Op Fl P Ar pid_file .Op Fl p Ar log_socket +.Op Fl U Ar user .Sh DESCRIPTION The .Nm @@ -214,6 +215,16 @@ .Dq => to .Dq = . +.It Fl U Ar user +Run as +.Ar user . +.Ar User +must be a valid user name. +This option allows the daemon to drop root privileges, but still open +privileged sockets as root at start up. +Note that privileges are dropped before log files are opened and that the +user must have privileges to write to ttys in order to send messages +to users. .It Fl v Verbose logging. If specified once, the numeric facility and priority are logged with each locally-written message. If specified more than once, Index: src/usr.sbin/syslogd/syslogd.c =================================================================== RCS file: /ncvs/src/usr.sbin/syslogd/syslogd.c,v retrieving revision 1.59.2.28 diff -u -r1.59.2.28 syslogd.c --- src/usr.sbin/syslogd/syslogd.c 29 Feb 2004 20:59:19 -0000 1.59.2.28 +++ src/usr.sbin/syslogd/syslogd.c 4 Jun 2004 19:47:22 -0000 @@ -102,6 +102,7 @@ #include #include #include +#include #include #include #include @@ -334,9 +335,12 @@ sigset_t mask; pid_t ppid = 1; socklen_t len; + struct passwd *pw; + uid_t runAs; bindhostname = NULL; - while ((ch = getopt(argc, argv, "46Aa:b:cdf:kl:m:np:P:suv")) != -1) + runAs = getuid(); + while ((ch = getopt(argc, argv, "46Aa:b:cdf:kl:m:np:P:suU:v")) != -1) switch (ch) { case '4': family = PF_INET; @@ -393,6 +397,11 @@ case 'u': /* only log specified priority */ UniquePriority++; break; + case 'U': + if ((pw = getpwnam(optarg)) == NULL) + errx(1, "could not find user \"%s\"", optarg); + runAs = pw->pw_uid; + break; case 'v': /* log facility and priority */ LogFacPri++; break; @@ -489,6 +498,16 @@ if (fp != NULL) { fprintf(fp, "%d\n", getpid()); (void)fclose(fp); + } + + if (runAs != getuid()) { + if (setuid(runAs) == -1) { + (void)snprintf(line, sizeof(line), + "failed to change uid to %d\n", runAs); + logerror(line); + die(0); + } + dprintf("changed running uid to %d\n", runAs); } dprintf("off & running....\n"); --OgqxwSJOaUobr8KG Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="syslogd.CURRENT" Index: src/usr.sbin/syslogd/syslogd.8 =================================================================== RCS file: /export/freebsd/ncvs/src/usr.sbin/syslogd/syslogd.8,v retrieving revision 1.50 diff -u -r1.50 syslogd.8 --- src/usr.sbin/syslogd/syslogd.8 8 Sep 2003 19:57:22 -0000 1.50 +++ src/usr.sbin/syslogd/syslogd.8 4 Jun 2004 19:53:11 -0000 @@ -48,6 +48,7 @@ .Op Fl m Ar mark_interval .Op Fl P Ar pid_file .Op Fl p Ar log_socket +.Op Fl U Ar user .Sh DESCRIPTION The .Nm @@ -219,6 +220,16 @@ .Dq => to .Dq = . +.It Fl U Ar user +Run as +.Ar user . +.Ar User +must be a valid user name. +This option allows the daemon to drop root privileges, but still open +privileged sockets as root at start up. +Note that privileges are dropped before log files are opened and that the +user must have privileges to write to ttys in order to send messages +to users. .It Fl v Verbose logging. If specified once, the numeric facility and priority are logged with each locally-written message. If specified more than once, Index: src/usr.sbin/syslogd/syslogd.c =================================================================== RCS file: /export/freebsd/ncvs/src/usr.sbin/syslogd/syslogd.c,v retrieving revision 1.128 diff -u -r1.128 syslogd.c --- src/usr.sbin/syslogd/syslogd.c 30 May 2004 10:34:58 -0000 1.128 +++ src/usr.sbin/syslogd/syslogd.c 4 Jun 2004 16:33:14 -0000 @@ -103,6 +103,7 @@ #include #include #include +#include #include #include #include @@ -340,9 +341,12 @@ sigset_t mask; pid_t ppid = 1; socklen_t len; + struct passwd *pw; + uid_t runAs; bindhostname = NULL; - while ((ch = getopt(argc, argv, "46Aa:b:cdf:kl:m:nop:P:suv")) != -1) + runAs = getuid(); + while ((ch = getopt(argc, argv, "46Aa:b:cdf:kl:m:nop:P:suU:v")) != -1) switch (ch) { case '4': family = PF_INET; @@ -406,6 +410,11 @@ case 'u': /* only log specified priority */ UniquePriority++; break; + case 'U': + if ((pw = getpwnam(optarg)) == NULL) + errx(1, "could not find user \"%s\"", optarg); + runAs = pw->pw_uid; + break; case 'v': /* log facility and priority */ LogFacPri++; break; @@ -501,6 +510,16 @@ if (fp != NULL) { fprintf(fp, "%d\n", getpid()); (void)fclose(fp); + } + + if (runAs != getuid()) { + if (setuid(runAs) == -1) { + (void)snprintf(line, sizeof(line), + "failed to change uid to %d\n", runAs); + logerror(line); + die(0); + } + dprintf("changed running uid to %d\n", runAs); } dprintf("off & running....\n"); --OgqxwSJOaUobr8KG--