From 700e78f257ad161b4bd040de2d6bd9f1de4ff0b2 Mon Sep 17 00:00:00 2001 From: Matthias Schwarzott Date: Sat, 23 Aug 2025 13:37:46 +0200 Subject: [PATCH] Bug 508779 - PRE(sys_prlimit64): reorder check for memory validity so all errors are displayed and not just the first --- NEWS | 1 + coregrind/m_syswrap/syswrap-linux.c | 14 +- memcheck/tests/amd64-linux/scalar.c | 22 ++++ memcheck/tests/amd64-linux/scalar.stderr.exp | 128 +++++++++++++++++++ memcheck/tests/x86-linux/scalar.c | 14 ++ memcheck/tests/x86-linux/scalar.stderr.exp | 96 ++++++++++++++ 6 files changed, 267 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 0d6e10ee9..b1f4d8d11 100644 --- a/NEWS +++ b/NEWS @@ -89,6 +89,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 508638 Self-hosting not working on FreeBSD 508777 amd64-linux: add minimal scalar test 508778 syscall-wrapper waitid warns about infop=null +508779 PRE(sys_prlimit64): reorder check for memory validity 508869 x86-linux: simplify scalar test output To see details of a given bug, visit diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index a740912f8..785031c10 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -2307,17 +2307,15 @@ PRE(sys_prlimit64) struct rlimit64 *, old_rlim); if (ARG3) { PRE_MEM_READ( "rlimit64(new_rlim)", ARG3, sizeof(struct vki_rlimit64) ); - if (!ML_(safe_to_deref)((void*)(Addr)ARG3, sizeof(struct vki_rlimit64))) { - SET_STATUS_Failure(VKI_EFAULT); - return; - } } if (ARG4) { PRE_MEM_WRITE( "rlimit64(old_rlim)", ARG4, sizeof(struct vki_rlimit64) ); - if (!ML_(safe_to_deref)((void*)(Addr)ARG4, sizeof(struct vki_rlimit64))) { - SET_STATUS_Failure(VKI_EFAULT); - return; - } + } + + if ((ARG3 && !ML_(safe_to_deref)((void*)(Addr)ARG3, sizeof(struct vki_rlimit64))) + || (ARG4 && !ML_(safe_to_deref)((void*)(Addr)ARG4, sizeof(struct vki_rlimit64)))) { + SET_STATUS_Failure(VKI_EFAULT); + return; } if (ARG3 && diff --git a/memcheck/tests/amd64-linux/scalar.c b/memcheck/tests/amd64-linux/scalar.c index 5167fde2d..fe133d8d2 100644 --- a/memcheck/tests/amd64-linux/scalar.c +++ b/memcheck/tests/amd64-linux/scalar.c @@ -3,6 +3,7 @@ #include "../../memcheck.h" #include "scalar.h" #include +#include // Here we are trying to trigger every syscall error (scalar errors and // memory errors) for every syscall. We do this by passing a lot of bogus @@ -45,6 +46,14 @@ int main(void) GO(__NR_exit, "below"); // (see below) + // __NR_getrlimit 97 + GO(__NR_getrlimit, "2s 1m"); + SY(__NR_getrlimit, x0, x0); FAIL; + + // __NR_setrlimit 160 + GO(__NR_setrlimit, "2s 1m"); + SY(__NR_setrlimit, x0, x0); FAILx(EFAULT); + // __NR_waitid 247 GO(__NR_waitid, "5s 0m"); SY(__NR_waitid, x0, x0, x0, x0, x0); FAIL; @@ -52,6 +61,19 @@ int main(void) GO(__NR_waitid, "(infop,ru) 5s 2m"); SY(__NR_waitid, x0, x0, x0 + 1, x0, x0 + 1); FAIL; + // __NR_prlimit64 302 + GO(__NR_prlimit64, "(nop) 4s 0m"); + SY(__NR_prlimit64, x0, x0 + RLIMIT_NOFILE, x0, x0); SUCC; + + GO(__NR_prlimit64, "(set) 4s 1m"); + SY(__NR_prlimit64, x0, x0 + RLIMIT_NOFILE, x0 + 1, x0); FAILx(EFAULT); + + GO(__NR_prlimit64, "(get) 4s 1m"); + SY(__NR_prlimit64, x0, x0 + RLIMIT_NOFILE, x0, x0 + 1); FAILx(EFAULT); + + GO(__NR_prlimit64, "(get+set) 4s 2m"); + SY(__NR_prlimit64, x0, x0 + RLIMIT_NOFILE, x0 + 1, x0 + 1); FAILx(EFAULT); + // no such syscall... GO(9999, "1e"); SY(9999); FAIL; diff --git a/memcheck/tests/amd64-linux/scalar.stderr.exp b/memcheck/tests/amd64-linux/scalar.stderr.exp index 12f6fcba3..1757cc3eb 100644 --- a/memcheck/tests/amd64-linux/scalar.stderr.exp +++ b/memcheck/tests/amd64-linux/scalar.stderr.exp @@ -45,6 +45,38 @@ Syscall param write(buf) points to unaddressable byte(s) ----------------------------------------------------- 60: __NR_exit below ----------------------------------------------------- +----------------------------------------------------- + 97: __NR_getrlimit 2s 1m +----------------------------------------------------- +Syscall param getrlimit(resource) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param getrlimit(rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param getrlimit(rlim) points to unaddressable byte(s) + ... + by 0x........: main (scalar.c) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +----------------------------------------------------- +160: __NR_setrlimit 2s 1m +----------------------------------------------------- +Syscall param setrlimit(resource) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param setrlimit(rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param setrlimit(rlim) points to unaddressable byte(s) + ... + by 0x........: main (scalar.c) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + ----------------------------------------------------- 247: __NR_waitid 5s 0m ----------------------------------------------------- @@ -101,6 +133,102 @@ Syscall param waitid(ru) points to unaddressable byte(s) by 0x........: main (scalar.c) Address 0x........ is not stack'd, malloc'd or (recently) free'd +----------------------------------------------------- +302: __NR_prlimit64 (nop) 4s 0m +----------------------------------------------------- +Syscall param prlimit64(pid) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(resource) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(new_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(old_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +----------------------------------------------------- +302: __NR_prlimit64 (set) 4s 1m +----------------------------------------------------- +Syscall param prlimit64(pid) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(resource) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(new_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(old_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param rlimit64(new_rlim) points to unaddressable byte(s) + ... + by 0x........: main (scalar.c) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +----------------------------------------------------- +302: __NR_prlimit64 (get) 4s 1m +----------------------------------------------------- +Syscall param prlimit64(pid) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(resource) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(new_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(old_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param rlimit64(old_rlim) points to unaddressable byte(s) + ... + by 0x........: main (scalar.c) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +----------------------------------------------------- +302: __NR_prlimit64 (get+set) 4s 2m +----------------------------------------------------- +Syscall param prlimit64(pid) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(resource) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(new_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(old_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param rlimit64(new_rlim) points to unaddressable byte(s) + ... + by 0x........: main (scalar.c) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +Syscall param rlimit64(old_rlim) points to unaddressable byte(s) + ... + by 0x........: main (scalar.c) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + ----------------------------------------------------- 9999: 9999 1e ----------------------------------------------------- diff --git a/memcheck/tests/x86-linux/scalar.c b/memcheck/tests/x86-linux/scalar.c index 5141f0496..e6ff44fe0 100644 --- a/memcheck/tests/x86-linux/scalar.c +++ b/memcheck/tests/x86-linux/scalar.c @@ -7,6 +7,7 @@ #include #include // MREMAP_FIXED #include +#include // Here we are trying to trigger every syscall error (scalar errors and // memory errors) for every syscall. We do this by passing a lot of bogus @@ -1283,6 +1284,19 @@ int main(void) GO(__NR_epoll_create1, "1s 0m"); SY(__NR_epoll_create1, x0); SUCC_OR_FAIL; + // __NR_prlimit64 340 + GO(__NR_prlimit64, "(nop) 4s 0m"); + SY(__NR_prlimit64, x0, x0 + RLIMIT_NOFILE, x0, x0); SUCC; + + GO(__NR_prlimit64, "(set) 4s 1m"); + SY(__NR_prlimit64, x0, x0 + RLIMIT_NOFILE, x0 + 1, x0); FAILx(EFAULT); + + GO(__NR_prlimit64, "(get) 4s 1m"); + SY(__NR_prlimit64, x0, x0 + RLIMIT_NOFILE, x0, x0 + 1); FAILx(EFAULT); + + GO(__NR_prlimit64, "(get+set) 4s 2m"); + SY(__NR_prlimit64, x0, x0 + RLIMIT_NOFILE, x0 + 1, x0 + 1); FAILx(EFAULT); + // __NR_process_vm_readv 347 GO(__NR_process_vm_readv, "6s 2m"); SY(__NR_process_vm_readv, x0, x0, x0+1, x0, x0+1, x0); FAIL; diff --git a/memcheck/tests/x86-linux/scalar.stderr.exp b/memcheck/tests/x86-linux/scalar.stderr.exp index b75507547..3cbb0c6ff 100644 --- a/memcheck/tests/x86-linux/scalar.stderr.exp +++ b/memcheck/tests/x86-linux/scalar.stderr.exp @@ -4208,6 +4208,102 @@ Syscall param epoll_create1(flags) contains uninitialised byte(s) ... by 0x........: main (scalar.c) +----------------------------------------------------- +340: __NR_prlimit64 (nop) 4s 0m +----------------------------------------------------- +Syscall param prlimit64(pid) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(resource) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(new_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(old_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +----------------------------------------------------- +340: __NR_prlimit64 (set) 4s 1m +----------------------------------------------------- +Syscall param prlimit64(pid) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(resource) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(new_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(old_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param rlimit64(new_rlim) points to unaddressable byte(s) + ... + by 0x........: main (scalar.c) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +----------------------------------------------------- +340: __NR_prlimit64 (get) 4s 1m +----------------------------------------------------- +Syscall param prlimit64(pid) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(resource) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(new_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(old_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param rlimit64(old_rlim) points to unaddressable byte(s) + ... + by 0x........: main (scalar.c) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +----------------------------------------------------- +340: __NR_prlimit64 (get+set) 4s 2m +----------------------------------------------------- +Syscall param prlimit64(pid) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(resource) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(new_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param prlimit64(old_rlim) contains uninitialised byte(s) + ... + by 0x........: main (scalar.c) + +Syscall param rlimit64(new_rlim) points to unaddressable byte(s) + ... + by 0x........: main (scalar.c) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +Syscall param rlimit64(old_rlim) points to unaddressable byte(s) + ... + by 0x........: main (scalar.c) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + ----------------------------------------------------- 347:__NR_process_vm_readv 6s 2m ----------------------------------------------------- -- 2.47.3