Index: sys/sys/capsicum_misc.h =================================================================== --- /dev/null +++ sys/sys/capsicum_misc.h @@ -0,0 +1,91 @@ +/*- + * Copyright (c) 2016 Mariusz Zaborski + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _CAPSICUM_MISC_ +#define _CAPSICUM_MISC_ + +#include +#include + +#include +#include +#include +#include +#include +#include + +static inline bool +capm_limit_stdout(int fd) +{ + cap_rights_t rights; + unsigned long cmds[] = { TIOCGETA }; + + cap_rights_init(&rights, CAP_FSTAT, CAP_IOCTL, CAP_READ, CAP_WRITE); + if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS) + return (false); + + if (cap_ioctls_limit(fd, cmds, nitems(cmds)) < 0 && errno != ENOSYS) + return (false); + + return (true); +} + +static inline bool +capm_limit_stdin(int fd) +{ + cap_rights_t rights; + + cap_rights_init(&rights, CAP_FSTAT, CAP_READ); + + return (cap_rights_limit(fd, &rights) == 0 || errno == ENOSYS); +} + +static inline bool +capm_limit_stdio(void) +{ + + return (capm_limit_stdin(STDIN_FILENO) && + capm_limit_stdout(STDOUT_FILENO) && + capm_limit_stdout(STDERR_FILENO)); +} + +static inline void +capm_time(void) +{ + + tzset(); +} + +static inline void +capm_err(void) +{ + + (void)catopen("libc", NL_CAT_LOCALE); +} + +#endif /* _CAPSICUM_MISC_ */ Index: usr.bin/cmp/cmp.c =================================================================== --- usr.bin/cmp/cmp.c +++ usr.bin/cmp/cmp.c @@ -44,6 +44,7 @@ #include #include +#include #include #include @@ -53,7 +54,6 @@ #include #include #include -#include #include #include "extern.h" @@ -70,7 +70,6 @@ int ch, fd1, fd2, oflag, special; const char *file1, *file2; cap_rights_t rights; - unsigned long cmd; uint32_t fcntls; oflag = O_RDONLY; @@ -165,20 +164,12 @@ if (cap_fcntls_limit(fd2, fcntls) < 0 && errno != ENOSYS) err(ERR_EXIT, "unable to limit fcntls for %s", file2); - cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE, CAP_IOCTL); - if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) - err(ERR_EXIT, "unable to limit rights for stdout"); + if (capm_limit_stdout(STDOUT_FILENO)) + err(ERR_EXIT, "unable to limit stdout"); + if (capm_limit_stdout(STDERR_FILENO)) + err(ERR_EXIT, "unable to limit stderr"); - /* Required for printf(3) via isatty(3). */ - cmd = TIOCGETA; - if (cap_ioctls_limit(STDOUT_FILENO, &cmd, 1) < 0 && errno != ENOSYS) - err(ERR_EXIT, "unable to limit ioctls for stdout"); - - /* - * Cache NLS data, for strerror, for err(3), before entering capability - * mode. - */ - (void)catopen("libc", NL_CAT_LOCALE); + capm_err(); if (cap_enter() < 0 && errno != ENOSYS) err(ERR_EXIT, "unable to enter capability mode"); Index: usr.bin/col/col.c =================================================================== --- usr.bin/col/col.c +++ usr.bin/col/col.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include @@ -135,20 +136,11 @@ int nflushd_lines; /* number of lines that were flushed */ int adjust, opt, warned, width; const char *errstr; - cap_rights_t rights; - unsigned long cmd; (void)setlocale(LC_CTYPE, ""); - cap_rights_init(&rights, CAP_FSTAT, CAP_READ); - if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) - err(1, "unable to limit rights for stdin"); - cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE, CAP_IOCTL); - if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) - err(1, "unable to limit rights for stdout"); - cmd = TIOCGETA; /* required by isatty(3) in printf(3) */ - if (cap_ioctls_limit(STDOUT_FILENO, &cmd, 1) < 0 && errno != ENOSYS) - err(1, "unable to limit ioctls for stdout"); + if (capm_limit_stdio()) + err(1, "unable to limit stdio"); if (cap_enter() < 0 && errno != ENOSYS) err(1, "unable to enter capability mode"); Index: usr.bin/elfdump/elfdump.c =================================================================== --- usr.bin/elfdump/elfdump.c +++ usr.bin/elfdump/elfdump.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -44,7 +45,6 @@ #include #include #include -#include #include #define ED_DYN (1<<0) @@ -505,7 +505,6 @@ u_int64_t name; u_int64_t type; struct stat sb; - unsigned long cmd; u_int flags; Elf32_Ehdr *e; void *p; @@ -573,14 +572,8 @@ cap_rights_init(&rights, CAP_MMAP_R); if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS) err(1, "unable to limit rights for %s", *av); - cap_rights_limit(STDIN_FILENO, cap_rights_init(&rights)); - cap_rights_init(&rights, CAP_FSTAT, CAP_IOCTL, CAP_WRITE); - cmd = TIOCGETA; /* required by isatty(3) in printf(3) */ - if ((cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) || - (cap_ioctls_limit(STDOUT_FILENO, &cmd, 1) < 0 && errno != ENOSYS) || - (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS) || - (cap_ioctls_limit(STDERR_FILENO, &cmd, 1) < 0 && errno != ENOSYS)) - err(1, "unable to limit rights for stdout/stderr"); + if (capm_limit_stdio()) + err(1, "unable to limit rights for stdio"); if (cap_enter() < 0 && errno != ENOSYS) err(1, "unable to enter capability mode"); e = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); Index: usr.bin/tee/tee.c =================================================================== --- usr.bin/tee/tee.c +++ usr.bin/tee/tee.c @@ -42,6 +42,7 @@ #endif /* not lint */ #include +#include #include #include @@ -52,7 +53,6 @@ #include #include #include -#include #include typedef struct _list { @@ -73,8 +73,6 @@ char *bp; int append, ch, exitval; char *buf; - cap_rights_t rights; - unsigned long cmd; #define BSIZE (8 * 1024) append = 0; @@ -96,15 +94,11 @@ if ((buf = malloc(BSIZE)) == NULL) err(1, "malloc"); - cap_rights_init(&rights, CAP_READ, CAP_FSTAT); - if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) - err(EXIT_FAILURE, "unable to limit rights for stdin"); - cap_rights_init(&rights, CAP_WRITE, CAP_FSTAT, CAP_IOCTL); - if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS) - err(EXIT_FAILURE, "unable to limit rights for stderr"); - cmd = TIOCGETA; - if (cap_ioctls_limit(STDERR_FILENO, &cmd, 1) < 0 && errno != ENOSYS) - err(EXIT_FAILURE, "unable to limit ioctls for stderr"); + if (capm_limit_stdin(STDIN_FILENO)) + err(EXIT_FAILURE, "unable to limit stdin"); + + if (capm_limit_stdout(STDERR_FILENO)) + err(EXIT_FAILURE, "unable to limit stderr"); add(STDOUT_FILENO, "stdout"); @@ -148,19 +142,14 @@ { LIST *p; cap_rights_t rights; - unsigned long cmd; - - if (fd == STDOUT_FILENO) - cap_rights_init(&rights, CAP_WRITE, CAP_FSTAT, CAP_IOCTL); - else - cap_rights_init(&rights, CAP_WRITE, CAP_FSTAT); - if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS) - err(EXIT_FAILURE, "unable to limit rights"); if (fd == STDOUT_FILENO) { - cmd = TIOCGETA; - if (cap_ioctls_limit(fd, &cmd, 1) < 0 && errno != ENOSYS) - err(EXIT_FAILURE, "unable to limit ioctls for stdout"); + if (capm_limit_stdout(STDOUT_FILENO)) + err(EXIT_FAILURE, "unable to limit stdout"); + } else { + cap_rights_init(&rights, CAP_WRITE, CAP_FSTAT); + if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to limit rights"); } if ((p = malloc(sizeof(LIST))) == NULL) Index: usr.bin/tr/tr.c =================================================================== --- usr.bin/tr/tr.c +++ usr.bin/tr/tr.c @@ -43,17 +43,16 @@ #include #include +#include #include #include -#include #include #include #include #include #include #include -#include #include #include #include @@ -72,8 +71,6 @@ main(int argc, char **argv) { static int carray[NCHARS_SB]; - cap_rights_t rights; - unsigned long cmd; struct cmap *map; struct cset *delete, *squeeze; int n, *p; @@ -82,23 +79,8 @@ (void)setlocale(LC_ALL, ""); - cap_rights_init(&rights, CAP_FSTAT, CAP_IOCTL, CAP_READ); - if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) - err(1, "unable to limit rights for stdin"); - cap_rights_init(&rights, CAP_FSTAT, CAP_IOCTL, CAP_WRITE); - if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) - err(1, "unable to limit rights for stdout"); - if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS) - err(1, "unable to limit rights for stderr"); - - /* Required for isatty(3). */ - cmd = TIOCGETA; - if (cap_ioctls_limit(STDIN_FILENO, &cmd, 1) < 0 && errno != ENOSYS) - err(1, "unable to limit ioctls for stdin"); - if (cap_ioctls_limit(STDOUT_FILENO, &cmd, 1) < 0 && errno != ENOSYS) - err(1, "unable to limit ioctls for stdout"); - if (cap_ioctls_limit(STDERR_FILENO, &cmd, 1) < 0 && errno != ENOSYS) - err(1, "unable to limit ioctls for stderr"); + if (capm_limit_stdio()) + err(1, "unable to limit stdio"); if (cap_enter() < 0 && errno != ENOSYS) err(1, "unable to enter capability mode");