Skip to contentSkip to conversation

cve-2015-3290: Handle 16-bit segments being disabled

PATCH New Richard Palethorpe 2 participants 5 messages Mar 13, 2018 – Mar 15, 2018 Library code

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 cve-2015-3290: Handle 16-bit segments being disabled

If modify_ldt fails with EINVAL then we can only assume the kernel has 16-bit data segments disabled.

---

It seems that on SUSE Enterprise 15 we have 16-bit segments disabled by default so the test can not run.

 testcases/cve/cve-2015-3290.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
testcases/cve/cve-2015-3290.c +10 -2
index 87c9c956c..dbc2101a7 100644
@@ -215,8 +215,14 @@ static void set_ldt(void)
 		.useable	 = 0
 	};
 
-	if (tst_syscall(__NR_modify_ldt, 1, &data_desc, sizeof(data_desc)) != 0)
-		tst_brk(TBROK | TERRNO, "modify_ldt");
+	TEST(tst_syscall(__NR_modify_ldt, 1, &data_desc, sizeof(data_desc)));
+	TEST_ERRNO = -(int)TEST_RETURN;
+	if (TEST_RETURN == -EINVAL) {
+		tst_brk(TCONF | TTERRNO,
+			"modify_ldt: 16-bit data segments are probably disabled");
+	} else if (TEST_RETURN != 0) {
+		tst_brk(TBROK | TTERRNO, "modify_ldt");
+	}
 }
 
 static void try_corrupt_stack(unsigned short orig_ss)
@@ -474,6 +480,8 @@ static void run(void)
 	SAFE_WAITPID(pid, &status, 0);
 	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)
 		tst_res(TFAIL, "corrupted NMI stack");
+	else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
+		tst_res(WEXITSTATUS(status), "Propogate child status");
 }
 
 static struct tst_test test = {
Signature · 1 line
2.16.2
#1 lore raw

PATCH 1/1 cve-2015-3290: Handle 16-bit segments being disabled

Hi!

testcases/cve/cve-2015-3290.c static void set_ldt(void) · line 219

Quoted 2 lines
testcases/cve/cve-2015-3290.c +2 -0
+	TEST(tst_syscall(__NR_modify_ldt, 1, &data_desc, sizeof(data_desc)));
+	TEST_ERRNO = -(int)TEST_RETURN;

We do have TRERRNO if we changed the test library to ignore the sign bit we may was well get rid of this ugly hack and use TRERRNO in the tst_brk() below.

Quoted 7 lines
testcases/cve/cve-2015-3290.c +6 -0
+	if (TEST_RETURN == -EINVAL) {
+		tst_brk(TCONF | TTERRNO,
+			"modify_ldt: 16-bit data segments are probably disabled");
+	} else if (TEST_RETURN != 0) {
+		tst_brk(TBROK | TTERRNO, "modify_ldt");
+	}
 }
Signature · 2 lines
Cyril Hrubis
[email protected]
#2 lore raw

PATCH v2 1/2 lib: Add TRERRNO to tst_res and remove sign when present

Some system calls and libraries pass the error code back to the user in the return value. Sometimes it is inverted, sometimes not. This allows TRERRNO to be passed to tst_res which then causes it to print the error code in TEST_RETURN.

---

I think we have to branch on TEST_RETURN < 0 because of two's complement integer representation, but I could be missing a trick here.

 lib/tst_res.c  | 4 ++--
 lib/tst_test.c | 5 +++++
 2 files changed, 7 insertions(+), 2 deletions(-)
lib/tst_res.c +2 -2
index b56f37db0..b4bc09179 100644
@@ -346,10 +346,10 @@ static void tst_print(const char *tcid, int tnum, int ttype, const char *tmesg)
 	}
 
 	if (ttype & TRERRNO) {
+		err = TEST_RETURN < 0 ? -(int)TEST_RETURN : (int)TEST_RETURN;
 		size += snprintf(message + size, sizeof(message) - size,
 				 ": TEST_RETURN=%s(%i): %s",
-				 tst_strerrno(TEST_RETURN), (int)TEST_RETURN,
-				 strerror(TEST_RETURN));
+				 tst_strerrno(err), err, strerror(err));
 	}
 
 	if (size + 1 >= sizeof(message)) {
lib/tst_test.c +5 -0
index 2cf35ed66..00b8ccb69 100644
@@ -215,6 +215,11 @@ static void print_result(const char *file, const int lineno, int ttype,
 	if (ttype & TTERRNO)
 		str_errno = tst_strerrno(TEST_ERRNO);
 
+	if (ttype & TRERRNO) {
+		ret = TEST_RETURN < 0 ? -(int)TEST_RETURN : (int)TEST_RETURN;
+		str_errno = tst_strerrno(ret);
+	}
+
 	ret = snprintf(str, size, "%s:%i: ", file, lineno);
 	str += ret;
 	size -= ret;
Signature · 1 line
2.16.2
#3 lore raw

PATCH v2 2/2 cve-2015-3290: Handle 16-bit segments being disabled

In reply to Cyril Hrubis

If modify_ldt fails with EINVAL then we can only assume the kernel has 16-bit data segments disabled.

---
 testcases/cve/cve-2015-3290.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
testcases/cve/cve-2015-3290.c +9 -2
index 87c9c956c..631702e2e 100644
@@ -215,8 +215,13 @@ static void set_ldt(void)
 		.useable	 = 0
 	};
 
-	if (tst_syscall(__NR_modify_ldt, 1, &data_desc, sizeof(data_desc)) != 0)
-		tst_brk(TBROK | TERRNO, "modify_ldt");
+	TEST(tst_syscall(__NR_modify_ldt, 1, &data_desc, sizeof(data_desc)));
+	if (TEST_RETURN == -EINVAL) {
+		tst_brk(TCONF | TRERRNO,
+			"modify_ldt: 16-bit data segments are probably disabled");
+	} else if (TEST_RETURN != 0) {
+		tst_brk(TBROK | TRERRNO, "modify_ldt");
+	}
 }
 
 static void try_corrupt_stack(unsigned short orig_ss)
@@ -474,6 +479,8 @@ static void run(void)
 	SAFE_WAITPID(pid, &status, 0);
 	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)
 		tst_res(TFAIL, "corrupted NMI stack");
+	else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
+		tst_res(WEXITSTATUS(status), "Propogate child status");
 }
 
 static struct tst_test test = {
Signature · 1 line
2.16.2