1 /*
2  * Test that shmat() does not break /proc/self/maps.
3  *
4  * SPDX-License-Identifier: GPL-2.0-or-later
5  */
6 #include <assert.h>
7 #include <fcntl.h>
8 #include <stdlib.h>
9 #include <sys/ipc.h>
10 #include <sys/shm.h>
11 #include <unistd.h>
12 
13 int main(void)
14 {
15     char buf[128];
16     int err, fd;
17     int shmid;
18     ssize_t n;
19     void *p;
20 
21     shmid = shmget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
22     assert(shmid != -1);
23 
24     /*
25      * The original bug required a non-NULL address, which skipped the
26      * mmap_find_vma step, which could result in a host mapping smaller
27      * than the target mapping.  Choose an address at random.
28      */
29     p = shmat(shmid, (void *)0x800000, SHM_RND);
30     if (p == (void *)-1) {
31         /*
32          * Because we are now running the testcase for all guests for which
33          * we have a cross-compiler, the above random address might conflict
34          * with the guest executable in some way.  Rather than stopping,
35          * continue with a system supplied address, which should never fail.
36          */
37         p = shmat(shmid, NULL, 0);
38         assert(p != (void *)-1);
39     }
40 
41     fd = open("/proc/self/maps", O_RDONLY);
42     assert(fd != -1);
43     do {
44         n = read(fd, buf, sizeof(buf));
45         assert(n >= 0);
46     } while (n != 0);
47     close(fd);
48 
49     err = shmdt(p);
50     assert(err == 0);
51     err = shmctl(shmid, IPC_RMID, NULL);
52     assert(err == 0);
53 
54     return EXIT_SUCCESS;
55 }
56