[LTP] [PATCH v9 1/3] syscalls/modify_ldt: Add lapi/ldt.h

Ricardo B. Marlière rbm@suse.com
Wed May 7 13:32:41 CEST 2025


On Wed May 7, 2025 at 8:23 AM -03, Martin Doucha wrote:
> Hi,
> one more thing for cve-2015-3290 below.
>

Thanks for the reports, I'll send a fix soon!

> On 29. 04. 25 12:44, Ricardo B. Marlière via ltp wrote:
>> From: Ricardo B. Marlière <rbm@suse.com>
>> 
>> Add a wrapper to modify_ldt and a fallback definition to struct user_desc,
>> which are needed in a few tests and should be reused.
>> 
>> Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
>> Reviewed-by: Andrea Cervesato <andrea.cervesato@suse.com>
>> Signed-off-by: Ricardo B. Marlière <rbm@suse.com>
>> ---
>>   include/lapi/ldt.h                      | 59 +++++++++++++++++++++++++++++++++
>>   testcases/cve/cve-2015-3290.c           | 26 ++-------------
>>   testcases/cve/cve-2017-17053.c          |  6 ++--
>>   testcases/kernel/syscalls/fork/fork05.c |  5 ++-
>>   4 files changed, 65 insertions(+), 31 deletions(-)
>> 
>> diff --git a/include/lapi/ldt.h b/include/lapi/ldt.h
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..6b5a2d59cb41bfc24eb5ac26c3d47d49fb8ff78f
>> --- /dev/null
>> +++ b/include/lapi/ldt.h
>> @@ -0,0 +1,59 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * Copyright (c) 2025 SUSE LLC Ricardo B. Marlière <rbm@suse.com>
>> + */
>> +
>> +#ifndef LAPI_LDT_H__
>> +#define LAPI_LDT_H__
>> +
>> +#include "config.h"
>> +#include "lapi/syscalls.h"
>> +
>> +#ifdef HAVE_ASM_LDT_H
>> +#include <asm/ldt.h>
>> +#else
>> +struct user_desc {
>> +	unsigned int entry_number;
>> +	unsigned int base_addr;
>> +	unsigned int limit;
>> +	unsigned int seg_32bit : 1;
>> +	unsigned int contents : 2;
>> +	unsigned int read_exec_only : 1;
>> +	unsigned int limit_in_pages : 1;
>> +	unsigned int seg_not_present : 1;
>> +	unsigned int useable : 1;
>> +#ifdef __x86_64__
>> +	unsigned int lm : 1;
>> +#endif /* __x86_64__ */
>> +};
>> +#endif /* HAVE_ASM_LDT_H */
>> +
>> +static inline int modify_ldt(int func, const struct user_desc *ptr,
>> +			     unsigned long bytecount)
>> +{
>> +	return tst_syscall(__NR_modify_ldt, func, ptr, bytecount);
>> +}
>> +
>> +static inline int safe_modify_ldt(const char *file, const int lineno, int func,
>> +				  const struct user_desc *ptr,
>> +				  unsigned long bytecount)
>> +{
>> +	int rval;
>> +
>> +	rval = modify_ldt(func, ptr, bytecount);
>> +	if (rval == -1) {
>> +		tst_brk_(file, lineno, TBROK | TERRNO,
>> +			 "modify_ldt(%d, %p, %lu)", func, ptr, bytecount);
>> +	} else if (rval) {
>> +		tst_brk_(file, lineno, TBROK | TERRNO,
>> +			 "modify_ltd(%d, %p, %lu) invalid retval %i", func, ptr,
>> +			 bytecount, rval);
>> +	}
>> +
>> +	return rval;
>> +}
>> +
>> +#define SAFE_MODIFY_LDT(func, ptr, bytecount) \
>> +	safe_modify_ldt(__FILE__, __LINE__, (func), (ptr), (bytecount))
>> +
>> +#endif /* LAPI_LDT_H__ */
>> diff --git a/testcases/cve/cve-2015-3290.c b/testcases/cve/cve-2015-3290.c
>> index 63e5d92c91b830cd8066a6a6c329461b72731f32..8ec1d53bbb5a9f3e7761d39855d34f593e118a28 100644
>> --- a/testcases/cve/cve-2015-3290.c
>> +++ b/testcases/cve/cve-2015-3290.c
>> @@ -123,16 +123,14 @@ perhaps unsurprisingly.)
>>   #include <stdlib.h>
>>   #include <stdio.h>
>>   #include <inttypes.h>
>> -#include <asm/ldt.h>
>>   #include <unistd.h>
>> -#include <sys/syscall.h>
>>   #include <setjmp.h>
>>   #include <signal.h>
>>   #include <string.h>
>>   #include <sys/wait.h>
>>   #include <linux/perf_event.h>
>>   
>> -#include "lapi/syscalls.h"
>> +#include "lapi/ldt.h"
>>   #include "tst_safe_pthread.h"
>>   
>>   /* Abstractions for some 32-bit vs 64-bit differences. */
>> @@ -199,27 +197,7 @@ static void set_ldt(void)
>>   		.useable	 = 0
>>   	};
>>   
>> -	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");
>
> There's a TCONF here if modify_ldt() returns EINVAL. SAFE_MODIFY_LDT() 
> will treat that as failure instead. EINVAL is expected.
>
>> -	} else if (TST_RET != 0) {
>> -		tst_brk(TBROK | TTERRNO, "modify_ldt");
>> -	}
>> +	SAFE_MODIFY_LDT(1, &data_desc, sizeof(data_desc));
>>   }
>>   
>>   static void try_corrupt_stack(unsigned short *orig_ss)
>> diff --git a/testcases/cve/cve-2017-17053.c b/testcases/cve/cve-2017-17053.c
>> index fe7b6d694d6ffbbce863abc1672e03ae5f419df1..ec7a534a6c0104e6688f204d763c31ed7a048201 100644
>> --- a/testcases/cve/cve-2017-17053.c
>> +++ b/testcases/cve/cve-2017-17053.c
>> @@ -17,16 +17,14 @@
>>   #include "tst_test.h"
>>   
>>   #ifdef HAVE_ASM_LDT_H
>> -#include <asm/ldt.h>
>>   #include <pthread.h>
>>   #include <signal.h>
>>   #include <stdlib.h>
>> -#include <sys/syscall.h>
>>   #include <sys/wait.h>
>>   #include <unistd.h>
>>   #include <stdio.h>
>>   
>> -#include "lapi/syscalls.h"
>> +#include "lapi/ldt.h"
>>   
>>   #define EXEC_USEC   5000000
>>   
>> @@ -109,7 +107,7 @@ void run_test(void)
>>   	struct user_desc desc = { .entry_number = 8191 };
>>   
>>   	install_sighandler();
>> -	syscall(__NR_modify_ldt, 1, &desc, sizeof(desc));
>> +	SAFE_MODIFY_LDT(1, &desc, sizeof(desc));
>>   
>>   	for (;;) {
>>   		if (shm->do_exit)
>> diff --git a/testcases/kernel/syscalls/fork/fork05.c b/testcases/kernel/syscalls/fork/fork05.c
>> index 22edefc3686978fbb9453dffabfcbccb7ea6bb12..9aa12e16201dec8f3d2a4c99df83c4e5e25ef857 100644
>> --- a/testcases/kernel/syscalls/fork/fork05.c
>> +++ b/testcases/kernel/syscalls/fork/fork05.c
>> @@ -55,8 +55,7 @@
>>   
>>   #if defined(__i386__)
>>   
>> -#include "lapi/syscalls.h"
>> -#include <asm/ldt.h>
>> +#include "lapi/ldt.h"
>>   
>>   static void run(void)
>>   {
>> @@ -76,7 +75,7 @@ static void run(void)
>>   	ldt0.seg_not_present = 0;
>>   	ldt0.useable = 1;
>>   
>> -	tst_syscall(__NR_modify_ldt, 1, &ldt0, sizeof(ldt0));
>> +	SAFE_MODIFY_LDT(1, &ldt0, sizeof(ldt0));
>>   
>>   	asm volatile ("movw %w0, %%fs"::"q" (7));
>>   	asm volatile ("movl %%fs:0, %0":"=r" (lo));
>> 



More information about the ltp mailing list