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
This commit is contained in:
David van Moolenbroek 2015-06-06 11:21:23 +00:00
parent 7eb698ea4a
commit dfc3261535
3 changed files with 25 additions and 9 deletions

View file

@ -3,6 +3,7 @@
#include <minix/drivers.h> #include <minix/drivers.h>
#include <minix/fsdriver.h> #include <minix/fsdriver.h>
#include <minix/vfsif.h> #include <minix/vfsif.h>
#include <minix/rs.h>
#include <assert.h> #include <assert.h>
/* /*
@ -385,6 +386,20 @@ pfs_signal(int signo)
fsdriver_terminate(); 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. * Perform SEF initialization.
*/ */
@ -393,7 +408,7 @@ pfs_startup(void)
{ {
/* Register initialization callbacks. */ /* 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); sef_setcb_init_restart(sef_cb_init_fail);
/* No live update support for now. */ /* No live update support for now. */

View file

@ -12,6 +12,12 @@ Interface to the reincarnation server
#define SERVICE_LOGIN "service" /* passwd file entry for services */ #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. */ /* RSS definitions. */
#define RSS_NR_IRQ 16 #define RSS_NR_IRQ 16
#define RSS_NR_IO 16 #define RSS_NR_IO 16

View file

@ -161,7 +161,6 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info)
int timerand, fd; int timerand, fd;
u8_t randbits[32]; u8_t randbits[32];
struct timeval tv; struct timeval tv;
struct passwd *pw;
#if DEBUG #if DEBUG
printf("Starting inet...\n"); 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")); ip_panic(("inet: can't subscribe to driver events"));
} }
/* Drop root privileges */ /* Drop privileges. */
if ((pw = getpwnam(SERVICE_LOGIN)) == NULL) { if (setuid(SERVICE_UID) != 0)
printf("inet: unable to retrieve uid of SERVICE_LOGIN, " printf("inet: warning, unable to drop privileges\n");
"still running as root");
} else if (setuid(pw->pw_uid) != 0) {
ip_panic(("inet: unable to drop privileges"));
}
/* Announce we are up. INET announces its presence to VFS just like /* Announce we are up. INET announces its presence to VFS just like
* any other character driver. * any other character driver.