Index: usr.bin/ident/ident.c =================================================================== --- usr.bin/ident/ident.c +++ usr.bin/ident/ident.c @@ -28,15 +28,18 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include #include #include +#include #include #include #include #include +#include #include typedef enum { @@ -201,6 +204,8 @@ int main(int argc, char **argv) { + cap_rights_t rights; + unsigned long cmd; bool quiet = false; int ch, i; int ret = EXIT_SUCCESS; @@ -223,8 +228,30 @@ argc -= optind; argv += optind; - if (argc == 0) + cap_rights_init(&rights, CAP_FSTAT, CAP_IOCTL, CAP_WRITE); + if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to limit rights for stdout"); + if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to limit rights for stderr"); + + cap_rights_init(&rights, CAP_FSTAT, CAP_IOCTL, CAP_READ); + if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to limit rights for stdin"); + + /* Required for printf(3)/std input, via isatty(3). */ + cmd = TIOCGETA; + if (cap_ioctls_limit(STDOUT_FILENO, &cmd, 1) < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to limit ioctls for stdout"); + if (cap_ioctls_limit(STDERR_FILENO, &cmd, 1) < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to limit ioctls for stderr"); + if (cap_ioctls_limit(STDIN_FILENO, &cmd, 1) < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to limit ioctls for stdin"); + + if (argc == 0) { + if (cap_enter() < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to enter capability mode"); return (scan(stdin, NULL, quiet)); + } for (i = 0; i < argc; i++) { fp = fopen(argv[i], "r"); @@ -233,6 +260,12 @@ ret = EXIT_FAILURE; continue; } + cap_rights_init(&rights, CAP_FSTAT, CAP_READ); + if (cap_rights_limit(fileno(fp), &rights) < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to limit rights for %s", argv[i]); + /* Enter Capsicum sandbox for last file. */ + if (i + 1 == argc && cap_enter() < 0 && errno != ENOSYS) + err(EXIT_FAILURE, "unable to enter capability mode"); if (scan(fp, argv[i], quiet) != EXIT_SUCCESS) ret = EXIT_FAILURE; fclose(fp);