[LTP] [PATCH V2 2/5] Rename CVE 2012-0957, 2016-4997, 2017-5669, 2017-6951 tests

Stanislav Kholmanskikh stanislav.kholmanskikh@oracle.com
Fri Oct 12 15:10:54 CEST 2018


Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
Changes since V1:
 - moved source files to corresponding directories

 runtest/cve                                        |    8 +-
 runtest/syscalls                                   |    8 +-
 testcases/cve/.gitignore                           |    4 -
 testcases/cve/cve-2012-0957.c                      |   94 --------------
 testcases/cve/cve-2016-4997.c                      |  129 --------------------
 testcases/cve/cve-2017-5669.c                      |  113 -----------------
 testcases/cve/cve-2017-6951.c                      |   46 -------
 testcases/kernel/syscalls/ipc/shmat/.gitignore     |    1 +
 testcases/kernel/syscalls/ipc/shmat/shmat03.c      |  113 +++++++++++++++++
 testcases/kernel/syscalls/request_key/.gitignore   |    1 +
 .../kernel/syscalls/request_key/request_key05.c    |   46 +++++++
 testcases/kernel/syscalls/setsockopt/.gitignore    |    1 +
 .../kernel/syscalls/setsockopt/setsockopt03.c      |  129 ++++++++++++++++++++
 testcases/kernel/syscalls/uname/.gitignore         |    1 +
 testcases/kernel/syscalls/uname/Makefile           |    2 +
 testcases/kernel/syscalls/uname/uname04.c          |   94 ++++++++++++++
 16 files changed, 396 insertions(+), 394 deletions(-)
 delete mode 100644 testcases/cve/cve-2012-0957.c
 delete mode 100644 testcases/cve/cve-2016-4997.c
 delete mode 100644 testcases/cve/cve-2017-5669.c
 delete mode 100644 testcases/cve/cve-2017-6951.c
 create mode 100644 testcases/kernel/syscalls/ipc/shmat/shmat03.c
 create mode 100644 testcases/kernel/syscalls/request_key/request_key05.c
 create mode 100644 testcases/kernel/syscalls/setsockopt/setsockopt03.c
 create mode 100644 testcases/kernel/syscalls/uname/uname04.c

diff --git a/runtest/cve b/runtest/cve
index b38fb35..4fc67ce 100644
--- a/runtest/cve
+++ b/runtest/cve
@@ -2,13 +2,13 @@
 cve-2011-0999 thp01 -I 120
 cve-2011-2183 ksm05 -I 10
 cve-2011-2496 vma03
-cve-2012-0957 cve-2012-0957
+cve-2012-0957 uname04
 cve-2014-0196 cve-2014-0196
 cve-2015-0235 gethostbyname_r01
 cve-2015-7550 keyctl02
 cve-2016-4470 keyctl01.sh
 cve-2015-3290 cve-2015-3290
-cve-2016-4997 cve-2016-4997
+cve-2016-4997 setsockopt03
 cve-2016-5195 dirtyc0w
 cve-2016-7042 cve-2016-7042
 cve-2016-7117 cve-2016-7117
@@ -16,8 +16,8 @@ cve-2016-9604 keyctl08
 cve-2016-10044 cve-2016-10044
 cve-2017-2618 cve-2017-2618
 cve-2017-2671 cve-2017-2671
-cve-2017-5669 cve-2017-5669
-cve-2017-6951 cve-2017-6951
+cve-2017-5669 shmat03
+cve-2017-6951 request_key05
 cve-2017-7308 setsockopt02
 cve-2017-7472 keyctl04
 cve-2017-12192 keyctl07
diff --git a/runtest/syscalls b/runtest/syscalls
index 53a4a42..7ad4262 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -960,8 +960,8 @@ renameat202 renameat202 -i 10
 request_key01 request_key01
 request_key02 request_key02
 request_key03 request_key03
-cve-2017-6951 cve-2017-6951
 request_key04 request_key04
+request_key05 request_key05
 
 rmdir01 rmdir01
 rmdir02 rmdir02
@@ -1187,7 +1187,7 @@ setsid01 setsid01
 
 setsockopt01 setsockopt01
 setsockopt02 setsockopt02
-cve-2016-4997 cve-2016-4997
+setsockopt03 setsockopt03
 
 settimeofday01 settimeofday01
 settimeofday02 settimeofday02
