I have to say I'm only a beginner to C but hopefully my patch is
good.

This patch adds a second and more restrictive pledge (only "stdio"
instead of "stdio rpath") after the getopt loop if there is no
input file or if the input file is "-" (stdin) or a sequence of
repeated instances of "-". It doesn't move argv past the last "-",
and doesn't pledge if it runs into an input file other than "-".

I've compiled it and tested it with ktrace(1) and kdump(1) and it
appears to work as expected and pledge correctly with at least
these invocations:
$ echo test | ./cat -uv     # pledge("stdio", NULL);
$ echo test | ./cat -uv -   # pledge("stdio", NULL);
$ echo test | ./cat         # pledge("stdio", NULL);
$ echo test | ./cat - - -   # pledge("stdio", NULL);
$ echo test | ./cat -       # pledge("stdio", NULL);
$ echo test | ./cat - cat.c # pledge("stdio rpath", NULL);
$ echo test | ./cat cat.c - # pledge("stdio rpath", NULL);



Index: bin/cat/cat.c
===================================================================
RCS file: /cvs/src/bin/cat/cat.c,v
retrieving revision 1.27
diff -u -p -u -p -r1.27 cat.c
--- bin/cat/cat.c       28 Jun 2019 13:34:58 -0000      1.27
+++ bin/cat/cat.c       30 Jul 2020 23:21:14 -0000
@@ -94,7 +94,26 @@ main(int argc, char *argv[])
                            "usage: %s [-benstuv] [file ...]\n", __progname);
                        return 1;
                }
+       argc -= optind;
        argv += optind;
+
+       if (argc) {
+               if (!strcmp(*argv, "-")) {
+                       do {
+                               if (argc == 1) {
+                                       if (pledge("stdio", NULL) == -1)
+                                               err(1, "pledge");
+                                       argc--, argv++;
+                                       break;
+                               } else
+                                       argc--, argv++;
+                       } while (argc && !strcmp(*argv, "-"));
+                       argc++, argv--;
+               }
+       } else {
+               if (pledge("stdio", NULL) == -1)
+                       err(1, "pledge");
+       }

        if (bflag || eflag || nflag || sflag || tflag || vflag)
                cook_args(argv);

Reply via email to