From dfc326153594d66dfe6fe8e63ec89bc102b0e050 Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Sat, 6 Jun 2015 11:21:23 +0000 Subject: [PATCH] PFS, inet: use static UID to drop privileges Previously, services would obtain the user ID of "service" through getpwnam(3). While this approach is conceptually better, it also imposes linking against libc which in turn causes problems with printf(3), which already led to PFS no longer dropping privileges at all. For now, we hardcode SERVICE_UID and use that instead. In the future, two changes should allow removal of SERVICE_UID again: - "service edit" should cause RS to request that a service (such as PFS) drop privileges through SEF, using the user ID resolved by service(8), or something similar; - a future devfs should make it possible for inet to start without root privileges altogether. Change-Id: Ie02a1e888cde325806fc0ae76909943ac42c9b96 --- minix/fs/pfs/pfs.c | 17 ++++++++++++++++- minix/include/minix/rs.h | 6 ++++++ minix/net/inet/inet.c | 11 +++-------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/minix/fs/pfs/pfs.c b/minix/fs/pfs/pfs.c index 52750a728..f73adb6fd 100644 --- a/minix/fs/pfs/pfs.c +++ b/minix/fs/pfs/pfs.c @@ -3,6 +3,7 @@ #include #include #include +#include #include /* @@ -385,6 +386,20 @@ pfs_signal(int signo) fsdriver_terminate(); } +/* + * Initialize PFS. + */ +static int +pfs_init(int __unused type, sef_init_info_t * __unused info) +{ + + /* Drop privileges. */ + if (setuid(SERVICE_UID) != 0) + printf("PFS: warning, unable to drop privileges\n"); + + return OK; +} + /* * Perform SEF initialization. */ @@ -393,7 +408,7 @@ pfs_startup(void) { /* Register initialization callbacks. */ - sef_setcb_init_fresh(sef_cb_init_null); + sef_setcb_init_fresh(pfs_init); sef_setcb_init_restart(sef_cb_init_fail); /* No live update support for now. */ diff --git a/minix/include/minix/rs.h b/minix/include/minix/rs.h index f5f8621d6..36dcf06ef 100644 --- a/minix/include/minix/rs.h +++ b/minix/include/minix/rs.h @@ -12,6 +12,12 @@ Interface to the reincarnation server #define SERVICE_LOGIN "service" /* passwd file entry for services */ +/* The following definition should be kept in sync with the actual /etc/passwd + * value for SERVICE_LOGIN for now, and removed altogether once we are able to + * obtain its value dynamically everywhere. + */ +#define SERVICE_UID 12 /* user ID for services */ + /* RSS definitions. */ #define RSS_NR_IRQ 16 #define RSS_NR_IO 16 diff --git a/minix/net/inet/inet.c b/minix/net/inet/inet.c index 1c6aecb67..09ce1bfe4 100644 --- a/minix/net/inet/inet.c +++ b/minix/net/inet/inet.c @@ -161,7 +161,6 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info) int timerand, fd; u8_t randbits[32]; struct timeval tv; - struct passwd *pw; #if DEBUG printf("Starting inet...\n"); @@ -236,13 +235,9 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info) ip_panic(("inet: can't subscribe to driver events")); } - /* Drop root privileges */ - if ((pw = getpwnam(SERVICE_LOGIN)) == NULL) { - printf("inet: unable to retrieve uid of SERVICE_LOGIN, " - "still running as root"); - } else if (setuid(pw->pw_uid) != 0) { - ip_panic(("inet: unable to drop privileges")); - } + /* Drop privileges. */ + if (setuid(SERVICE_UID) != 0) + printf("inet: warning, unable to drop privileges\n"); /* Announce we are up. INET announces its presence to VFS just like * any other character driver.