From 6323fd5bfd94c3f80e2ff44f16488e0172bd9a96 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 27 Jul 2020 16:36:17 +0200 Subject: [PATCH] Handle linux syscalls sched_getattr and sched_setattr The only "special" thing about these syscalls is that the given struct sched_attr determines its own size for future expansion. Original fix by "ISHIKAWA,chiaki" https://bugs.kde.org/show_bug.cgi?id=369029 --- NEWS | 1 + coregrind/m_syswrap/priv_syswrap-linux.h | 2 ++ coregrind/m_syswrap/syswrap-amd64-linux.c | 5 ++- coregrind/m_syswrap/syswrap-arm-linux.c | 2 ++ coregrind/m_syswrap/syswrap-arm64-linux.c | 4 +-- coregrind/m_syswrap/syswrap-linux.c | 35 ++++++++++++++++++++ coregrind/m_syswrap/syswrap-mips32-linux.c | 3 ++ coregrind/m_syswrap/syswrap-mips64-linux.c | 2 ++ coregrind/m_syswrap/syswrap-nanomips-linux.c | 2 ++ coregrind/m_syswrap/syswrap-ppc32-linux.c | 3 ++ coregrind/m_syswrap/syswrap-ppc64-linux.c | 2 ++ coregrind/m_syswrap/syswrap-s390x-linux.c | 4 +-- coregrind/m_syswrap/syswrap-x86-linux.c | 4 +-- include/vki/vki-linux.h | 17 ++++++++++ 14 files changed, 77 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index 0ffcb5bf9f..77de28a294 100644 --- a/NEWS +++ b/NEWS @@ -40,6 +40,7 @@ To see details of a given bug, visit where XXXXXX is the bug number as listed below. 345077 linux syscall execveat support (linux 3.19) +369029 handle linux syscalls sched_getattr and sched_setattr n-i-bz helgrind: If hg_cli__realloc fails, return NULL. 423021 PPC: Add missing ISA 3.0 documentation link and HWCAPS test. diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h index cdc73c1e6d..eb0b320caa 100644 --- a/coregrind/m_syswrap/priv_syswrap-linux.h +++ b/coregrind/m_syswrap/priv_syswrap-linux.h @@ -227,6 +227,8 @@ DECL_TEMPLATE(linux, sys_fremovexattr); // syscalls. DECL_TEMPLATE(linux, sys_sched_setparam); DECL_TEMPLATE(linux, sys_sched_getparam); +DECL_TEMPLATE(linux, sys_sched_setattr); +DECL_TEMPLATE(linux, sys_sched_getattr); DECL_TEMPLATE(linux, sys_sched_setscheduler); DECL_TEMPLATE(linux, sys_sched_getscheduler); DECL_TEMPLATE(linux, sys_sched_yield); diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index 28d90135a4..d6f3eb9109 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -846,9 +846,8 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 311 LINX_(__NR_kcmp, sys_kcmp), // 312 LINX_(__NR_finit_module, sys_finit_module), // 313 -// LIN__(__NR_sched_setattr, sys_ni_syscall), // 314 - -// LIN__(__NR_sched_getattr, sys_ni_syscall), // 315 + LINX_(__NR_sched_setattr, sys_sched_setattr), // 314 + LINXY(__NR_sched_getattr, sys_sched_getattr), // 315 LINX_(__NR_renameat2, sys_renameat2), // 316 // LIN__(__NR_seccomp, sys_ni_syscall), // 317 LINXY(__NR_getrandom, sys_getrandom), // 318 diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c index 579542785e..70700e53f7 100644 --- a/coregrind/m_syswrap/syswrap-arm-linux.c +++ b/coregrind/m_syswrap/syswrap-arm-linux.c @@ -1009,6 +1009,8 @@ static SyscallTableEntry syscall_main_table[] = { LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 376 LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 377 + LINX_(__NR_sched_setattr, sys_sched_setattr), // 380 + LINXY(__NR_sched_getattr, sys_sched_getattr), // 381 LINX_(__NR_renameat2, sys_renameat2), // 382 LINXY(__NR_getrandom, sys_getrandom), // 384 diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c index 81e01456f8..acca024423 100644 --- a/coregrind/m_syswrap/syswrap-arm64-linux.c +++ b/coregrind/m_syswrap/syswrap-arm64-linux.c @@ -806,8 +806,8 @@ static SyscallTableEntry syscall_main_table[] = { LINX_(__NR_process_vm_writev, sys_process_vm_writev), // 271 LINX_(__NR_kcmp, sys_kcmp), // 272 LINX_(__NR_finit_module, sys_finit_module), // 273 - // (__NR_sched_setattr, sys_ni_syscall), // 274 - // (__NR_sched_getattr, sys_ni_syscall), // 275 + LINX_(__NR_sched_setattr, sys_sched_setattr), // 274 + LINXY(__NR_sched_getattr, sys_sched_getattr), // 275 LINX_(__NR_renameat2, sys_renameat2), // 276 // (__NR_seccomp, sys_ni_syscall), // 277 LINXY(__NR_getrandom, sys_getrandom), // 278 diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 5b5b7eee63..56be3032d3 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -3677,6 +3677,41 @@ POST(sys_sched_getparam) POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) ); } +PRE(sys_sched_setattr) +{ + struct vki_sched_attr *attr; + PRINT("sched_setattr ( %ld, %#" FMT_REGWORD "x, %#" + FMT_REGWORD "x )", SARG1, ARG2, ARG3 ); + PRE_REG_READ3(long, "sched_setattr", + vki_pid_t, pid, struct sched_attr *, p, unsigned int, flags); + /* We need to be able to read at least the size field. */ + PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) ); + attr = (struct vki_sched_attr *)(Addr)ARG2; + if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t))) + PRE_MEM_READ( "sched_setattr(attr)", (Addr)attr, attr->size); +} + +PRE(sys_sched_getattr) +{ + struct vki_sched_attr *attr; + PRINT("sched_getattr ( %ld, %#" FMT_REGWORD "x, %ld, %#" + FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4 ); + PRE_REG_READ4(long, "sched_getattr", + vki_pid_t, pid, struct sched_attr *, p, + unsigned int, size, unsigned int, flags); + /* We need to be able to read at least the size field. */ + PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) ); + /* And the kernel needs to be able to write to the whole struct size. */ + attr = (struct vki_sched_attr *)(Addr)ARG2; + if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t))) + PRE_MEM_WRITE( "sched_setattr(attr)", (Addr)attr, attr->size); +} +POST(sys_sched_getattr) +{ + struct vki_sched_attr *attr = (struct vki_sched_attr *)(Addr)ARG2; + POST_MEM_WRITE( (Addr)attr, attr->size ); +} + PRE(sys_sched_getscheduler) { PRINT("sys_sched_getscheduler ( %ld )", SARG1); diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c index ffb428dcb5..5face576be 100644 --- a/coregrind/m_syswrap/syswrap-mips32-linux.c +++ b/coregrind/m_syswrap/syswrap-mips32-linux.c @@ -1094,6 +1094,9 @@ static SyscallTableEntry syscall_main_table[] = { LINXY (__NR_process_vm_readv, sys_process_vm_readv), // 345 LINX_ (__NR_process_vm_writev, sys_process_vm_writev), // 346 //.. + LINX_(__NR_sched_setattr, sys_sched_setattr), // 349 + LINXY(__NR_sched_getattr, sys_sched_getattr), // 350 + //.. LINXY (__NR_getrandom, sys_getrandom), // 353 LINXY (__NR_memfd_create, sys_memfd_create), // 354 //.. diff --git a/coregrind/m_syswrap/syswrap-mips64-linux.c b/coregrind/m_syswrap/syswrap-mips64-linux.c index e5b471955c..c64911a50b 100644 --- a/coregrind/m_syswrap/syswrap-mips64-linux.c +++ b/coregrind/m_syswrap/syswrap-mips64-linux.c @@ -798,6 +798,8 @@ static SyscallTableEntry syscall_main_table[] = { LINXY (__NR_clock_adjtime, sys_clock_adjtime), LINXY (__NR_process_vm_readv, sys_process_vm_readv), LINX_ (__NR_process_vm_writev, sys_process_vm_writev), + LINX_ (__NR_sched_setattr, sys_sched_setattr), + LINXY (__NR_sched_getattr, sys_sched_getattr), LINXY (__NR_getrandom, sys_getrandom), LINXY (__NR_memfd_create, sys_memfd_create), LINX_ (__NR_execveat, sys_execveat), diff --git a/coregrind/m_syswrap/syswrap-nanomips-linux.c b/coregrind/m_syswrap/syswrap-nanomips-linux.c index 40253fadf5..7ceecb6daf 100644 --- a/coregrind/m_syswrap/syswrap-nanomips-linux.c +++ b/coregrind/m_syswrap/syswrap-nanomips-linux.c @@ -804,6 +804,8 @@ static SyscallTableEntry syscall_main_table[] = { LINX_ (__NR_process_vm_writev, sys_process_vm_writev), LINX_ (__NR_kcmp, sys_kcmp), LINX_ (__NR_renameat2, sys_renameat2), + LINX_ (__NR_sched_setattr, sys_sched_setattr), + LINXY (__NR_sched_getattr, sys_sched_getattr), LINXY (__NR_getrandom, sys_getrandom), LINXY (__NR_memfd_create, sys_memfd_create), LINXY (__NR_statx, sys_statx), diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index eed12a1bc6..c19cb9e0ee 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -1016,6 +1016,9 @@ static SyscallTableEntry syscall_table[] = { LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 351 LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 352 + LINX_(__NR_sched_setattr, sys_sched_setattr), // 355 + LINXY(__NR_sched_getattr, sys_sched_getattr), // 356 + LINXY(__NR_getrandom, sys_getrandom), // 359 LINXY(__NR_memfd_create, sys_memfd_create), // 360 diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c index d58200b491..b6422a7655 100644 --- a/coregrind/m_syswrap/syswrap-ppc64-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c @@ -998,6 +998,8 @@ static SyscallTableEntry syscall_table[] = { LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 351 LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 352 + LINX_(__NR_sched_setattr, sys_sched_setattr), // 355 + LINXY(__NR_sched_getattr, sys_sched_getattr), // 356 LINX_(__NR_renameat2, sys_renameat2), // 357 LINXY(__NR_getrandom, sys_getrandom), // 359 diff --git a/coregrind/m_syswrap/syswrap-s390x-linux.c b/coregrind/m_syswrap/syswrap-s390x-linux.c index a0a330aa20..3427fee16d 100644 --- a/coregrind/m_syswrap/syswrap-s390x-linux.c +++ b/coregrind/m_syswrap/syswrap-s390x-linux.c @@ -825,8 +825,8 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_kcmp, sys_kcmp), // 343 // ?????(__NR_finit_module, ), // 344 -// ?????(__NR_sched_setattr, ), // 345 -// ?????(__NR_sched_getattr, ), // 346 + LINX_(__NR_sched_setattr, sys_sched_setattr), // 345 + LINXY(__NR_sched_getattr, sys_sched_getattr), // 346 LINX_(__NR_renameat2, sys_renameat2), // 347 // ?????(__NR_seccomp, ), // 348 LINXY(__NR_getrandom, sys_getrandom), // 349 diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 332ed0bf27..b59d96f375 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -1580,8 +1580,8 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_kcmp, sys_kcmp), // 349 // LIN__(__NR_finit_module, sys_ni_syscall), // 350 -// LIN__(__NR_sched_setattr, sys_ni_syscall), // 351 -// LIN__(__NR_sched_getattr, sys_ni_syscall), // 352 + LINX_(__NR_sched_setattr, sys_sched_setattr), // 351 + LINXY(__NR_sched_getattr, sys_sched_getattr), // 352 LINX_(__NR_renameat2, sys_renameat2), // 353 // LIN__(__NR_seccomp, sys_ni_syscall), // 354 diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h index 75b5831650..ef93b92585 100644 --- a/include/vki/vki-linux.h +++ b/include/vki/vki-linux.h @@ -410,6 +410,23 @@ struct vki_sched_param { int sched_priority; }; +struct vki_sched_attr { + vki_uint32_t size; + vki_uint32_t sched_policy; + vki_uint64_t sched_flags; + + /* SCHED_NORMAL, SCHED_BATCH */ + vki_int32_t sched_nice; + + /* SCHED_FIFO, SCHED_RR */ + vki_uint32_t sched_priority; + + /* SCHED_DEADLINE */ + vki_uint64_t sched_runtime; + vki_uint64_t sched_deadline; + vki_uint64_t sched_period; +}; + #define VKI_TASK_COMM_LEN 16 //---------------------------------------------------------------------- -- 2.47.3