Fix unveil(2) in patch(1) with explicit patchfile.
authorbluhm <bluhm@openbsd.org>
Wed, 25 Oct 2023 20:05:43 +0000 (20:05 +0000)
committerbluhm <bluhm@openbsd.org>
Wed, 25 Oct 2023 20:05:43 +0000 (20:05 +0000)
A backup file should be created in the directory of the original
file, but only the current directory was unveiled.  Then the patched
file was created in /tmp and did not replace the original patchfile
in place.  If a patchfile is passed in argv[0], unveil its directory
instead of current directory.

OK florian@ deraadt@ millert@

usr.bin/patch/patch.c

index 322a024..1e926d1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: patch.c,v 1.74 2023/07/19 13:26:20 tb Exp $   */
+/*     $OpenBSD: patch.c,v 1.75 2023/10/25 20:05:43 bluhm Exp $        */
 
 /*
  * patch - a program to apply diffs to original files
@@ -32,6 +32,7 @@
 
 #include <ctype.h>
 #include <getopt.h>
+#include <libgen.h>
 #include <limits.h>
 #include <paths.h>
 #include <stdio.h>
@@ -213,11 +214,27 @@ main(int argc, char *argv[])
                        perror("unveil");
                        my_exit(2);
                }
-       if (filearg[0] != NULL)
+       if (filearg[0] != NULL) {
+               char *origdir;
+
                if (unveil(filearg[0], "rwc") == -1) {
                        perror("unveil");
                        my_exit(2);
                }
+               if ((origdir = dirname(filearg[0])) == NULL) {
+                       perror("dirname");
+                       my_exit(2);
+               }
+               if (unveil(origdir, "rwc") == -1) {
+                       perror("unveil");
+                       my_exit(2);
+               }
+       } else {
+               if (unveil(".", "rwc") == -1) {
+                       perror("unveil");
+                       my_exit(2);
+               }
+       }
        if (filearg[1] != NULL)
                if (unveil(filearg[1], "r") == -1) {
                        perror("unveil");
@@ -228,10 +245,6 @@ main(int argc, char *argv[])
                        perror("unveil");
                        my_exit(2);
                }
-       if (unveil(".", "rwc") == -1) {
-               perror("unveil");
-               my_exit(2);
-       }
        if (*rejname != '\0')
                if (unveil(rejname, "rwc") == -1) {
                        perror("unveil");