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

Martin Doucha mdoucha@suse.cz
Wed May 7 13:23:53 CEST 2025


Hi,
one more thing for cve-2015-3290 below.

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));
> 


-- 
Martin Doucha   mdoucha@suse.cz
SW Quality Engineer
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic


More information about the ltp mailing list