Author: pjd Date: Wed Jul 3 20:42:10 2013 New Revision: 252598 URL: http://svnweb.freebsd.org/changeset/base/252598
Log: Sandbox rwho(1) using capability mode and Capsicum capabilities. rwho(1) gets only read-only access to /var/rwho/ directory. Submitted by: Mariusz Zaborski <osho...@freebsd.org> Sponsored by: Google Summer of Code 2013 Reviewed by: pjd MFC after: 1 month Modified: head/usr.bin/rwho/rwho.c Modified: head/usr.bin/rwho/rwho.c ============================================================================== --- head/usr.bin/rwho/rwho.c Wed Jul 3 20:29:15 2013 (r252597) +++ head/usr.bin/rwho/rwho.c Wed Jul 3 20:42:10 2013 (r252598) @@ -1,5 +1,6 @@ /*- * Copyright (c) 1983, 1993 The Regents of the University of California. + * Copyright (c) 2013 Mariusz Zaborski <osho...@freebsd.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,6 +43,7 @@ static char sccsid[] = "@(#)rwho.c 8.1 ( #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <sys/capability.h> #include <sys/param.h> #include <sys/file.h> @@ -49,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include <dirent.h> #include <err.h> +#include <errno.h> #include <langinfo.h> #include <locale.h> #include <stdio.h> @@ -92,6 +95,8 @@ main(int argc, char *argv[]) struct myutmp *mp; int f, n, i; int d_first; + int dfd; + time_t ct; w = &wd; (void) setlocale(LC_TIME, ""); @@ -113,16 +118,31 @@ main(int argc, char *argv[]) if (argc != 0) usage(); - if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL) - err(1, "%s", _PATH_RWHODIR); + if (chdir(_PATH_RWHODIR) < 0) + err(1, "chdir(%s)", _PATH_RWHODIR); + if ((dirp = opendir(".")) == NULL) + err(1, "opendir(%s)", _PATH_RWHODIR); + dfd = dirfd(dirp); mp = myutmp; + if (cap_rights_limit(dfd, CAP_READ | CAP_LOOKUP) < 0 && errno != ENOSYS) + err(1, "cap_rights_limit failed: %s", _PATH_RWHODIR); + /* + * Cache files required for time(3) and localtime(3) before entering + * capability mode. + */ + (void) time(&ct); + (void) localtime(&ct); + if (cap_enter() < 0 && errno != ENOSYS) + err(1, "cap_enter"); (void) time(&now); while ((dp = readdir(dirp)) != NULL) { if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5) != 0) continue; - f = open(dp->d_name, O_RDONLY); + f = openat(dfd, dp->d_name, O_RDONLY); if (f < 0) continue; + if (cap_rights_limit(f, CAP_READ) < 0 && errno != ENOSYS) + err(1, "cap_rights_limit failed: %s", dp->d_name); cc = read(f, (char *)&wd, sizeof (struct whod)); if (cc < WHDRSIZE) { (void) close(f); _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"