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 *);