From owner-freebsd-security Mon Sep 3 4:35:42 2001 Delivered-To: freebsd-security@freebsd.org Received: from whale.sunbay.crimea.ua (whale.sunbay.crimea.ua [212.110.138.65]) by hub.freebsd.org (Postfix) with ESMTP id D371237B40B for ; Mon, 3 Sep 2001 04:35:28 -0700 (PDT) Received: (from ru@localhost) by whale.sunbay.crimea.ua (8.11.2/8.11.2) id f83BZAN90330 for security@FreeBSD.org; Mon, 3 Sep 2001 14:35:10 +0300 (EEST) (envelope-from ru) Date: Mon, 3 Sep 2001 14:35:10 +0300 From: Ruslan Ermilov To: security@FreeBSD.org Subject: at(1) sugid fixes Message-ID: <20010903143510.D49997@sunbay.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Kj7319i9nmIyA2yE" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-security@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org --Kj7319i9nmIyA2yE Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi! The attached patch fixes at(1) macros that manipulate user and group IDs of the proccess so that they don't change the real user and group IDs of the process, and instead use the saved user and group IDs feature. The setre[ug]id() calls are still used with the REDUCE_PERM macro (with the r[ug]id arguments of -1) so that the call changes the saved user/group ID of the process to that specified. That is to say, if the process was initially run ``setuid root'', the call to ``REDUCE_PERM(1, ...)'' changes the process's saved-user-ID to that of the user "daemon", and the process then becomes ``setuid daemon'' (with effective privileges temporarily relinquished to the real privileges). Also, the panic() and perr() functions had insufficient privileges to delete the problematic file under /var/at. Comments/reviews are welcome. Cheers, -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age --Kj7319i9nmIyA2yE Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=p Index: panic.c =================================================================== RCS file: /home/ncvs/src/usr.bin/at/panic.c,v retrieving revision 1.10 diff -u -p -r1.10 panic.c --- panic.c 1999/12/05 19:57:14 1.10 +++ panic.c 2001/09/03 11:21:00 @@ -39,6 +39,7 @@ static const char rcsid[] = /* Local headers */ #include "panic.h" +#include "privs.h" #include "at.h" /* External variables */ @@ -50,8 +51,11 @@ panic(char *a) { /* Something fatal has happened, print error message and exit. */ - if (fcreated) + if (fcreated) { + PRIV_START unlink(atfile); + PRIV_END + } errx(EXIT_FAILURE, "%s", a); } @@ -63,8 +67,11 @@ perr(char *a) */ int serrno = errno; - if (fcreated) + if (fcreated) { + PRIV_START unlink(atfile); + PRIV_END + } errno = serrno; err(EXIT_FAILURE, "%s", a); Index: privs.h =================================================================== RCS file: /home/ncvs/src/usr.bin/at/privs.h,v retrieving revision 1.7 diff -u -p -r1.7 privs.h --- privs.h 1999/12/05 19:57:14 1.7 +++ privs.h 2001/09/03 11:21:00 @@ -28,17 +28,11 @@ #ifndef _PRIVS_H #define _PRIVS_H -#ifndef _USE_BSD -#define _USE_BSD 1 #include -#undef _USE_BSD -#else -#include -#endif /* Relinquish privileges temporarily for a setuid or setgid program - * with the option of getting them back later. This is done by swapping - * the real and effective userid BSD style. Call RELINQUISH_PRIVS once + * with the option of getting them back later. This is done by + * utilizing POSIX saved user and group IDs. Call RELINQUISH_PRIVS once * at the beginning of the main program. This will cause all operations * to be executed with the real userid. When you need the privileges * of the setuid/setgid invocation, call PRIV_START; when you no longer @@ -76,38 +70,39 @@ extern gid_t real_gid, effective_gid; #define RELINQUISH_PRIVS { \ - real_uid = getuid(); \ - effective_uid = geteuid(); \ - real_gid = getgid(); \ - effective_gid = getegid(); \ - setreuid(effective_uid, real_uid); \ - setregid(effective_gid, real_gid); \ - } - -#define RELINQUISH_PRIVS_ROOT(a,b) { \ - real_uid = (a); \ - effective_uid = geteuid(); \ - real_gid = (b); \ - effective_gid = getegid(); \ - setregid(effective_gid, real_gid); \ - setreuid(effective_uid, real_uid); \ - } - -#define PRIV_START {\ - setreuid(real_uid, effective_uid); \ - setregid(real_gid, effective_gid); - -#define PRIV_END \ - setregid(effective_gid, real_gid); \ - setreuid(effective_uid, real_uid); \ - } - -#define REDUCE_PRIV(a,b) {\ - setreuid(real_uid, effective_uid); \ - setregid(real_gid, effective_gid); \ - effective_uid = (a); \ - effective_gid = (b); \ - setregid(effective_gid, real_gid); \ - setreuid(effective_uid, real_uid); \ - } + real_uid = getuid(); \ + effective_uid = geteuid(); \ + real_gid = getgid(); \ + effective_gid = getegid(); \ + seteuid(real_uid); \ + setegid(real_gid); \ +} + +#define RELINQUISH_PRIVS_ROOT(a, b) { \ + real_uid = (a); \ + effective_uid = geteuid(); \ + real_gid = (b); \ + effective_gid = getegid(); \ + setegid(real_gid); \ + seteuid(real_uid); \ +} + +#define PRIV_START { \ + seteuid(effective_uid); \ + setegid(effective_gid); \ +} + +#define PRIV_END { \ + setegid(real_gid); \ + seteuid(real_uid); \ +} + +#define REDUCE_PRIV(a, b) { \ + PRIV_START \ + effective_uid = (a); \ + effective_gid = (b); \ + setreuid((uid_t)-1, effective_uid); \ + setregid((gid_t)-1, effective_gid); \ + PRIV_END \ +} #endif --Kj7319i9nmIyA2yE-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message