Index: usr.bin/lam/lam.c =================================================================== --- usr.bin/lam/lam.c +++ usr.bin/lam/lam.c @@ -46,11 +46,17 @@ * Author: John Kunze, UCB */ +#include + #include #include +#include +#include #include #include #include +#include +#include #define MAXOFILES 20 #define BIGBUFSIZ 5 * BUFSIZ @@ -74,6 +80,38 @@ static char *pad(struct openfile *); static void usage(void); +/* XXX: Replace with new capsicum helper once it is available */ +static void +setup_capsicum(void) +{ + cap_rights_t rights; + unsigned long cmd; + + 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_WRITE, CAP_IOCTL); + 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 printf(3) via 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"); + + /* + * Cache NLS data, for strerror, for err(3), before entering capability + * mode. + */ + (void)catopen("libc", NL_CAT_LOCALE); +} + int main(int argc, char *argv[]) { @@ -81,9 +119,16 @@ if (argc == 1) usage(); + + setup_capsicum(); + getargs(argv); if (!morefiles) usage(); + + if (cap_enter() < 0 && errno != ENOSYS) + err(1, "unable to enter capability mode"); + for (;;) { linep = line; for (ip = input; ip->fp != NULL; ip++) @@ -105,6 +150,9 @@ static char fmtbuf[BUFSIZ]; char *fmtp = fmtbuf; int P, S, F, T; + cap_rights_t rights_ro; + + cap_rights_init(&rights_ro, CAP_READ, CAP_FSTAT); P = S = F = T = 0; /* capitalized options */ while ((p = *++av) != NULL) { @@ -116,6 +164,8 @@ else if ((ip->fp = fopen(p, "r")) == NULL) { err(1, "%s", p); } + if (cap_rights_limit(fileno(ip->fp), &rights_ro) < 0) + err(1, "unable to limit rights on: %s", p); ip->pad = P; if (!ip->sepstring) ip->sepstring = (S ? (ip-1)->sepstring : "");