svn commit: r253457 - head/usr.bin/uniq

Pawel Jakub Dawidek pjd at FreeBSD.org
Thu Jul 18 22:11:28 UTC 2013


Author: pjd
Date: Thu Jul 18 22:11:27 2013
New Revision: 253457
URL: http://svnweb.freebsd.org/changeset/base/253457

Log:
  Close uniq(1) in the capability mode sandbox and limit descriptors using
  capability rights.

Modified:
  head/usr.bin/uniq/uniq.c

Modified: head/usr.bin/uniq/uniq.c
==============================================================================
--- head/usr.bin/uniq/uniq.c	Thu Jul 18 21:56:10 2013	(r253456)
+++ head/usr.bin/uniq/uniq.c	Thu Jul 18 22:11:27 2013	(r253457)
@@ -44,15 +44,20 @@ static const char rcsid[] =
   "$FreeBSD$";
 #endif /* not lint */
 
+#include <sys/capability.h>
+
 #include <ctype.h>
 #include <err.h>
+#include <errno.h>
 #include <limits.h>
 #include <locale.h>
+#include <nl_types.h>
 #include <stdint.h>
 #define _WITH_GETLINE
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <termios.h>
 #include <unistd.h>
 #include <wchar.h>
 #include <wctype.h>
@@ -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;


More information about the svn-src-all mailing list