1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) International Business Machines Corp., 2001 4 */ 5 6/* 7 * DESCRIPTION 8 * 9 * 1) shmat() fails and set errno to EINVAL when shmid is invalid. 10 * 2) shmat() fails and set errno to EINVAL when shmaddr is not page 11 * aligned and SHM_RND is not given 12 * 3) shmat() fails and set errno to EACCES when the shm resource has 13 * no read/write permission. 14 */ 15 16#include <errno.h> 17#include <stdlib.h> 18#include <sys/types.h> 19#include <sys/ipc.h> 20#include <sys/shm.h> 21#include <pwd.h> 22 23#include "tst_test.h" 24#include "tst_safe_sysv_ipc.h" 25#include "libnewipc.h" 26 27static int shm_id1 = -1; 28static int shm_id2 = -1; 29static void *aligned_addr; 30static void *unaligned_addr; 31static key_t shm_key1; 32static struct passwd *pw; 33 34static struct test_case_t { 35 int *shmid; 36 void **shmaddr; 37 int exp_err; 38 int exp_user; 39} tcases[] = { 40 {&shm_id1, &aligned_addr, EINVAL, 0}, 41 {&shm_id2, &unaligned_addr, EINVAL, 0}, 42 {&shm_id2, &aligned_addr, EACCES, 1}, 43}; 44 45static void verify_shmat(struct test_case_t *tc) 46{ 47 void *addr; 48 49 addr = shmat(*tc->shmid, *tc->shmaddr, 0); 50 if (addr != (void *)-1) { 51 tst_res(TFAIL, "shmat() succeeded unexpectedly"); 52 return; 53 } 54 55 if (errno == tc->exp_err) { 56 tst_res(TPASS | TERRNO, "shmat() failed as expected"); 57 } else { 58 tst_res(TFAIL | TERRNO, "shmat() failed unexpectedly, expected: %s", 59 tst_strerrno(tc->exp_err)); 60 } 61} 62 63static void do_shmat(unsigned int n) 64{ 65 pid_t pid; 66 67 struct test_case_t *tc = &tcases[n]; 68 69 if (!tc->exp_user) { 70 verify_shmat(tc); 71 } else { 72 pid = SAFE_FORK(); 73 if (pid) { 74 tst_reap_children(); 75 } else { 76 SAFE_SETUID(pw->pw_uid); 77 verify_shmat(tc); 78 exit(0); 79 } 80 } 81} 82 83static void setup(void) 84{ 85 aligned_addr = PROBE_FREE_ADDR(); 86 unaligned_addr = aligned_addr + SHMLBA - 1; 87 88 shm_key1 = GETIPCKEY(); 89 90 shm_id2 = SAFE_SHMGET(shm_key1, INT_SIZE, SHM_RW | IPC_CREAT | IPC_EXCL); 91 92 pw = SAFE_GETPWNAM("nobody"); 93} 94 95static void cleanup(void) 96{ 97 if (shm_id2 != -1) 98 SAFE_SHMCTL(shm_id2, IPC_RMID, NULL); 99} 100 101static struct tst_test test = { 102 .needs_root = 1, 103 .forks_child = 1, 104 .test = do_shmat, 105 .tcnt = ARRAY_SIZE(tcases), 106 .setup = setup, 107 .cleanup = cleanup 108}; 109