@@ -1205,7 +1205,7 @@ setxattr03 setxattr03
 
 shmat01 shmat01
 shmat02 shmat02
-cve-2017-5669 cve-2017-5669
+shmat03 shmat03
 
 shmctl01 shmctl01
 shmctl02 shmctl02
@@ -1400,7 +1400,7 @@ umask01 umask01
 uname01 uname01
 uname02 uname02
 uname03 uname03
-cve-2012-0957 cve-2012-0957
+uname04 uname04
 
 unlink01 symlink01 -T unlink01
 unlink05 unlink05
diff --git a/testcases/cve/.gitignore b/testcases/cve/.gitignore
index b05c0de..01a3e4c 100644
--- a/testcases/cve/.gitignore
+++ b/testcases/cve/.gitignore
@@ -1,14 +1,10 @@
-cve-2012-0957
 cve-2014-0196
 cve-2015-3290
-cve-2016-4997
 cve-2016-7042
 cve-2016-7117
 cve-2016-10044
 cve-2017-2618
 cve-2017-2671
-cve-2017-6951
-cve-2017-5669
 meltdown
 stack_clash
 cve-2017-17052
diff --git a/testcases/cve/cve-2012-0957.c b/testcases/cve/cve-2012-0957.c
deleted file mode 100644
index e4d9e8f..0000000
--- a/testcases/cve/cve-2012-0957.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2017 Richard Palethorpe <rpalethorpe@suse.com>
- * Copyright (c) 2012, Kees Cook <keescook@chromium.org>
- *
- * 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/>.
- */
-/*
- * Check that memory after the string terminator in all the utsname fields has
- * been zeroed. cve-2012-0957 leaked kernel memory through the release field
- * when the UNAME26 personality was set.
- *
- * Thanks to Kees Cook for the original proof of concept:
- * http://www.securityfocus.com/bid/55855/info
- */
-
-#include <string.h>
-#include <sys/utsname.h>
-#include "tst_test.h"
-#include "lapi/personality.h"
-
-static struct utsname saved_buf;
-
-static int check_field(char *bytes, char *saved_bytes, size_t length,
-		       char *field)
-{
-	size_t i = strlen(bytes) + 1;
-
-	for (; i < length; i++) {
-		if (bytes[i] && (bytes[i] != saved_bytes[i])) {
-			tst_res(TFAIL, "Bytes leaked in %s!", field);
-			return 1;
-		}
-	}
-	return 0;
-}
-
-
-static void try_leak_bytes(unsigned int test_nr)
-{
-	struct utsname buf;
-
-	memset(&buf, 0, sizeof(buf));
-
-	if (uname(&buf))
-		tst_brk(TBROK | TERRNO, "Call to uname failed");
-
-	if (!test_nr)
-		memcpy(&saved_buf, &buf, sizeof(saved_buf));
-
-#define CHECK_FIELD(field_name) \
-	(check_field(buf.field_name, saved_buf.field_name, \
-		     ARRAY_SIZE(buf.field_name), #field_name))
-
-	if (!(CHECK_FIELD(release) |
-	    CHECK_FIELD(sysname) |
-	    CHECK_FIELD(nodename) |
-	    CHECK_FIELD(version) |
-	    CHECK_FIELD(machine) |
-#ifdef HAVE_STRUCT_UTSNAME_DOMAINNAME
-	    CHECK_FIELD(domainname) |
-#endif
-		    0)) {
-		tst_res(TPASS, "No bytes leaked");
-	}
-#undef CHECK_FIELD
-}
-
-static void run(unsigned int test_nr)
-{
-	if (!test_nr) {
-		tst_res(TINFO, "Calling uname with default personality");
-	} else {
-		SAFE_PERSONALITY(PER_LINUX | UNAME26);
-		tst_res(TINFO, "Calling uname with UNAME26 personality");
-	}
-
-	try_leak_bytes(test_nr);
-}
-
-static struct tst_test test = {
-	.test = run,
-	.tcnt = 2,
-};
diff --git a/testcases/cve/cve-2016-4997.c b/testcases/cve/cve-2016-4997.c
deleted file mode 100644
index 2d99865..0000000
--- a/testcases/cve/cve-2016-4997.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2017 Richard Palethorpe <rpalethorpe@suse.com>
- * Based on repro-compatReleaseEntry.c by NCC group
- *
- * 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/>.
- */
-/*
- * Test for CVE-2016-4997
- *
- * For a full explanation of how the vulnerability works see:
- * https://github.com/nccgroup/TriforceLinuxSyscallFuzzer/tree/master/crash_reports/report_compatIpt
- *
- * The original vulnerability was present in the 32-bit compatibility system
- * call, so the test should be compiled with -m32 and run on a 64-bit kernel.
- * For simplicities sake the test requests root privliges instead of creating
- * a user namespace.
- */
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <net/if.h>
-#include <limits.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
-
-#include "tst_test.h"
-#include "tst_safe_net.h"
-#include "tst_kernel.h"
-
-#define TOO_SMALL_OFFSET 74
-#define OFFSET_OVERWRITE 0xFFFF
-#define NEXT_OFFSET (sizeof(struct ipt_entry)		\
-		     + sizeof(struct xt_entry_match)	\
-		     + sizeof(struct xt_entry_target))
-#define PADDING (OFFSET_OVERWRITE - NEXT_OFFSET)
-
-#ifndef HAVE_STRUCT_XT_ENTRY_MATCH
-struct xt_entry_match {
-	union {
-		struct {
-			uint16_t match_size;
-			char name[29];
-			uint8_t revision;
-		} user;
-		struct {
-			uint16_t match_size;
-			void *match;
-		} kernel;
-		uint16_t match_size;
-	} u;
-	unsigned char data[0];
-};
-#endif
-
-#ifndef HAVE_STRUCT_XT_ENTRY_TARGET
-struct xt_entry_target {
-	union {
-		struct {
-			uint16_t target_size;
-			char name[29];
-			uint8_t revision;
-		} user;
-		struct {
-			uint16_t target_size;
-			void *target;
-		} kernel;
-		uint16_t target_size;
-	} u;
-	unsigned char data[0];
-};
-#endif
-
-struct payload {
-	struct ipt_replace repl;
-	struct ipt_entry ent;
-	struct xt_entry_match match;
-	struct xt_entry_target targ;
-	char padding[PADDING];
-	struct xt_entry_target targ2;
-};
-
-static void setup(void)
-{
-	if (tst_kernel_bits() == 32 || sizeof(long) > 4)
-		tst_res(TCONF,
-			"The vulnerability was only present in 32-bit compat mode");
-}
-
-static void run(void)
-{
-	int ret, sock_fd;
-	struct payload p = { 0 };
-
-	sock_fd = SAFE_SOCKET(AF_INET, SOCK_DGRAM, 0);
-
-	strncpy(p.match.u.user.name, "icmp", sizeof(p.match.u.user.name));
-	p.match.u.match_size = OFFSET_OVERWRITE;
-
-	p.ent.next_offset = NEXT_OFFSET;
-	p.ent.target_offset = TOO_SMALL_OFFSET;
-
-	p.repl.num_entries = 2;
-	p.repl.num_counters = 1;
-	p.repl.size = sizeof(struct payload);
-	p.repl.valid_hooks = 0;
-
-	ret = setsockopt(sock_fd, SOL_IP, IPT_SO_SET_REPLACE,
-			 &p, sizeof(struct payload));
-	tst_res(TPASS | TERRNO, "We didn't cause a crash, setsockopt returned %d", ret);
-}
-
-static struct tst_test test = {
-	.min_kver = "2.6.32",
-	.setup = setup,
-	.test_all = run,
-	.needs_root = 1,
-};
diff --git a/testcases/cve/cve-2017-5669.c b/testcases/cve/cve-2017-5669.c
deleted file mode 100644
index 0834626..0000000
--- a/testcases/cve/cve-2017-5669.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2017 Richard Palethorpe <rpalethorpe@suse.com>
- * Copyright (c) 2017 Fujitsu Ltd. (Xiao Yang <yangx.jy@cn.fujitsu.com>)
- *
- * 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/>.
- */
-/*
- * Test for CVE-2017-5669 which allows us to map the nil page using shmat.
- *
- * When the bug is present shmat(..., (void *)1, SHM_RND) will round address
- * 0x1 down to zero and give us the (nil/null) page. With the current bug fix
- * in place, shmat it will return EINVAL instead. We also check to see if the
- * returned address is outside the nil page in case an alternative fix has
- * been applied.
- *
- * In any case we manage to map some memory we also try to write to it. This
- * is just to see if we get an access error or some other unexpected behaviour.
- *
- * See commit 95e91b831f (ipc/shm: Fix shmat mmap nil-page protection)
- *
- * The commit above disallowed SHM_RND maps to zero (and rounded) entirely and
- * that broke userland for cases like Xorg. New behavior disallows REMAPs to
- * lower addresses (0<=PAGESIZE).
- *
- * See commit a73ab244f0da (Revert "ipc/shm: Fix shmat mmap nil-page protect...)
- * See commit 8f89c007b6de (ipc/shm: fix shmat() nil address after round-dow...)
- * See https://github.com/linux-test-project/ltp/issues/319
- *
- * This test needs root permissions or else security_mmap_addr(), from
- * get_unmapped_area(), will cause permission errors when trying to mmap lower
- * addresses.
- */
-
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include "tst_test.h"
-#include "tst_safe_sysv_ipc.h"
-
-static int shm_id;
-static void *shm_addr;
-
-static void setup(void)
-{
-	shm_id = SAFE_SHMGET(IPC_PRIVATE, getpagesize(), 0777);
-}
-
-static void cleanup(void)
-{
-	if (shm_addr)
-		SAFE_SHMDT(shm_addr);
-
-	if (shm_id)
-		SAFE_SHMCTL(shm_id, IPC_RMID, 0);
-}
-
-static void run(void)
-{
-	tst_res(TINFO, "Attempting to attach shared memory to null page");
-	/*
-	 * shmat() for 0 (or < PAGESIZE with RND flag) has to fail with REMAPs
-	 * https://github.com/linux-test-project/ltp/issues/319
-	 */
-	shm_addr = shmat(shm_id, ((void *)1), SHM_RND | SHM_REMAP);
-	if (shm_addr == (void *)-1) {
-		shm_addr = NULL;
-		if (errno == EINVAL) {
-			tst_res(TPASS, "shmat returned EINVAL");
-			return;
-		}
-		tst_brk(TBROK | TERRNO,
-			"The bug was not triggered, but the shmat error is unexpected");
-	}
-
-	tst_res(TINFO, "Mapped shared memory to %p", shm_addr);
-
-	if (!((size_t)shm_addr & (~0U << 16)))
-		tst_res(TFAIL,
-			"We have mapped a VM address within the first 64Kb");
-	else
-		tst_res(TPASS,
-			"The kernel assigned a different VM address");
-
-	tst_res(TINFO,
-		"Touching shared memory to see if anything strange happens");
-	((char *)shm_addr)[0] = 'P';
-
-	SAFE_SHMDT(shm_addr);
-	shm_addr = NULL;
-}
-
-static struct tst_test test = {
-	.needs_root = 1,
-	.setup = setup,
-	.cleanup = cleanup,
-	.test_all = run,
-};
diff --git a/testcases/cve/cve-2017-6951.c b/testcases/cve/cve-2017-6951.c
deleted file mode 100644
index 028e25f..0000000
--- a/testcases/cve/cve-2017-6951.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2017 Richard Palethorpe <rpalethorpe@suse.com>
- *
- * 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/>.
- */
-/*
- * Test for CVE-2016-6951, original reproducer can be found here:
- * http://www.spinics.net/lists/keyrings/msg01845.html
- *
- * request_key() is not in glibc, so we just use the syscall directly instead
- * of linking to keyutils.
- */
-
-#include <unistd.h>
-#include <sys/syscall.h>
-
-#include "tst_test.h"
-#include "lapi/syscalls.h"
-
-#define ATTEMPTS 0x100
-
-static void run(void)
-{
-	int i;
-
-	tst_res(TINFO, "Requesting dead key");
-	for (i = 0; i < ATTEMPTS; i++)
-		tst_syscall(__NR_request_key, "dead", "abc", "abc", 0, 0, 0);
-
-	tst_res(TPASS, "No crash after %d attempts", ATTEMPTS);
-}
-
-static struct tst_test test = {
-	.test_all = run,
-};
diff --git a/testcases/kernel/syscalls/ipc/shmat/.gitignore b/testcases/kernel/syscalls/ipc/shmat/.gitignore
index 488abd3..2b972f8 100644
--- a/testcases/kernel/syscalls/ipc/shmat/.gitignore
+++ b/testcases/kernel/syscalls/ipc/shmat/.gitignore
@@ -1,2 +1,3 @@
 /shmat01
 /shmat02
+/shmat03
diff --git a/testcases/kernel/syscalls/ipc/shmat/shmat03.c b/testcases/kernel/syscalls/ipc/shmat/shmat03.c
new file mode 100644
index 0000000..0834626
--- /dev/null
+++ b/testcases/kernel/syscalls/ipc/shmat/shmat03.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2017 Richard Palethorpe <rpalethorpe@suse.com>
+ * Copyright (c) 2017 Fujitsu Ltd. (Xiao Yang <yangx.jy@cn.fujitsu.com>)
+ *
+ * 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/>.
+ */
+/*
+ * Test for CVE-2017-5669 which allows us to map the nil page using shmat.
+ *
+ * When the bug is present shmat(..., (void *)1, SHM_RND) will round address
+ * 0x1 down to zero and give us the (nil/null) page. With the current bug fix
+ * in place, shmat it will return EINVAL instead. We also check to see if the
+ * returned address is outside the nil page in case an alternative fix has
+ * been applied.
+ *
+ * In any case we manage to map some memory we also try to write to it. This
+ * is just to see if we get an access error or some other unexpected behaviour.
+ *
+ * See commit 95e91b831f (ipc/shm: Fix shmat mmap nil-page protection)
+ *
+ * The commit above disallowed SHM_RND maps to zero (and rounded) entirely and
+ * that broke userland for cases like Xorg. New behavior disallows REMAPs to
+ * lower addresses (0<=PAGESIZE).
+ *
+ * See commit a73ab244f0da (Revert "ipc/shm: Fix shmat mmap nil-page protect...)
+ * See commit 8f89c007b6de (ipc/shm: fix shmat() nil address after round-dow...)
+ * See https://github.com/linux-test-project/ltp/issues/319
+ *
+ * This test needs root permissions or else security_mmap_addr(), from
+ * get_unmapped_area(), will cause permission errors when trying to mmap lower
+ * addresses.
+ */
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include "tst_test.h"
+#include "tst_safe_sysv_ipc.h"
+
+static int shm_id;
+static void *shm_addr;
+
+static void setup(void)
+{
+	shm_id = SAFE_SHMGET(IPC_PRIVATE, getpagesize(), 0777);
+}
+
+static void cleanup(void)
+{
+	if (shm_addr)
+		SAFE_SHMDT(shm_addr);
+
+	if (shm_id)
+		SAFE_SHMCTL(shm_id, IPC_RMID, 0);
+}
+
+static void run(void)
+{
+	tst_res(TINFO, "Attempting to attach shared memory to null page");
+	/*
+	 * shmat() for 0 (or < PAGESIZE with RND flag) has to fail with REMAPs
+	 * https://github.com/linux-test-project/ltp/issues/319
+	 */
+	shm_addr = shmat(shm_id, ((void *)1), SHM_RND | SHM_REMAP);
+	if (shm_addr == (void *)-1) {
+		shm_addr = NULL;
+		if (errno == EINVAL) {
+			tst_res(TPASS, "shmat returned EINVAL");
+			return;
+		}
+		tst_brk(TBROK | TERRNO,
+			"The bug was not triggered, but the shmat error is unexpected");
+	}
+
+	tst_res(TINFO, "Mapped shared memory to %p", shm_addr);
+
+	if (!((size_t)shm_addr & (~0U << 16)))
+		tst_res(TFAIL,
+			"We have mapped a VM address within the first 64Kb");
+	else
+		tst_res(TPASS,
+			"The kernel assigned a different VM address");
+
+	tst_res(TINFO,
+		"Touching shared memory to see if anything strange happens");
+	((char *)shm_addr)[0] = 'P';
+
+	SAFE_SHMDT(shm_addr);
+	shm_addr = NULL;
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = run,
+};
diff --git a/testcases/kernel/syscalls/request_key/.gitignore b/testcases/kernel/syscalls/request_key/.gitignore
index 4c813a8..e8dc1c5 100644
--- a/testcases/kernel/syscalls/request_key/.gitignore
+++ b/testcases/kernel/syscalls/request_key/.gitignore
@@ -2,3 +2,4 @@
 /request_key02
 /request_key03
 /request_key04
+/request_key05
diff --git a/testcases/kernel/syscalls/request_key/request_key05.c b/testcases/kernel/syscalls/request_key/request_key05.c
new file mode 100644
index 0000000..028e25f
--- /dev/null
+++ b/testcases/kernel/syscalls/request_key/request_key05.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 Richard Palethorpe <rpalethorpe@suse.com>
+ *
+ * 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/>.
+ */
+/*
+ * Test for CVE-2016-6951, original reproducer can be found here:
+ * http://www.spinics.net/lists/keyrings/msg01845.html
+ *
+ * request_key() is not in glibc, so we just use the syscall directly instead
+ * of linking to keyutils.
+ */
+
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+
+#define ATTEMPTS 0x100
+
+static void run(void)
+{
+	int i;
+
+	tst_res(TINFO, "Requesting dead key");
+	for (i = 0; i < ATTEMPTS; i++)
+		tst_syscall(__NR_request_key, "dead", "abc", "abc", 0, 0, 0);
+
+	tst_res(TPASS, "No crash after %d attempts", ATTEMPTS);
+}
+
+static struct tst_test test = {
+	.test_all = run,
+};
diff --git a/testcases/kernel/syscalls/setsockopt/.gitignore b/testcases/kernel/syscalls/setsockopt/.gitignore
index 2b24f9f..d8fb0f3 100644
--- a/testcases/kernel/syscalls/setsockopt/.gitignore
+++ b/testcases/kernel/syscalls/setsockopt/.gitignore
@@ -1,2 +1,3 @@
 /setsockopt01
 /setsockopt02
+/setsockopt03
diff --git a/testcases/kernel/syscalls/setsockopt/setsockopt03.c b/testcases/kernel/syscalls/setsockopt/setsockopt03.c
new file mode 100644
index 0000000..2d99865
--- /dev/null
+++ b/testcases/kernel/syscalls/setsockopt/setsockopt03.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2017 Richard Palethorpe <rpalethorpe@suse.com>
+ * Based on repro-compatReleaseEntry.c by NCC group
+ *
+ * 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/>.
+ */
+/*
+ * Test for CVE-2016-4997
+ *
+ * For a full explanation of how the vulnerability works see:
+ * https://github.com/nccgroup/TriforceLinuxSyscallFuzzer/tree/master/crash_reports/report_compatIpt
+ *
+ * The original vulnerability was present in the 32-bit compatibility system
+ * call, so the test should be compiled with -m32 and run on a 64-bit kernel.
+ * For simplicities sake the test requests root privliges instead of creating
+ * a user namespace.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <limits.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+
+#include "tst_test.h"
+#include "tst_safe_net.h"
+#include "tst_kernel.h"
+
+#define TOO_SMALL_OFFSET 74
+#define OFFSET_OVERWRITE 0xFFFF
+#define NEXT_OFFSET (sizeof(struct ipt_entry)		\
+		     + sizeof(struct xt_entry_match)	\
+		     + sizeof(struct xt_entry_target))
+#define PADDING (OFFSET_OVERWRITE - NEXT_OFFSET)
+
+#ifndef HAVE_STRUCT_XT_ENTRY_MATCH
+struct xt_entry_match {
+	union {
+		struct {
+			uint16_t match_size;
+			char name[29];
+			uint8_t revision;
+		} user;
+		struct {
+			uint16_t match_size;
+			void *match;
+		} kernel;
+		uint16_t match_size;
+	} u;
+	unsigned char data[0];
+};
+#endif
+
+#ifndef HAVE_STRUCT_XT_ENTRY_TARGET
+struct xt_entry_target {
+	union {
+		struct {
+			uint16_t target_size;
+			char name[29];
+			uint8_t revision;
+		} user;
+		struct {
+			uint16_t target_size;
+			void *target;
+		} kernel;
+		uint16_t target_size;
+	} u;
+	unsigned char data[0];
+};
+#endif
+
+struct payload {
+	struct ipt_replace repl;
+	struct ipt_entry ent;
+	struct xt_entry_match match;
+	struct xt_entry_target targ;
+	char padding[PADDING];
+	struct xt_entry_target targ2;
+};
+
+static void setup(void)
+{
+	if (tst_kernel_bits() == 32 || sizeof(long) > 4)
+		tst_res(TCONF,
+			"The vulnerability was only present in 32-bit compat mode");
+}
+
+static void run(void)
+{
+	int ret, sock_fd;
+	struct payload p = { 0 };
+
+	sock_fd = SAFE_SOCKET(AF_INET, SOCK_DGRAM, 0);
+
+	strncpy(p.match.u.user.name, "icmp", sizeof(p.match.u.user.name));
+	p.match.u.match_size = OFFSET_OVERWRITE;
+
+	p.ent.next_offset = NEXT_OFFSET;
+	p.ent.target_offset = TOO_SMALL_OFFSET;
+
+	p.repl.num_entries = 2;
+	p.repl.num_counters = 1;
+	p.repl.size = sizeof(struct payload);
+	p.repl.valid_hooks = 0;
+
+	ret = setsockopt(sock_fd, SOL_IP, IPT_SO_SET_REPLACE,
+			 &p, sizeof(struct payload));
+	tst_res(TPASS | TERRNO, "We didn't cause a crash, setsockopt returned %d", ret);
+}
+
+static struct tst_test test = {
+	.min_kver = "2.6.32",
+	.setup = setup,
+	.test_all = run,
+	.needs_root = 1,
+};
diff --git a/testcases/kernel/syscalls/uname/.gitignore b/testcases/kernel/syscalls/uname/.gitignore
index 1bcf6a4..4f153e7 100644
--- a/testcases/kernel/syscalls/uname/.gitignore
+++ b/testcases/kernel/syscalls/uname/.gitignore
@@ -1,3 +1,4 @@
 /uname01
 /uname02
 /uname03
+/uname04
diff --git a/testcases/kernel/syscalls/uname/Makefile b/testcases/kernel/syscalls/uname/Makefile
index bd617d8..eceaa64 100644
--- a/testcases/kernel/syscalls/uname/Makefile
+++ b/testcases/kernel/syscalls/uname/Makefile
@@ -20,4 +20,6 @@ top_srcdir		?= ../../../..
 
 include $(top_srcdir)/include/mk/testcases.mk
 
+uname04:	CFLAGS += -D_GNU_SOURCE
+
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/uname/uname04.c b/testcases/kernel/syscalls/uname/uname04.c
new file mode 100644
index 0000000..e4d9e8f
--- /dev/null
+++ b/testcases/kernel/syscalls/uname/uname04.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017 Richard Palethorpe <rpalethorpe@suse.com>
+ * Copyright (c) 2012, Kees Cook <keescook@chromium.org>
+ *
+ * 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/>.
+ */
+/*
+ * Check that memory after the string terminator in all the utsname fields has
+ * been zeroed. cve-2012-0957 leaked kernel memory through the release field
+ * when the UNAME26 personality was set.
+ *
+ * Thanks to Kees Cook for the original proof of concept:
+ * http://www.securityfocus.com/bid/55855/info
+ */
+
+#include <string.h>
+#include <sys/utsname.h>
+#include "tst_test.h"
+#include "lapi/personality.h"
+
+static struct utsname saved_buf;
+
+static int check_field(char *bytes, char *saved_bytes, size_t length,
+		       char *field)
+{
+	size_t i = strlen(bytes) + 1;
+
+	for (; i < length; i++) {
+		if (bytes[i] && (bytes[i] != saved_bytes[i])) {
+			tst_res(TFAIL, "Bytes leaked in %s!", field);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
+static void try_leak_bytes(unsigned int test_nr)
+{
+	struct utsname buf;
+
+	memset(&buf, 0, sizeof(buf));
+
+	if (uname(&buf))
+		tst_brk(TBROK | TERRNO, "Call to uname failed");
+
+	if (!test_nr)
+		memcpy(&saved_buf, &buf, sizeof(saved_buf));
+
+#define CHECK_FIELD(field_name) \
+	(check_field(buf.field_name, saved_buf.field_name, \
+		     ARRAY_SIZE(buf.field_name), #field_name))
+
+	if (!(CHECK_FIELD(release) |
+	    CHECK_FIELD(sysname) |
+	    CHECK_FIELD(nodename) |
+	    CHECK_FIELD(version) |
+	    CHECK_FIELD(machine) |
+#ifdef HAVE_STRUCT_UTSNAME_DOMAINNAME
+	    CHECK_FIELD(domainname) |
+#endif
+		    0)) {
+		tst_res(TPASS, "No bytes leaked");
+	}
+#undef CHECK_FIELD
+}
+
+static void run(unsigned int test_nr)
+{
+	if (!test_nr) {
+		tst_res(TINFO, "Calling uname with default personality");
+	} else {
+		SAFE_PERSONALITY(PER_LINUX | UNAME26);
+		tst_res(TINFO, "Calling uname with UNAME26 personality");
+	}
+
+	try_leak_bytes(test_nr);
+}
+
+static struct tst_test test = {
+	.test = run,
+	.tcnt = 2,
+};
-- 
1.7.1



More information about the ltp mailing list