1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd 4f08c3bdfSopenharmony_ci * Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, 5f08c3bdfSopenharmony_ci * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, 6f08c3bdfSopenharmony_ci * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> 7f08c3bdfSopenharmony_ci * Copyright (c) 2016 Linux Test Project 8f08c3bdfSopenharmony_ci */ 9f08c3bdfSopenharmony_ci 10f08c3bdfSopenharmony_ci#include <errno.h> 11f08c3bdfSopenharmony_ci#include <pwd.h> 12f08c3bdfSopenharmony_ci#include <mqueue.h> 13f08c3bdfSopenharmony_ci 14f08c3bdfSopenharmony_ci#include "tst_test.h" 15f08c3bdfSopenharmony_ci#include "tst_safe_posix_ipc.h" 16f08c3bdfSopenharmony_ci 17f08c3bdfSopenharmony_ci#define QUEUE_NAME "/test_mqueue" 18f08c3bdfSopenharmony_ci 19f08c3bdfSopenharmony_cistatic uid_t euid; 20f08c3bdfSopenharmony_cistatic struct passwd *pw; 21f08c3bdfSopenharmony_ci 22f08c3bdfSopenharmony_cistruct test_case { 23f08c3bdfSopenharmony_ci int as_nobody; 24f08c3bdfSopenharmony_ci char *qname; 25f08c3bdfSopenharmony_ci int ret; 26f08c3bdfSopenharmony_ci int err; 27f08c3bdfSopenharmony_ci}; 28f08c3bdfSopenharmony_ci 29f08c3bdfSopenharmony_cistatic struct test_case tcase[] = { 30f08c3bdfSopenharmony_ci { 31f08c3bdfSopenharmony_ci .qname = QUEUE_NAME, 32f08c3bdfSopenharmony_ci .ret = 0, 33f08c3bdfSopenharmony_ci .err = 0, 34f08c3bdfSopenharmony_ci }, 35f08c3bdfSopenharmony_ci { 36f08c3bdfSopenharmony_ci .as_nobody = 1, 37f08c3bdfSopenharmony_ci .qname = QUEUE_NAME, 38f08c3bdfSopenharmony_ci .ret = -1, 39f08c3bdfSopenharmony_ci .err = EACCES, 40f08c3bdfSopenharmony_ci }, 41f08c3bdfSopenharmony_ci { 42f08c3bdfSopenharmony_ci .qname = "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 43f08c3bdfSopenharmony_ci "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 44f08c3bdfSopenharmony_ci "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 45f08c3bdfSopenharmony_ci "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 46f08c3bdfSopenharmony_ci "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 47f08c3bdfSopenharmony_ci "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 48f08c3bdfSopenharmony_ci "aaaaaaaaaaaaaaa", 49f08c3bdfSopenharmony_ci .ret = -1, 50f08c3bdfSopenharmony_ci .err = ENOENT, 51f08c3bdfSopenharmony_ci }, 52f08c3bdfSopenharmony_ci { 53f08c3bdfSopenharmony_ci .qname = "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 54f08c3bdfSopenharmony_ci "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 55f08c3bdfSopenharmony_ci "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 56f08c3bdfSopenharmony_ci "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 57f08c3bdfSopenharmony_ci "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 58f08c3bdfSopenharmony_ci "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 59f08c3bdfSopenharmony_ci "aaaaaaaaaaaaaaaa", 60f08c3bdfSopenharmony_ci .ret = -1, 61f08c3bdfSopenharmony_ci .err = ENAMETOOLONG, 62f08c3bdfSopenharmony_ci }, 63f08c3bdfSopenharmony_ci}; 64f08c3bdfSopenharmony_ci 65f08c3bdfSopenharmony_civoid setup(void) 66f08c3bdfSopenharmony_ci{ 67f08c3bdfSopenharmony_ci euid = geteuid(); 68f08c3bdfSopenharmony_ci pw = SAFE_GETPWNAM("nobody"); 69f08c3bdfSopenharmony_ci} 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_cistatic void do_test(unsigned int i) 72f08c3bdfSopenharmony_ci{ 73f08c3bdfSopenharmony_ci struct test_case *tc = &tcase[i]; 74f08c3bdfSopenharmony_ci mqd_t fd; 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_ci tst_res(TINFO, "queue name %s", tc->qname); 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_ci /* 79f08c3bdfSopenharmony_ci * When test ended with SIGTERM etc, mq descriptor is left remains. 80f08c3bdfSopenharmony_ci * So we delete it first. 81f08c3bdfSopenharmony_ci */ 82f08c3bdfSopenharmony_ci mq_unlink(QUEUE_NAME); 83f08c3bdfSopenharmony_ci 84f08c3bdfSopenharmony_ci /* prepare */ 85f08c3bdfSopenharmony_ci fd = SAFE_MQ_OPEN(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR, S_IRWXU, NULL); 86f08c3bdfSopenharmony_ci 87f08c3bdfSopenharmony_ci if (tc->as_nobody && seteuid(pw->pw_uid)) { 88f08c3bdfSopenharmony_ci tst_res(TFAIL | TERRNO, "seteuid failed"); 89f08c3bdfSopenharmony_ci goto EXIT; 90f08c3bdfSopenharmony_ci } 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_ci /* test */ 93f08c3bdfSopenharmony_ci TEST(mq_unlink(tc->qname)); 94f08c3bdfSopenharmony_ci if (TST_ERR != tc->err || TST_RET != tc->ret) { 95f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "mq_unlink returned %ld, expected %d," 96f08c3bdfSopenharmony_ci " expected errno %s (%d)", TST_RET, 97f08c3bdfSopenharmony_ci tc->ret, tst_strerrno(tc->err), tc->err); 98f08c3bdfSopenharmony_ci } else { 99f08c3bdfSopenharmony_ci tst_res(TPASS | TTERRNO, "mq_unlink returned %ld", TST_RET); 100f08c3bdfSopenharmony_ci } 101f08c3bdfSopenharmony_ci 102f08c3bdfSopenharmony_ciEXIT: 103f08c3bdfSopenharmony_ci /* cleanup */ 104f08c3bdfSopenharmony_ci if (tc->as_nobody && seteuid(euid) == -1) 105f08c3bdfSopenharmony_ci tst_res(TWARN | TERRNO, "seteuid back to %d failed", euid); 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci if (fd > 0 && close(fd)) 108f08c3bdfSopenharmony_ci tst_res(TWARN | TERRNO, "close(fd) failed"); 109f08c3bdfSopenharmony_ci 110f08c3bdfSopenharmony_ci mq_unlink(QUEUE_NAME); 111f08c3bdfSopenharmony_ci} 112f08c3bdfSopenharmony_ci 113f08c3bdfSopenharmony_cistatic struct tst_test test = { 114f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tcase), 115f08c3bdfSopenharmony_ci .test = do_test, 116f08c3bdfSopenharmony_ci .needs_root = 1, 117f08c3bdfSopenharmony_ci .setup = setup, 118f08c3bdfSopenharmony_ci}; 119