syscalls/shmctl05: new test for IPC file use-after-free bug
PATCH v2 1/1 syscalls/shmctl05: new test for IPC file use-after-free bug
From: Eric Biggers <[email protected]>
Test for a bug in the System V IPC subsystem that resulted in a shared memory file being used after it was freed (or being freed).
---
Changed since v1:
- Use using "fuzzy sync" spinlocks instead of random sleeps.
- Use threads with .timeout instead of processes.
- Use SAFE_SHMAT() instead of shmat() directly.
- Use tst_timer_expired_ms() instead of tst_timer_stop() + tst_timer_elapsed_ms().
runtest/syscalls | 1 + runtest/syscalls-ipc | 1 + .../kernel/syscalls/ipc/shmctl/.gitignore | 1 + testcases/kernel/syscalls/ipc/shmctl/Makefile | 2 + .../kernel/syscalls/ipc/shmctl/shmctl05.c | 112 ++++++++++++++++++ 5 files changed, 117 insertions(+) create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl05.c
runtest/syscalls +1 -0
@@ -1187,6 +1187,7 @@ shmctl01 shmctl01 shmctl02 shmctl02 shmctl03 shmctl03 shmctl04 shmctl04 +shmctl05 shmctl05 shmdt01 shmdt01 shmdt02 shmdt02
runtest/syscalls-ipc +1 -0
@@ -53,6 +53,7 @@ shmctl01 shmctl01 shmctl02 shmctl02 shmctl03 shmctl03 shmctl04 shmctl04 +shmctl05 shmctl05 shmdt01 shmdt01 shmdt02 shmdt02
testcases/kernel/syscalls/ipc/shmctl/.gitignore +1 -0
@@ -2,3 +2,4 @@ /shmctl02 /shmctl03 /shmctl04 +/shmctl05
testcases/kernel/syscalls/ipc/shmctl/Makefile +2 -0
@@ -18,6 +18,8 @@ top_srcdir ?= ../../../../.. +shmctl05: LDLIBS += -lpthread + include $(top_srcdir)/include/mk/testcases.mk include $(abs_srcdir)/../Makefile.inc include $(top_srcdir)/include/mk/generic_leaf_target.mk
testcases/kernel/syscalls/ipc/shmctl/shmctl05.c new file +112 -0
112 lines not on this page · raw message
Signature · 1 line
2.18.0
PATCH v2 1/1 syscalls/shmctl05: new test for IPC file use-after-free bug
----- Original Message -----
Quoted 6 lines
From: Eric Biggers <[email protected]>
Test for a bug in the System V IPC subsystem that resulted in a shared memory file being used after it was freed (or being freed).
Signed-off-by Eric Biggers <[email protected]>
Hi,
overall looks good to me, just 2 small comments inline.
Quoted 57 lines
---
Changed since v1:
- Use using "fuzzy sync" spinlocks instead of random sleeps.
- Use threads with .timeout instead of processes.
- UseSAFE_SHMAT()instead ofshmat()directly.
- Usetst_timer_expired_ms()instead oftst_timer_stop()+tst_timer_elapsed_ms().runtest/syscalls | 1 + runtest/syscalls-ipc | 1 + .../kernel/syscalls/ipc/shmctl/.gitignore | 1 + testcases/kernel/syscalls/ipc/shmctl/Makefile | 2 + .../kernel/syscalls/ipc/shmctl/shmctl05.c | 112 ++++++++++++++++++ 5 files changed, 117 insertions(+) create mode 100644 testcases/kernel/syscalls/ipc/shmctl/shmctl05.cruntest/syscalls +1
-0@@ -1187,6 +1187,7 @@ shmctl01 shmctl01 shmctl02 shmctl02 shmctl03 shmctl03 shmctl04 shmctl04 +shmctl05 shmctl05 shmdt01 shmdt01 shmdt02 shmdt02runtest/syscalls-ipc +1
-0@@ -53,6 +53,7 @@ shmctl01 shmctl01 shmctl02 shmctl02 shmctl03 shmctl03 shmctl04 shmctl04 +shmctl05 shmctl05 shmdt01 shmdt01 shmdt02 shmdt02testcases/kernel/syscalls/ipc/shmctl/.gitignore +1
-0@@ -2,3 +2,4 @@ /shmctl02 /shmctl03 /shmctl04 +/shmctl05testcases/kernel/syscalls/ipc/shmctl/Makefile +0
-0
testcases/kernel/syscalls/ipc/shmctl/Makefile line 21
Quoted 4 lines
testcases/kernel/syscalls/ipc/shmctl/Makefile +1
-0@@ -18,6 +18,8 @@ top_srcdir ?= ../../../../.. +shmctl05: LDLIBS += -lpthread
New code has been using:
CFLAGS += -pthread
to match more closely "Compile and link with -pthread".
Quoted 68 lines
testcases/kernel/syscalls/ipc/shmctl/Makefile +1
-0+ include $(top_srcdir)/include/mk/testcases.mk include $(abs_srcdir)/../Makefile.inc include $(top_srcdir)/include/mk/generic_leaf_target.mktestcases/kernel/syscalls/ipc/shmctl/shmctl05.c new file +19
-0@@ -0,0 +1,112 @@ +/* +* Copyright (c) 2018 Google, Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program, if not, see <http://www.gnu.org/licenses/>. +*/ + +/* +* Regression test for commit 3f05317d9889 ("ipc/shm: fix use-after-free of shm
+ * file viaremap_file_pages()"). This bug allowed theremap_file_pages()
+ * syscall to use the file of a System V shared memory segment after its ID had
+ * been reallocated and the file freed. This test reproduces the bug as a NULL
+ * pointer dereference intouch_atime(), although it's a race condition so it's
+ * not guaranteed to work. This test is based on the reproducer provided in the
+ * fix's commit message.
+ */testcases/kernel/syscalls/ipc/shmctl/shmctl05.c new file +26
-0+ +#include "lapi/syscalls.h" +#include "tst_test.h" +#include "tst_fuzzy_sync.h" +#include "tst_safe_pthread.h" +#include "tst_safe_sysv_ipc.h" +#include "tst_timer.h" + +static struct tst_fzsync_pair fzsync_pair =TST_FZSYNC_PAIR_INIT ; + +static pthread_t thrd; + +/* +* Thread 2: repeatedly remove the shm ID and reallocate it again for a +* new shm segment. +*/ +static void *thrproc (void *unused) +{ +int id =SAFE_SHMGET (0xF00F ,4096 ,IPC_CREAT |0700 ); + +for (;;) { +if (!tst_fzsync_wait_b (&fzsync_pair)) +break ; +SAFE_SHMCTL (id,IPC_RMID ,NULL ); + id =SAFE_SHMGET (0xF00F ,4096 ,IPC_CREAT |0700 ); +if (!tst_fzsync_wait_b (&fzsync_pair))
testcases/kernel/syscalls/ipc/shmctl/shmctl05.c line 62
Quoted 10 lines
testcases/kernel/syscalls/ipc/shmctl/shmctl05.c new file +10
-0+break ; + } +return unused; +} + +static void setup (void ) +{ +/* Skip test if either remap_file_pages() or SysV IPC is unavailable */ +tst_syscall (__NR_remap_file_pages,NULL ,0 ,0 ,0 ,0 ); +tst_syscall (__NR_shmctl,0xF00F ,IPC_RMID ,NULL );
There was a thread about something like "tst_timer_start_any()", but that doesn't exist yet. So adding a check for specific clock still seems to be needed in setup():
tst_timer_check(CLOCK_MONOTONIC);
Regards,
Jan