1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2009 4f08c3bdfSopenharmony_ci * Veerendra C <vechandr@in.ibm.com> 5f08c3bdfSopenharmony_ci * Copyright (C) 2022 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> 6f08c3bdfSopenharmony_ci */ 7f08c3bdfSopenharmony_ci 8f08c3bdfSopenharmony_ci/*\ 9f08c3bdfSopenharmony_ci * [Description] 10f08c3bdfSopenharmony_ci * 11f08c3bdfSopenharmony_ci * Test SysV IPC semaphore usage between namespaces and processes. 12f08c3bdfSopenharmony_ci * 13f08c3bdfSopenharmony_ci * [Algorithm] 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * Create 2 'containers' 16f08c3bdfSopenharmony_ci * In container1 create semaphore with a specific key and lock it 17f08c3bdfSopenharmony_ci * In container2 try to access the semaphore created in container1 and try to 18f08c3bdfSopenharmony_ci * unlock it. 19f08c3bdfSopenharmony_ci * 20f08c3bdfSopenharmony_ci * If mode = None, test will PASS when semaphore created process1 can be read 21f08c3bdfSopenharmony_ci * and unlocked from process2. 22f08c3bdfSopenharmony_ci * If mode = Clone, test will PASS when semaphore created in container1 can't 23f08c3bdfSopenharmony_ci * be accessed from container2. 24f08c3bdfSopenharmony_ci * If mode = Unshare, test will PASS when semaphore created in container2 can't 25f08c3bdfSopenharmony_ci * be accessed from container2. 26f08c3bdfSopenharmony_ci */ 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_ci#define _GNU_SOURCE 29f08c3bdfSopenharmony_ci 30f08c3bdfSopenharmony_ci#include <sys/wait.h> 31f08c3bdfSopenharmony_ci#include <sys/msg.h> 32f08c3bdfSopenharmony_ci#include <sys/types.h> 33f08c3bdfSopenharmony_ci#include <sys/sem.h> 34f08c3bdfSopenharmony_ci#include "tst_safe_sysv_ipc.h" 35f08c3bdfSopenharmony_ci#include "tst_test.h" 36f08c3bdfSopenharmony_ci#include "common.h" 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_ci#define MY_KEY 124326L 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_cistatic char *str_op; 41f08c3bdfSopenharmony_cistatic int use_clone; 42f08c3bdfSopenharmony_ci 43f08c3bdfSopenharmony_cistatic void check_sem1(void) 44f08c3bdfSopenharmony_ci{ 45f08c3bdfSopenharmony_ci int id; 46f08c3bdfSopenharmony_ci struct sembuf sm = { 47f08c3bdfSopenharmony_ci .sem_num = 0, 48f08c3bdfSopenharmony_ci .sem_op = 1, 49f08c3bdfSopenharmony_ci .sem_flg = SEM_UNDO, 50f08c3bdfSopenharmony_ci }; 51f08c3bdfSopenharmony_ci 52f08c3bdfSopenharmony_ci id = SAFE_SEMGET(MY_KEY, 1, IPC_CREAT | IPC_EXCL | 0666); 53f08c3bdfSopenharmony_ci 54f08c3bdfSopenharmony_ci tst_res(TINFO, "%s: created key in child1", str_op); 55f08c3bdfSopenharmony_ci 56f08c3bdfSopenharmony_ci TST_CHECKPOINT_WAKE_AND_WAIT(0); 57f08c3bdfSopenharmony_ci 58f08c3bdfSopenharmony_ci tst_res(TINFO, "Lock semaphore in container1"); 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_ci SAFE_SEMOP(id, &sm, 1); 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_ci TST_CHECKPOINT_WAKE_AND_WAIT(0); 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_ci SAFE_SEMCTL(id, IPC_RMID, 0); 65f08c3bdfSopenharmony_ci} 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_cistatic void check_sem2(void) 68f08c3bdfSopenharmony_ci{ 69f08c3bdfSopenharmony_ci int id; 70f08c3bdfSopenharmony_ci struct sembuf sm = { 71f08c3bdfSopenharmony_ci .sem_num = 0, 72f08c3bdfSopenharmony_ci .sem_op = -1, 73f08c3bdfSopenharmony_ci .sem_flg = IPC_NOWAIT | SEM_UNDO, 74f08c3bdfSopenharmony_ci }; 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_ci TST_CHECKPOINT_WAIT(0); 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_ci tst_res(TINFO, "%s: reading key in child2", str_op); 79f08c3bdfSopenharmony_ci 80f08c3bdfSopenharmony_ci id = semget(MY_KEY, 1, 0); 81f08c3bdfSopenharmony_ci if (id >= 0) { 82f08c3bdfSopenharmony_ci if (use_clone == T_NONE) 83f08c3bdfSopenharmony_ci tst_res(TPASS, "Plain cloned process able to access the semaphore created"); 84f08c3bdfSopenharmony_ci else 85f08c3bdfSopenharmony_ci tst_res(TFAIL, "%s: In namespace2 found semaphore created in namespace1", str_op); 86f08c3bdfSopenharmony_ci } else { 87f08c3bdfSopenharmony_ci if (use_clone == T_NONE) 88f08c3bdfSopenharmony_ci tst_res(TFAIL, "Plain cloned process didn't find semaphore"); 89f08c3bdfSopenharmony_ci else 90f08c3bdfSopenharmony_ci tst_res(TPASS, "%s: In namespace2 unable to access semaphore created in namespace1", str_op); 91f08c3bdfSopenharmony_ci } 92f08c3bdfSopenharmony_ci 93f08c3bdfSopenharmony_ci TST_CHECKPOINT_WAKE_AND_WAIT(0); 94f08c3bdfSopenharmony_ci 95f08c3bdfSopenharmony_ci if (id >= 0) { 96f08c3bdfSopenharmony_ci tst_res(TINFO, "Trying to unlock semaphore in container2"); 97f08c3bdfSopenharmony_ci TEST(semop(id, &sm, 1)); 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ci if (TST_RET >= 0) { 100f08c3bdfSopenharmony_ci if (use_clone == T_NONE) 101f08c3bdfSopenharmony_ci tst_res(TPASS, "Plain cloned process able to unlock semaphore"); 102f08c3bdfSopenharmony_ci else 103f08c3bdfSopenharmony_ci tst_res(TFAIL, "%s: In namespace2 able to unlock the semaphore created in an namespace1", str_op); 104f08c3bdfSopenharmony_ci } else { 105f08c3bdfSopenharmony_ci if (use_clone == T_NONE) 106f08c3bdfSopenharmony_ci tst_res(TFAIL, "Plain cloned process unable to unlock semaphore"); 107f08c3bdfSopenharmony_ci else 108f08c3bdfSopenharmony_ci tst_res(TPASS, "%s: In namespace2 unable to unlock the semaphore created in an namespace1", str_op); 109f08c3bdfSopenharmony_ci } 110f08c3bdfSopenharmony_ci } 111f08c3bdfSopenharmony_ci 112f08c3bdfSopenharmony_ci TST_CHECKPOINT_WAKE(0); 113f08c3bdfSopenharmony_ci} 114f08c3bdfSopenharmony_ci 115f08c3bdfSopenharmony_cistatic void run(void) 116f08c3bdfSopenharmony_ci{ 117f08c3bdfSopenharmony_ci clone_unshare_test(use_clone, CLONE_NEWIPC, check_sem1); 118f08c3bdfSopenharmony_ci clone_unshare_test(use_clone, CLONE_NEWIPC, check_sem2); 119f08c3bdfSopenharmony_ci} 120f08c3bdfSopenharmony_ci 121f08c3bdfSopenharmony_cistatic void setup(void) 122f08c3bdfSopenharmony_ci{ 123f08c3bdfSopenharmony_ci use_clone = get_clone_unshare_enum(str_op); 124f08c3bdfSopenharmony_ci} 125f08c3bdfSopenharmony_ci 126f08c3bdfSopenharmony_cistatic void cleanup(void) 127f08c3bdfSopenharmony_ci{ 128f08c3bdfSopenharmony_ci int id; 129f08c3bdfSopenharmony_ci 130f08c3bdfSopenharmony_ci id = semget(MY_KEY, 1, 0); 131f08c3bdfSopenharmony_ci if (id >= 0) { 132f08c3bdfSopenharmony_ci tst_res(TINFO, "Destroy semaphore"); 133f08c3bdfSopenharmony_ci SAFE_SEMCTL(id, IPC_RMID, 0); 134f08c3bdfSopenharmony_ci } 135f08c3bdfSopenharmony_ci} 136f08c3bdfSopenharmony_ci 137f08c3bdfSopenharmony_cistatic struct tst_test test = { 138f08c3bdfSopenharmony_ci .test_all = run, 139f08c3bdfSopenharmony_ci .setup = setup, 140f08c3bdfSopenharmony_ci .cleanup = cleanup, 141f08c3bdfSopenharmony_ci .needs_root = 1, 142f08c3bdfSopenharmony_ci .forks_child = 1, 143f08c3bdfSopenharmony_ci .needs_checkpoints = 1, 144f08c3bdfSopenharmony_ci .options = (struct tst_option[]) { 145f08c3bdfSopenharmony_ci { "m:", &str_op, "Test execution mode <clone|unshare|none>" }, 146f08c3bdfSopenharmony_ci {}, 147f08c3bdfSopenharmony_ci }, 148f08c3bdfSopenharmony_ci}; 149