The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=9b20849bc5f1b500f2de7aeca77f0e6556069bbb

commit 9b20849bc5f1b500f2de7aeca77f0e6556069bbb
Author:     Ricardo Branco <rbra...@suse.de>
AuthorDate: 2024-01-03 18:00:47 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2024-01-16 14:38:53 +0000

    md5: Enter capability mode earlier
    
    Reviewed by:    markj
    MFC after:      1 month
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/988
---
 sbin/md5/Makefile |  9 ++++++---
 sbin/md5/md5.c    | 57 +++++++++++++++++++++++++++++++------------------------
 2 files changed, 38 insertions(+), 28 deletions(-)

diff --git a/sbin/md5/Makefile b/sbin/md5/Makefile
index c9bf16796459..f91e84323b04 100644
--- a/sbin/md5/Makefile
+++ b/sbin/md5/Makefile
@@ -58,16 +58,19 @@ MLINKS=     md5.1 md5sum.1 \
 
 LIBADD=        md
 
-.ifndef(BOOTSTRAPPING)
+.include <src.opts.mk>
+
+.if ${MK_CASPER} != "no" && !defined(RESCUE) && !defined(BOOTSTRAPPING)
 # Avoid depending on capsicum during bootstrap. caph_limit_stdout() is not
 # available when building for Linux/MacOS or older FreeBSD hosts.
 # We need to bootstrap md5 when building on Linux since the md5sum command 
there
 # produces different output.
 CFLAGS+=-DHAVE_CAPSICUM
+CFLAGS+=-DWITH_CASPER
+LIBADD+=       casper
+LIBADD+=       cap_fileargs
 .endif
 
-.include <src.opts.mk>
-
 HAS_TESTS=
 SUBDIR.${MK_TESTS}+= tests
 
diff --git a/sbin/md5/md5.c b/sbin/md5/md5.c
index abaadb12f3ee..c8292fe2f692 100644
--- a/sbin/md5/md5.c
+++ b/sbin/md5/md5.c
@@ -46,6 +46,8 @@
 #ifdef HAVE_CAPSICUM
 #include <sys/capsicum.h>
 #include <capsicum_helpers.h>
+#include <libcasper.h>
+#include <casper/cap_fileargs.h>
 #endif
 
 /*
@@ -310,6 +312,7 @@ gnu_check(const char *checksumsfile)
        const char      *digestname;
        size_t  digestnamelen;
        size_t  hashstrlen;
+       struct stat st;
 
        if (strcmp(checksumsfile, "-") == 0)
                inp = stdin;
@@ -357,6 +360,15 @@ gnu_check(const char *checksumsfile)
                rec = malloc(sizeof(*rec));
                if (rec == NULL)
                        errx(1, "malloc failed");
+
+               if (*filename == '*' ||
+                   *filename == ' ' ||
+                   *filename == 'U' ||
+                   *filename == '^') {
+                       if (lstat(filename, &st) != 0)
+                               filename++;
+               }
+
                rec->chksum = strdup(hashstr);
                rec->filename = strdup(filename);
                if (rec->chksum == NULL || rec->filename == NULL)
@@ -384,6 +396,7 @@ main(int argc, char *argv[])
 {
 #ifdef HAVE_CAPSICUM
        cap_rights_t    rights;
+       fileargs_t      *fa = NULL;
 #endif
        const struct option *longopts;
        const char *shortopts;
@@ -584,24 +597,25 @@ main(int argc, char *argv[])
                rec = head;
        }
 
+#ifdef HAVE_CAPSICUM
+       fa = fileargs_init(argc, argv, O_RDONLY, 0,
+           cap_rights_init(&rights, CAP_READ, CAP_FSTAT, CAP_FCNTL), FA_OPEN | 
FA_LSTAT);
+       if (fa == NULL)
+               err(1, "Unable to initialize casper");
+       if (caph_enter_casper() < 0)
+               err(1, "Unable to enter capability mode");
+#endif
+
        if (*argv) {
                do {
-                       struct stat st;
                        const char *filename = *argv;
                        const char *filemode = "rb";
 
-                       if (*filename == '*' ||
-                           *filename == ' ' ||
-                           *filename == 'U' ||
-                           *filename == '^') {
-                               if (lstat(filename, &st) != 0) {
-                                       input_mode = (int)*filename;
-                                       filename++;
-                               }
-                       }
-                       if (input_mode == input_text)
-                               filemode = "r";
+#ifdef HAVE_CAPSICUM
+                       if ((f = fileargs_fopen(fa, filename, filemode)) == 
NULL) {
+#else
                        if ((f = fopen(filename, filemode)) == NULL) {
+#endif
                                if (errno != ENOENT || !(cflag && 
ignoreMissing)) {
                                        warn("%s", filename);
                                        failed = true;
@@ -610,20 +624,10 @@ main(int argc, char *argv[])
                                        rec = rec->next;
                                continue;
                        }
-                       /*
-                        * XXX Enter capability mode on the last argv file.
-                        * When a casper file service or other approach is
-                        * available, switch to that and enter capability mode
-                        * earlier.
-                        */
-                       if (*(argv + 1) == NULL) {
 #ifdef HAVE_CAPSICUM
-                               cap_rights_init(&rights, CAP_READ, CAP_FSTAT);
-                               if (caph_rights_limit(fileno(f), &rights) < 0 ||
-                                   caph_enter() < 0)
-                                       err(1, "capsicum");
+                       if (caph_rights_limit(fileno(f), &rights) < 0)
+                               err(1, "capsicum");
 #endif
-                       }
                        if (cflag && mode != mode_bsd) {
                                checkAgainst = rec->chksum;
                                rec = rec->next;
@@ -634,7 +638,7 @@ main(int argc, char *argv[])
                } while (*++argv);
        } else if (!cflag && string == NULL && !skip) {
 #ifdef HAVE_CAPSICUM
-               if (caph_limit_stdin() < 0 || caph_enter() < 0)
+               if (caph_limit_stdin() < 0)
                        err(1, "capsicum");
 #endif
                if (mode == mode_bsd)
@@ -658,6 +662,9 @@ main(int argc, char *argv[])
                if (checksFailed != 0 || (strict && malformed > 0))
                        return (1);
        }
+#ifdef HAVE_CAPSICUM
+       fileargs_free(fa);
+#endif
        if (failed)
                return (1);
        if (checksFailed > 0)

Reply via email to