Index: sbin/fsck_ffs/Makefile =================================================================== --- sbin/fsck_ffs/Makefile +++ sbin/fsck_ffs/Makefile @@ -1,6 +1,8 @@ # $FreeBSD$ # @(#)Makefile 8.2 (Berkeley) 4/27/95 +.include + PACKAGE=runtime PROG= fsck_ffs LINKS+= ${BINDIR}/fsck_ffs ${BINDIR}/fsck_ufs @@ -14,6 +16,13 @@ WARNS?= 2 CFLAGS+= -I${.CURDIR} -I${.CURDIR:H}/mount +.if ${MK_CASPER} != "no" +LIBADD+= casper +LIBADD+= cap_sysctl +LIBADD+= cap_pwd +CFLAGS+= -DWITH_CASPER +.endif + .PATH: ${SRCTOP}/sys/ufs/ffs ${.CURDIR:H}/mount .include Index: sbin/fsck_ffs/dir.c =================================================================== --- sbin/fsck_ffs/dir.c +++ sbin/fsck_ffs/dir.c @@ -51,6 +51,8 @@ #include "fsck.h" +#include + static struct dirtemplate emptydir = { 0, DIRBLKSIZ, DT_UNKNOWN, 0, "", 0, 0, DT_UNKNOWN, 0, "" @@ -411,7 +413,7 @@ printf("adjrefcnt ino %ld amt %lld\n", (long)cmd.value, (long long)cmd.size); - if (sysctl(adjrefcnt, MIBSIZE, 0, 0, + if (cap_sysctl(capsysctl, adjrefcnt, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST INODE", cmd.value); } Index: sbin/fsck_ffs/fsck.h =================================================================== --- sbin/fsck_ffs/fsck.h +++ sbin/fsck_ffs/fsck.h @@ -71,6 +71,8 @@ #include +#include + #define MAXDUP 10 /* limit on dup blks (per inode) */ #define MAXBAD 10 /* limit on bad blks (per inode) */ #define MINBUFS 10 /* minimum number of buffers required */ @@ -290,6 +292,8 @@ extern unsigned long numdirs, listmax; extern long countdirs; /* number of directories we actually found */ +extern cap_channel_t *cappwd; +extern cap_channel_t *capsysctl; #define MIBSIZE 3 /* size of fsck sysctl MIBs */ extern int adjrefcnt[MIBSIZE]; /* MIB command to adjust inode reference cnt */ extern int adjblkcnt[MIBSIZE]; /* MIB command to adjust inode block count */ Index: sbin/fsck_ffs/fsutil.c =================================================================== --- sbin/fsck_ffs/fsutil.c +++ sbin/fsck_ffs/fsutil.c @@ -64,6 +64,8 @@ #include "fsck.h" +#include + static void slowio_start(void); static void slowio_end(void); static void printIOstats(void); @@ -403,7 +405,7 @@ if ((!(sblock.fs_flags & FS_UNCLEAN)) != markclean) { cmd.value = FS_UNCLEAN; cmd.size = markclean ? -1 : 1; - if (sysctlbyname("vfs.ffs.setflags", 0, 0, + if (cap_sysctlbyname(capsysctl, "vfs.ffs.setflags", 0, 0, &cmd, sizeof cmd) == -1) rwerror("SET FILE SYSTEM FLAGS", FS_UNCLEAN); if (!preen) { @@ -985,7 +987,7 @@ if (bkgrdflag) { cmd.value = FS_NEEDSFSCK; cmd.size = 1; - if (sysctlbyname("vfs.ffs.setflags", 0, 0, + if (cap_sysctlbyname(capsysctl, "vfs.ffs.setflags", 0, 0, &cmd, sizeof cmd) == -1) pwarn("CANNOT SET FS_NEEDSFSCK FLAG\n"); fprintf(stdout, "CANNOT RUN IN BACKGROUND\n"); @@ -1007,7 +1009,7 @@ if (bkgrdflag) { cmd.value = FS_NEEDSFSCK; cmd.size = 1; - if (sysctlbyname("vfs.ffs.setflags", 0, 0, + if (cap_sysctlbyname(capsysctl, "vfs.ffs.setflags", 0, 0, &cmd, sizeof cmd) == -1) pwarn("CANNOT SET FS_NEEDSFSCK FLAG\n"); } Index: sbin/fsck_ffs/inode.c =================================================================== --- sbin/fsck_ffs/inode.c +++ sbin/fsck_ffs/inode.c @@ -53,6 +53,9 @@ #include "fsck.h" +#include +#include + static ino_t startinum; static int iblock(struct inodesc *, off_t isize, int type); @@ -593,7 +596,7 @@ if (debug) printf("adjrefcnt ino %ld amt %lld\n", (long)cmd.value, (long long)cmd.size); - if (sysctl(adjrefcnt, MIBSIZE, 0, 0, + if (cap_sysctl(capsysctl, adjrefcnt, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST INODE", cmd.value); } @@ -652,7 +655,7 @@ if (ino < UFS_ROOTINO || ino > maxino) return; printf(" OWNER="); - if ((pw = getpwuid((int)DIP(dp, di_uid))) != NULL) + if ((pw = cap_getpwuid(cappwd, (int)DIP(dp, di_uid))) != NULL) printf("%s ", pw->pw_name); else printf("%u ", (unsigned)DIP(dp, di_uid)); Index: sbin/fsck_ffs/main.c =================================================================== --- sbin/fsck_ffs/main.c +++ sbin/fsck_ffs/main.c @@ -69,6 +69,9 @@ #include "fsck.h" +#include +#include + int restarts; static void usage(void) __dead2; @@ -76,6 +79,9 @@ static int checkfilesys(char *filesys); static int chkdoreload(struct statfs *mntp); static struct statfs *getmntpt(const char *); +static void cap_open(void); + +cap_channel_t *cappwd, *capsysctl; int main(int argc, char *argv[]) @@ -245,6 +251,7 @@ int cylno; intmax_t blks, files; size_t size; + int setupres; iov = NULL; iovlen = 0; @@ -402,8 +409,9 @@ filesys = snapname; } } - - switch (setup(filesys)) { + setupres = setup(filesys); + cap_open(); + switch (setupres) { case 0: if (preen) pfatal("CAN'T CHECK FILE SYSTEM."); @@ -750,3 +758,30 @@ { got_sigalarm = 1; } + +void cap_open() +{ + cap_channel_t *capcas; + const char *name = "kern.trap_enotcap"; + void *limit; + + capcas = cap_init(); + if (capcas == NULL) + err(1, "Unable to contact Casper"); + caph_cache_tzdata(); + /* Enter capability mode sandbox */ + if (caph_enter_casper() < 0) + err(1, "Unable to enter capability mode"); + cappwd = cap_service_open(capcas, "system.pwd"); + if (cappwd == NULL) + err(1, "Unable to open system.pwd service"); + capsysctl = cap_service_open(capcas, "system.sysctl"); + if (capsysctl == NULL) + err(1, "Unable to open system.sysctl service"); + limit = cap_sysctl_limit_init(capsysctl); + (void)cap_sysctl_limit_name(limit, name, CAP_SYSCTL_READ); + if (cap_sysctl_limit(limit) < 0) + err(1, "Unable to set cap_sysctl limits"); + cap_close(capcas); + return; +} Index: sbin/fsck_ffs/pass1.c =================================================================== --- sbin/fsck_ffs/pass1.c +++ sbin/fsck_ffs/pass1.c @@ -52,6 +52,8 @@ #include "fsck.h" +#include + static ufs2_daddr_t badblk; static ufs2_daddr_t dupblk; static ino_t lastino; /* last inode in use */ @@ -418,7 +420,7 @@ if (debug) printf("adjblkcnt ino %ju amount %lld\n", (uintmax_t)cmd.value, (long long)cmd.size); - if (sysctl(adjblkcnt, MIBSIZE, 0, 0, + if (cap_sysctl(capsysctl, adjblkcnt, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST INODE BLOCK COUNT", cmd.value); } @@ -457,7 +459,7 @@ if (debug) printf("setsize ino %ju size set to %ju\n", (uintmax_t)cmd.value, (uintmax_t)cmd.size); - if (sysctl(setsize, MIBSIZE, 0, 0, + if (cap_sysctl(capsysctl, setsize, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("SET INODE SIZE", cmd.value); } Index: sbin/fsck_ffs/pass2.c =================================================================== --- sbin/fsck_ffs/pass2.c +++ sbin/fsck_ffs/pass2.c @@ -51,6 +51,8 @@ #include "fsck.h" +#include + #define MINDIRSIZE (sizeof (struct dirtemplate)) static int fix_extraneous(struct inoinfo *, struct inodesc *); @@ -241,7 +243,7 @@ * setdotdot(inp->i_dotdot, inp->i_parent); */ cmd.value = inp->i_number; - if (sysctlbyname("vfs.ffs.setcwd", 0, 0, + if (cap_sysctlbyname(capsysctl, "vfs.ffs.setcwd", 0, 0, &cmd, sizeof cmd) == -1) { /* kernel lacks support for these functions */ printf(" (IGNORED)\n"); @@ -249,7 +251,7 @@ } cmd.value = inp->i_dotdot; /* verify same value */ cmd.size = inp->i_parent; /* new parent */ - if (sysctlbyname("vfs.ffs.setdotdot", 0, 0, + if (cap_sysctlbyname(capsysctl, "vfs.ffs.setdotdot", 0, 0, &cmd, sizeof cmd) == -1) { printf(" (FIX FAILED: %s)\n", strerror(errno)); continue; @@ -455,7 +457,7 @@ * rmdir(dirp->d_name); */ cmd.value = idesc->id_number; - if (sysctlbyname("vfs.ffs.setcwd", 0, 0, + if (cap_sysctlbyname(capsysctl, "vfs.ffs.setcwd", 0, 0, &cmd, sizeof cmd) == -1) { /* kernel lacks support */ printf(" (IGNORED)\n"); @@ -576,14 +578,14 @@ * unlink(idesc->id_dirp->d_name); */ cmd.value = idesc->id_number; - if (sysctlbyname("vfs.ffs.setcwd", 0, 0, + if (cap_sysctlbyname(capsysctl, "vfs.ffs.setcwd", 0, 0, &cmd, sizeof cmd) == -1) { printf(" (IGNORED)\n"); return (0); } cmd.value = (intptr_t)idesc->id_dirp->d_name; cmd.size = inp->i_number; /* verify same name */ - if (sysctlbyname("vfs.ffs.unlink", 0, 0, + if (cap_sysctlbyname(capsysctl, "vfs.ffs.unlink", 0, 0, &cmd, sizeof cmd) == -1) { printf(" (UNLINK FAILED: %s)\n", strerror(errno)); @@ -613,7 +615,7 @@ * unlink(last component of oldname pathname); */ cmd.value = inp->i_parent; - if (sysctlbyname("vfs.ffs.setcwd", 0, 0, + if (cap_sysctlbyname(capsysctl, "vfs.ffs.setcwd", 0, 0, &cmd, sizeof cmd) == -1) { printf(" (IGNORED)\n"); return (0); @@ -624,7 +626,7 @@ } cmd.value = (intptr_t)(cp + 1); cmd.size = inp->i_number; /* verify same name */ - if (sysctlbyname("vfs.ffs.unlink", 0, 0, + if (cap_sysctlbyname(capsysctl, "vfs.ffs.unlink", 0, 0, &cmd, sizeof cmd) == -1) { printf(" (UNLINK FAILED: %s)\n", strerror(errno)); Index: sbin/fsck_ffs/pass5.c =================================================================== --- sbin/fsck_ffs/pass5.c +++ sbin/fsck_ffs/pass5.c @@ -51,6 +51,8 @@ #include "fsck.h" +#include + static void check_maps(u_char *, u_char *, int, ufs2_daddr_t, const char *, int *, int, int, int); static void clear_blocks(ufs2_daddr_t start, ufs2_daddr_t end); @@ -392,7 +394,7 @@ if (cmd.value != 0) { if (debug) printf("adjndir by %+" PRIi64 "\n", cmd.value); - if (bkgrdsumadj == 0 || sysctl(adjndir, MIBSIZE, 0, 0, + if (bkgrdsumadj == 0 || cap_sysctl(capsysctl, adjndir, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST NUMBER OF DIRECTORIES", cmd.value); } @@ -401,7 +403,7 @@ if (cmd.value != 0) { if (debug) printf("adjnbfree by %+" PRIi64 "\n", cmd.value); - if (bkgrdsumadj == 0 || sysctl(adjnbfree, MIBSIZE, 0, 0, + if (bkgrdsumadj == 0 || cap_sysctl(capsysctl, adjnbfree, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST NUMBER OF FREE BLOCKS", cmd.value); } @@ -410,7 +412,7 @@ if (cmd.value != 0) { if (debug) printf("adjnifree by %+" PRIi64 "\n", cmd.value); - if (bkgrdsumadj == 0 || sysctl(adjnifree, MIBSIZE, 0, 0, + if (bkgrdsumadj == 0 || cap_sysctl(capsysctl, adjnifree, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST NUMBER OF FREE INODES", cmd.value); } @@ -419,7 +421,7 @@ if (cmd.value != 0) { if (debug) printf("adjnffree by %+" PRIi64 "\n", cmd.value); - if (bkgrdsumadj == 0 || sysctl(adjnffree, MIBSIZE, 0, 0, + if (bkgrdsumadj == 0 || cap_sysctl(capsysctl, adjnffree, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST NUMBER OF FREE FRAGS", cmd.value); } @@ -428,7 +430,7 @@ if (cmd.value != 0) { if (debug) printf("adjnumclusters by %+" PRIi64 "\n", cmd.value); - if (bkgrdsumadj == 0 || sysctl(adjnumclusters, MIBSIZE, 0, 0, + if (bkgrdsumadj == 0 || cap_sysctl(capsysctl, adjnumclusters, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST NUMBER OF FREE CLUSTERS", cmd.value); } @@ -553,7 +555,7 @@ if (usesysctl != 0) { cmd.value = ustart; cmd.size = size; - if (sysctl(opcode, MIBSIZE, 0, 0, + if (cap_sysctl(capsysctl, opcode, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) { snprintf(buf, BUFSIZE, "FREE %s", name); @@ -599,7 +601,7 @@ if (usesysctl != 0) { cmd.value = ustart; cmd.size = size; - if (sysctl(opcode, MIBSIZE, 0, 0, &cmd, + if (cap_sysctl(capsysctl, opcode, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) { snprintf(buf, BUFSIZE, "FREE %s", name); rwerror(buf, cmd.value);