diff mbox series

[2/2] cve-2015-3290: Check for mishandled modify_ldt() return value

Message ID 20240613152909.22000-2-mdoucha@suse.cz
State Accepted
Headers show
Series [1/2] cve-2015-3290: Fail on unexpected signal | expand

Commit Message

Martin Doucha June 13, 2024, 3:29 p.m. UTC
The kernel intentionally prevents modify_ldt() return value sign
extension to 64bit long. Some libc versions return the value as is
instead of correctly setting errno. Check for incorrect return value
handling and rectify the problem if needed.

Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
 testcases/cve/cve-2015-3290.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/testcases/cve/cve-2015-3290.c b/testcases/cve/cve-2015-3290.c
index 0aad26d74..171667d4a 100644
--- a/testcases/cve/cve-2015-3290.c
+++ b/testcases/cve/cve-2015-3290.c
@@ -195,13 +195,26 @@  static void set_ldt(void)
 		.useable	 = 0
 	};
 
-	TEST((int)tst_syscall(__NR_modify_ldt, 1, &data_desc,
-		sizeof(data_desc)));
-	if (TST_RET == -EINVAL) {
-		tst_brk(TCONF | TRERRNO,
+	TEST(tst_syscall(__NR_modify_ldt, 1, &data_desc, sizeof(data_desc)));
+
+	/*
+	 * The kernel intentionally casts modify_ldt() return value
+	 * to unsigned int to prevent sign extension to 64 bits. This may
+	 * result in syscall() returning the value as is instead of setting
+	 * errno and returning -1.
+	 */
+	if (TST_RET > 0 && ((int)TST_RET) < 0) {
+		tst_res(TINFO,
+			"WARNING: Libc mishandled modify_ldt() return value");
+		TST_ERR = -(int)TST_RET;
+		TST_RET = -1;
+	}
+
+	if (TST_RET == -1 && TST_ERR == EINVAL) {
+		tst_brk(TCONF | TTERRNO,
 			"modify_ldt: 16-bit data segments are probably disabled");
 	} else if (TST_RET != 0) {
-		tst_brk(TBROK | TRERRNO, "modify_ldt");
+		tst_brk(TBROK | TTERRNO, "modify_ldt");
 	}
 }