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