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 * This basic error handing of the semget syscall. 10 * 11 * - EACCES - a semaphore set exists for key, but the calling process does not 12 * have permission to access the set 13 * - EEXIST - a semaphore set already exists for key and IPC_CREAT | IPC_EXCL 14 * is given 15 * - ENOENT - No semaphore set exists for key and semflg did not specify 16 * IPC_CREAT 17 * - EINVAL - nsems is less than 0 or greater than the limit on the number of 18 * semaphores per semaphore set(SEMMSL) 19 * - EINVAL - a semaphore set corresponding to key already exists, but nsems is 20 * larger than the number of semaphores in that set 21 */ 22 23#include <stdlib.h> 24#include <errno.h> 25#include <sys/types.h> 26#include <sys/ipc.h> 27#include <sys/types.h> 28#include <pwd.h> 29#include "tst_test.h" 30#include "tst_safe_sysv_ipc.h" 31#include "libnewipc.h" 32#include "lapi/sem.h" 33 34static int sem_id = -1; 35static key_t semkey, semkey1; 36static struct passwd *pw; 37static struct tcase { 38 int *key; 39 int nsems; 40 int flags; 41 int exp_err; 42 /*1: nobody expected, 0: root expected */ 43 int exp_user; 44} tcases[] = { 45 {&semkey, PSEMS, SEM_RA, EACCES, 1}, 46 {&semkey, PSEMS, IPC_CREAT | IPC_EXCL, EEXIST, 0}, 47 {&semkey1, PSEMS, SEM_RA, ENOENT, 0}, 48 {&semkey1, -1, IPC_CREAT | IPC_EXCL, EINVAL, 0}, 49 {&semkey1, SEMMSL + 1, IPC_CREAT | IPC_EXCL, EINVAL, 0}, 50 {&semkey, PSEMS + 1, SEM_RA, EINVAL, 0}, 51}; 52 53static void verify_semget(struct tcase *tc) 54{ 55 TST_EXP_FAIL2(semget(*tc->key, tc->nsems, tc->flags), tc->exp_err, 56 "semget(%i, %i, %i)", *tc->key, tc->nsems, tc->flags); 57} 58 59static void do_test(unsigned int n) 60{ 61 pid_t pid; 62 struct tcase *tc = &tcases[n]; 63 64 if (tc->exp_user == 0) { 65 verify_semget(tc); 66 } else { 67 pid = SAFE_FORK(); 68 if (pid) { 69 tst_reap_children(); 70 } else { 71 SAFE_SETUID(pw->pw_uid); 72 verify_semget(tc); 73 exit(0); 74 } 75 } 76} 77 78static void setup(void) 79{ 80 semkey = GETIPCKEY(); 81 semkey1 = GETIPCKEY(); 82 83 sem_id = SAFE_SEMGET(semkey, PSEMS, IPC_CREAT | IPC_EXCL); 84 85 pw = SAFE_GETPWNAM("nobody"); 86} 87 88static void cleanup(void) 89{ 90 if (sem_id != -1) 91 SAFE_SEMCTL(sem_id, PSEMS, IPC_RMID); 92} 93 94static struct tst_test test = { 95 .needs_tmpdir = 1, 96 .needs_root = 1, 97 .forks_child = 1, 98 .tcnt = ARRAY_SIZE(tcases), 99 .setup = setup, 100 .cleanup = cleanup, 101 .test = do_test, 102}; 103