diff options
author | Ilya Leoshkevich <iii@linux.ibm.com> | 2024-02-23 12:31:40 +0100 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2024-03-01 08:09:55 -1000 |
commit | 04dadd22aed00e5a2955ab078d7edd676812cf41 (patch) | |
tree | 3fb4fa7d97211d4bb7032c2a6bd431a7345d073a /tests | |
parent | 78bc8ed9a8f092f6666d7a949ad67dac33cc014d (diff) | |
download | qemu-04dadd22aed00e5a2955ab078d7edd676812cf41.zip qemu-04dadd22aed00e5a2955ab078d7edd676812cf41.tar.gz qemu-04dadd22aed00e5a2955ab078d7edd676812cf41.tar.bz2 |
tests/tcg: Check that shmat() does not break /proc/self/maps
Add a regression test for a recently fixed issue, where shmat()
desynced the guest and the host view of the address space and caused
open("/proc/self/maps") to SEGV.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <jwyuvao4apydvykmsnvacwshdgy3ixv7qvkh4dbxm3jkwgnttw@k4wpaayou7oq>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/tcg/multiarch/linux/linux-shmat-maps.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/tests/tcg/multiarch/linux/linux-shmat-maps.c b/tests/tcg/multiarch/linux/linux-shmat-maps.c new file mode 100644 index 0000000..0ccf7a9 --- /dev/null +++ b/tests/tcg/multiarch/linux/linux-shmat-maps.c @@ -0,0 +1,55 @@ +/* + * Test that shmat() does not break /proc/self/maps. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include <assert.h> +#include <fcntl.h> +#include <stdlib.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <unistd.h> + +int main(void) +{ + char buf[128]; + int err, fd; + int shmid; + ssize_t n; + void *p; + + shmid = shmget(IPC_PRIVATE, 1, IPC_CREAT | 0600); + assert(shmid != -1); + + /* + * The original bug required a non-NULL address, which skipped the + * mmap_find_vma step, which could result in a host mapping smaller + * than the target mapping. Choose an address at random. + */ + p = shmat(shmid, (void *)0x800000, SHM_RND); + if (p == (void *)-1) { + /* + * Because we are now running the testcase for all guests for which + * we have a cross-compiler, the above random address might conflict + * with the guest executable in some way. Rather than stopping, + * continue with a system supplied address, which should never fail. + */ + p = shmat(shmid, NULL, 0); + assert(p != (void *)-1); + } + + fd = open("/proc/self/maps", O_RDONLY); + assert(fd != -1); + do { + n = read(fd, buf, sizeof(buf)); + assert(n >= 0); + } while (n != 0); + close(fd); + + err = shmdt(p); + assert(err == 0); + err = shmctl(shmid, IPC_RMID, NULL); + assert(err == 0); + + return EXIT_SUCCESS; +} |