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