[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