untrusted comment: signature from openbsd 5.6 base private key RWR0EANmo9nqhj+ponYcZH/jQhIRZZhLCU2kCgDmLziEe8Q7DCoLP4a6jrKZN/unc2omNDYVz/hzUxKKUasYzX2EPJZphIXUGwY= OpenBSD 5.6 errata 29, Jul 26, 2015: The patch utility could be made to invoke arbitrary commands via the obsolete SCCS and RCS support when processing a crafted input file. This patch deletes the SCCS and RCS support. Apply by doing: signify -Vep /etc/signify/openbsd-56-base.pub -x 029_patch.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install the patch utility: cd /usr/src/usr.bin/patch make obj make make install Index: usr.bin/patch/common.h =================================================================== RCS file: /data/src/openbsd/src/usr.bin/patch/common.h,v retrieving revision 1.26 diff -u -p -r1.26 common.h --- usr.bin/patch/common.h 11 Mar 2006 19:41:30 -0000 1.26 +++ usr.bin/patch/common.h 27 Jul 2015 00:00:25 -0000 @@ -39,14 +39,6 @@ #define MAXLINELEN 8192 #define BUFFERSIZE 1024 -#define SCCSPREFIX "s." -#define GET "get -e %s" -#define SCCSDIFF "get -p %s | diff - %s >/dev/null" - -#define RCSSUFFIX ",v" -#define CHECKOUT "co -l %s" -#define RCSDIFF "rcsdiff %s > /dev/null" - #define ORIGEXT ".orig" #define REJEXT ".rej" Index: usr.bin/patch/inp.c =================================================================== RCS file: /data/src/openbsd/src/usr.bin/patch/inp.c,v retrieving revision 1.37 diff -u -p -r1.37 inp.c --- usr.bin/patch/inp.c 26 Nov 2013 13:19:07 -0000 1.37 +++ usr.bin/patch/inp.c 27 Jul 2015 00:00:25 -0000 @@ -131,7 +131,7 @@ static bool plan_a(const char *filename) { int ifd, statfailed; - char *p, *s, lbuf[MAXLINELEN]; + char *p, *s; struct stat filestat; off_t i; ptrdiff_t sz; @@ -161,72 +161,8 @@ plan_a(const char *filename) close(creat(filename, 0666)); statfailed = stat(filename, &filestat); } - if (statfailed && check_only) - fatal("%s not found, -C mode, can't probe further\n", filename); - /* For nonexistent or read-only files, look for RCS or SCCS versions. */ - if (statfailed || - /* No one can write to it. */ - (filestat.st_mode & 0222) == 0 || - /* I can't write to it. */ - ((filestat.st_mode & 0022) == 0 && filestat.st_uid != getuid())) { - char *cs = NULL, *filebase, *filedir; - struct stat cstat; - - filebase = basename(filename); - filedir = dirname(filename); - - /* Leave room in lbuf for the diff command. */ - s = lbuf + 20; - -#define try(f, a1, a2, a3) \ - (snprintf(s, sizeof lbuf - 20, f, a1, a2, a3), stat(s, &cstat) == 0) - - if (try("%s/RCS/%s%s", filedir, filebase, RCSSUFFIX) || - try("%s/RCS/%s%s", filedir, filebase, "") || - try("%s/%s%s", filedir, filebase, RCSSUFFIX)) { - snprintf(buf, sizeof buf, CHECKOUT, filename); - snprintf(lbuf, sizeof lbuf, RCSDIFF, filename); - cs = "RCS"; - } else if (try("%s/SCCS/%s%s", filedir, SCCSPREFIX, filebase) || - try("%s/%s%s", filedir, SCCSPREFIX, filebase)) { - snprintf(buf, sizeof buf, GET, s); - snprintf(lbuf, sizeof lbuf, SCCSDIFF, s, filename); - cs = "SCCS"; - } else if (statfailed) - fatal("can't find %s\n", filename); - /* - * else we can't write to it but it's not under a version - * control system, so just proceed. - */ - if (cs) { - if (!statfailed) { - if ((filestat.st_mode & 0222) != 0) - /* The owner can write to it. */ - fatal("file %s seems to be locked " - "by somebody else under %s\n", - filename, cs); - /* - * It might be checked out unlocked. See if - * it's safe to check out the default version - * locked. - */ - if (verbose) - say("Comparing file %s to default " - "%s version...\n", - filename, cs); - if (system(lbuf)) - fatal("can't check out file %s: " - "differs from default %s version\n", - filename, cs); - } - if (verbose) - say("Checking out file %s from %s...\n", - filename, cs); - if (system(buf) || stat(filename, &filestat)) - fatal("can't check out file %s from %s\n", - filename, cs); - } - } + if (statfailed) + fatal("can't find %s\n", filename); filemode = filestat.st_mode; if (!S_ISREG(filemode)) fatal("%s is not a normal file--can't patch\n", filename); Index: usr.bin/patch/patch.1 =================================================================== RCS file: /data/src/openbsd/src/usr.bin/patch/patch.1,v retrieving revision 1.27 diff -u -p -r1.27 patch.1 --- usr.bin/patch/patch.1 15 Apr 2014 06:26:54 -0000 1.27 +++ usr.bin/patch/patch.1 27 Jul 2015 00:00:25 -0000 @@ -479,15 +479,6 @@ file names or, for a non-context diff, t file name, and choose the file name with the fewest path components, the shortest basename, and the shortest total file name length (in that order). .It -If no file exists, -.Nm -checks for the existence of the files in an SCCS or RCS directory -(using the appropriate prefix or suffix) using the criteria specified -above. -If found, -.Nm -will attempt to get or check out the file. -.It If no suitable file was found to patch, the patch file is a context or unified diff, and the old file was zero length, the new file name is created and used. Index: usr.bin/patch/pch.c =================================================================== RCS file: /data/src/openbsd/src/usr.bin/patch/pch.c,v retrieving revision 1.41 diff -u -p -r1.41 pch.c --- usr.bin/patch/pch.c 26 Nov 2013 13:19:07 -0000 1.41 +++ usr.bin/patch/pch.c 27 Jul 2015 00:01:30 -0000 @@ -1448,17 +1448,8 @@ posix_name(const struct file_name *names } if (path == NULL && !assume_exists) { /* - * No files found, look for something we can checkout from - * RCS/SCCS dirs. Same order as above. - */ - for (i = 0; i < MAX_FILE; i++) { - if (names[i].path != NULL && - (path = checked_in(names[i].path)) != NULL) - break; - } - /* - * Still no match? Check to see if the diff could be creating - * a new file. + * No files found, check to see if the diff could be + * creating a new file. */ if (path == NULL && ok_to_create_file && names[NEW_FILE].path != NULL) @@ -1469,7 +1460,7 @@ posix_name(const struct file_name *names } static char * -compare_names(const struct file_name *names, bool assume_exists, int phase) +compare_names(const struct file_name *names, bool assume_exists) { size_t min_components, min_baselen, min_len, tmp; char *best = NULL; @@ -1486,9 +1477,7 @@ compare_names(const struct file_name *na min_components = min_baselen = min_len = SIZE_MAX; for (i = INDEX_FILE; i >= OLD_FILE; i--) { path = names[i].path; - if (path == NULL || - (phase == 1 && !names[i].exists && !assume_exists) || - (phase == 2 && checked_in(path) == NULL)) + if (path == NULL || (!names[i].exists && !assume_exists)) continue; if ((tmp = num_components(path)) > min_components) continue; @@ -1519,17 +1508,12 @@ best_name(const struct file_name *names, { char *best; - best = compare_names(names, assume_exists, 1); - if (best == NULL) { - best = compare_names(names, assume_exists, 2); - /* - * Still no match? Check to see if the diff could be creating - * a new file. - */ - if (best == NULL && ok_to_create_file && - names[NEW_FILE].path != NULL) - best = names[NEW_FILE].path; - } + best = compare_names(names, assume_exists); + + /* No match? Check to see if the diff could be creating a new file. */ + if (best == NULL && ok_to_create_file) + best = names[NEW_FILE].path; + return best ? savestr(best) : NULL; } Index: usr.bin/patch/util.c =================================================================== RCS file: /data/src/openbsd/src/usr.bin/patch/util.c,v retrieving revision 1.36 diff -u -p -r1.36 util.c --- usr.bin/patch/util.c 26 Nov 2013 13:19:07 -0000 1.36 +++ usr.bin/patch/util.c 27 Jul 2015 00:01:59 -0000 @@ -373,32 +373,6 @@ fetchname(const char *at, bool *exists, return name; } -/* - * Takes the name returned by fetchname and looks in RCS/SCCS directories - * for a checked in version. - */ -char * -checked_in(char *file) -{ - char *filebase, *filedir, tmpbuf[MAXPATHLEN]; - struct stat filestat; - - filebase = basename(file); - filedir = dirname(file); - -#define try(f, a1, a2, a3) \ -(snprintf(tmpbuf, sizeof tmpbuf, f, a1, a2, a3), stat(tmpbuf, &filestat) == 0) - - if (try("%s/RCS/%s%s", filedir, filebase, RCSSUFFIX) || - try("%s/RCS/%s%s", filedir, filebase, "") || - try("%s/%s%s", filedir, filebase, RCSSUFFIX) || - try("%s/SCCS/%s%s", filedir, SCCSPREFIX, filebase) || - try("%s/%s%s", filedir, SCCSPREFIX, filebase)) - return file; - - return NULL; -} - void version(void) { Index: usr.bin/patch/util.h =================================================================== RCS file: /data/src/openbsd/src/usr.bin/patch/util.h,v retrieving revision 1.15 diff -u -p -r1.15 util.h --- usr.bin/patch/util.h 20 Jun 2005 07:14:06 -0000 1.15 +++ usr.bin/patch/util.h 27 Jul 2015 00:00:33 -0000 @@ -27,7 +27,6 @@ */ char *fetchname(const char *, bool *, int); -char *checked_in(char *); int backup_file(const char *); int move_file(const char *, const char *); int copy_file(const char *, const char *);