1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2004 4f08c3bdfSopenharmony_ci * Copyright (c) Linux Test Project, 2004-2017 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ci/* 8f08c3bdfSopenharmony_ci * DESCRIPTION 9f08c3bdfSopenharmony_ci * hugeshmctl03 - check for EACCES, and EPERM errors 10f08c3bdfSopenharmony_ci * 11f08c3bdfSopenharmony_ci * ALGORITHM 12f08c3bdfSopenharmony_ci * create a large shared memory segment with root only read & write 13f08c3bdfSopenharmony_ci * permissions fork a child process 14f08c3bdfSopenharmony_ci * if child 15f08c3bdfSopenharmony_ci * set the ID of the child process to that of "ltpuser1" 16f08c3bdfSopenharmony_ci * call do_child() 17f08c3bdfSopenharmony_ci * loop if that option was specified 18f08c3bdfSopenharmony_ci * call shmctl() using three different invalid cases 19f08c3bdfSopenharmony_ci * check the errno value 20f08c3bdfSopenharmony_ci * issue a PASS message if we get EACCES or EPERM 21f08c3bdfSopenharmony_ci * otherwise, the tests fails 22f08c3bdfSopenharmony_ci * issue a FAIL message 23f08c3bdfSopenharmony_ci * call cleanup 24f08c3bdfSopenharmony_ci * if parent 25f08c3bdfSopenharmony_ci * wait for child to exit 26f08c3bdfSopenharmony_ci * remove the large shared memory segment 27f08c3bdfSopenharmony_ci * 28f08c3bdfSopenharmony_ci * HISTORY 29f08c3bdfSopenharmony_ci * 03/2001 - Written by Wayne Boyer 30f08c3bdfSopenharmony_ci * 04/2004 - Updated by Robbie Williamson 31f08c3bdfSopenharmony_ci * 32f08c3bdfSopenharmony_ci * RESTRICTIONS 33f08c3bdfSopenharmony_ci * test must be run as root 34f08c3bdfSopenharmony_ci */ 35f08c3bdfSopenharmony_ci 36f08c3bdfSopenharmony_ci#include <sys/types.h> 37f08c3bdfSopenharmony_ci#include <sys/wait.h> 38f08c3bdfSopenharmony_ci#include <limits.h> 39f08c3bdfSopenharmony_ci#include "hugetlb.h" 40f08c3bdfSopenharmony_ci 41f08c3bdfSopenharmony_cistatic size_t shm_size; 42f08c3bdfSopenharmony_cistatic int shm_id_1 = -1; 43f08c3bdfSopenharmony_cistatic struct shmid_ds buf; 44f08c3bdfSopenharmony_cistatic uid_t test_uid; 45f08c3bdfSopenharmony_cistatic char *test_user = "nobody"; 46f08c3bdfSopenharmony_ci 47f08c3bdfSopenharmony_cistatic struct tcase { 48f08c3bdfSopenharmony_ci int *shmid; 49f08c3bdfSopenharmony_ci int cmd; 50f08c3bdfSopenharmony_ci struct shmid_ds *sbuf; 51f08c3bdfSopenharmony_ci int error; 52f08c3bdfSopenharmony_ci} tcases[] = { 53f08c3bdfSopenharmony_ci /* EACCES - child has no read permission for segment */ 54f08c3bdfSopenharmony_ci {&shm_id_1, IPC_STAT, &buf, EACCES}, 55f08c3bdfSopenharmony_ci /* EPERM - IPC_SET - child doesn't have permission to change segment */ 56f08c3bdfSopenharmony_ci {&shm_id_1, IPC_SET, &buf, EPERM}, 57f08c3bdfSopenharmony_ci /* EPERM - IPC_RMID - child can not remove the segment */ 58f08c3bdfSopenharmony_ci {&shm_id_1, IPC_RMID, &buf, EPERM}, 59f08c3bdfSopenharmony_ci}; 60f08c3bdfSopenharmony_ci 61f08c3bdfSopenharmony_cistatic void do_child(void); 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_cistatic void test_hugeshmctl(void) 64f08c3bdfSopenharmony_ci{ 65f08c3bdfSopenharmony_ci pid_t pid; 66f08c3bdfSopenharmony_ci int status; 67f08c3bdfSopenharmony_ci 68f08c3bdfSopenharmony_ci switch (pid = SAFE_FORK()) { 69f08c3bdfSopenharmony_ci case 0: 70f08c3bdfSopenharmony_ci /* set the user ID of the child to the non root user */ 71f08c3bdfSopenharmony_ci SAFE_SETUID(test_uid); 72f08c3bdfSopenharmony_ci do_child(); 73f08c3bdfSopenharmony_ci exit(0); 74f08c3bdfSopenharmony_ci default: 75f08c3bdfSopenharmony_ci SAFE_WAITPID(pid, &status, 0); 76f08c3bdfSopenharmony_ci } 77f08c3bdfSopenharmony_ci} 78f08c3bdfSopenharmony_ci 79f08c3bdfSopenharmony_cistatic void do_child(void) 80f08c3bdfSopenharmony_ci{ 81f08c3bdfSopenharmony_ci unsigned int i; 82f08c3bdfSopenharmony_ci 83f08c3bdfSopenharmony_ci for (i = 0; i < ARRAY_SIZE(tcases); i++) { 84f08c3bdfSopenharmony_ci TEST(shmctl(*(tcases[i].shmid), tcases[i].cmd, tcases[i].sbuf)); 85f08c3bdfSopenharmony_ci if (TST_RET != -1) { 86f08c3bdfSopenharmony_ci tst_res(TFAIL, "shmctl succeeded " 87f08c3bdfSopenharmony_ci "unexpectedly"); 88f08c3bdfSopenharmony_ci continue; 89f08c3bdfSopenharmony_ci } 90f08c3bdfSopenharmony_ci if (TST_ERR == tcases[i].error) 91f08c3bdfSopenharmony_ci tst_res(TPASS | TTERRNO, "shmctl failed " 92f08c3bdfSopenharmony_ci "as expected"); 93f08c3bdfSopenharmony_ci else 94f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "shmctl failed " 95f08c3bdfSopenharmony_ci "unexpectedly - expect errno = " 96f08c3bdfSopenharmony_ci "%d, got", tcases[i].error); 97f08c3bdfSopenharmony_ci } 98f08c3bdfSopenharmony_ci} 99f08c3bdfSopenharmony_ci 100f08c3bdfSopenharmony_cistatic void setup(void) 101f08c3bdfSopenharmony_ci{ 102f08c3bdfSopenharmony_ci long hpage_size; 103f08c3bdfSopenharmony_ci 104f08c3bdfSopenharmony_ci if (tst_hugepages == 0) 105f08c3bdfSopenharmony_ci tst_brk(TCONF, "No enough hugepages for testing."); 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci hpage_size = SAFE_READ_MEMINFO("Hugepagesize:") * 1024; 108f08c3bdfSopenharmony_ci 109f08c3bdfSopenharmony_ci shm_size = hpage_size * tst_hugepages / 2; 110f08c3bdfSopenharmony_ci update_shm_size(&shm_size); 111f08c3bdfSopenharmony_ci shmkey = getipckey(); 112f08c3bdfSopenharmony_ci shm_id_1 = shmget(shmkey, shm_size, 113f08c3bdfSopenharmony_ci SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW); 114f08c3bdfSopenharmony_ci if (shm_id_1 == -1) 115f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "shmget"); 116f08c3bdfSopenharmony_ci 117f08c3bdfSopenharmony_ci /* get the userid for a non root user */ 118f08c3bdfSopenharmony_ci test_uid = getuserid(test_user); 119f08c3bdfSopenharmony_ci} 120f08c3bdfSopenharmony_ci 121f08c3bdfSopenharmony_cistatic void cleanup(void) 122f08c3bdfSopenharmony_ci{ 123f08c3bdfSopenharmony_ci rm_shm(shm_id_1); 124f08c3bdfSopenharmony_ci} 125f08c3bdfSopenharmony_ci 126f08c3bdfSopenharmony_cistatic struct tst_test test = { 127f08c3bdfSopenharmony_ci .needs_root = 1, 128f08c3bdfSopenharmony_ci .forks_child = 1, 129f08c3bdfSopenharmony_ci .needs_tmpdir = 1, 130f08c3bdfSopenharmony_ci .options = (struct tst_option[]) { 131f08c3bdfSopenharmony_ci {"s:", &nr_opt, "Set the number of the been allocated hugepages"}, 132f08c3bdfSopenharmony_ci {} 133f08c3bdfSopenharmony_ci }, 134f08c3bdfSopenharmony_ci .setup = setup, 135f08c3bdfSopenharmony_ci .cleanup = cleanup, 136f08c3bdfSopenharmony_ci .test_all = test_hugeshmctl, 137f08c3bdfSopenharmony_ci .hugepages = {128, TST_REQUEST}, 138f08c3bdfSopenharmony_ci}; 139