From de89bd6bc26b31aef15dff6682a9b03d0566c678 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Thu, 18 Jul 2013 22:11:27 +0000 Subject: [PATCH] Close uniq(1) in the capability mode sandbox and limit descriptors using capability rights. --- usr.bin/uniq/uniq.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/usr.bin/uniq/uniq.c b/usr.bin/uniq/uniq.c index 1077307dab1c..d34b0c0a5b37 100644 --- a/usr.bin/uniq/uniq.c +++ b/usr.bin/uniq/uniq.c @@ -44,15 +44,20 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#include + #include #include +#include #include #include +#include #include #define _WITH_GETLINE #include #include #include +#include #include #include #include @@ -68,6 +73,17 @@ static wchar_t *skip(wchar_t *); static void obsolete(char *[]); static void usage(void); +static void +strerror_init(void) +{ + + /* + * Cache NLS data before entering capability mode. + * XXXPJD: There should be strerror_init() and strsignal_init() in libc. + */ + (void)catopen("libc", NL_CAT_LOCALE); +} + int main (int argc, char *argv[]) { @@ -77,6 +93,7 @@ main (int argc, char *argv[]) size_t prevbuflen, thisbuflen, b1; char *prevline, *thisline, *p; const char *ifn; + cap_rights_t rights; (void) setlocale(LC_ALL, ""); @@ -128,8 +145,34 @@ main (int argc, char *argv[]) ofp = stdout; if (argc > 0 && strcmp(argv[0], "-") != 0) ifp = file(ifn = argv[0], "r"); + if (cap_rights_limit(fileno(ifp), CAP_FSTAT | CAP_READ) < 0 && + errno != ENOSYS) { + err(1, "unable to limit rights for %s", ifn); + } + rights = CAP_FSTAT | CAP_WRITE; if (argc > 1) ofp = file(argv[1], "w"); + else + rights |= CAP_IOCTL; + if (cap_rights_limit(fileno(ofp), rights) < 0 && errno != ENOSYS) { + err(1, "unable to limit rights for %s", + argc > 1 ? argv[1] : "stdout"); + } + if ((rights & CAP_IOCTL) != 0) { + unsigned long cmd; + + cmd = TIOCGETA; /* required by isatty(3) in printf(3) */ + + if (cap_ioctls_limit(fileno(ofp), &cmd, 1) < 0 && + errno != ENOSYS) { + err(1, "unable to limit ioctls for %s", + argc > 1 ? argv[1] : "stdout"); + } + } + + strerror_init(); + if (cap_enter() < 0 && errno != ENOSYS) + err(1, "unable to enter capability mode"); prevbuflen = thisbuflen = 0; prevline = thisline = NULL;