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

Martin Doucha mdoucha@suse.cz
Thu Jun 13 17:29:05 CEST 2024


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 --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");
 	}
 }
 
-- 
2.44.0



More information about the ltp mailing list