From 9dd887f1a6b4c4d3aa4d0c5d595436867d2200a0 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Tue, 4 Sep 2001 16:15:51 +0000 Subject: [PATCH] SECURITY. Fixed macros for temporarily relinquishing and restoring setuid/setgid privileges so that they never change the real user and group IDs of the calling process. The setre[ug]id() calls are still used in the REDUCE_PERM macro (with the r[ug]id arguments of -1) so that the call changes the saved user and group IDs of the process to that specified. Also, the panic() and perr() functions had insufficient privileges to delete the problematic file under /var/at. --- usr.bin/at/panic.c | 11 +++++-- usr.bin/at/privs.h | 71 +++++++++++++++++++++------------------------- 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/usr.bin/at/panic.c b/usr.bin/at/panic.c index 9cabc1da0d5e..cf6d041e3daf 100644 --- a/usr.bin/at/panic.c +++ b/usr.bin/at/panic.c @@ -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); diff --git a/usr.bin/at/privs.h b/usr.bin/at/privs.h index 2fce5c02e4a6..50dd6b108af4 100644 --- a/usr.bin/at/privs.h +++ b/usr.bin/at/privs.h @@ -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); \ - } + 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(); \ - setregid(effective_gid, real_gid); \ - setreuid(effective_uid, real_uid); \ - } +#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 {\ - setreuid(real_uid, effective_uid); \ - setregid(real_gid, effective_gid); +#define PRIV_START { \ + seteuid(effective_uid); \ + setegid(effective_gid); \ +} -#define PRIV_END \ - setregid(effective_gid, real_gid); \ - setreuid(effective_uid, real_uid); \ - } +#define PRIV_END { \ + setegid(real_gid); \ + seteuid(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); \ - } +#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