1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved. 4f08c3bdfSopenharmony_ci * Copyright (c) 2018 Xiao Yang <yangx.jy@cn.fujitsu.com> 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ci/* 8f08c3bdfSopenharmony_ci * AUTHOR: Madhu T L <madhu.tarikere@wipro.com> 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * DESCRIPTION 11f08c3bdfSopenharmony_ci * Verify that, 12f08c3bdfSopenharmony_ci * 1. delete_module(2) returns -1 and sets errno to ENOENT for nonexistent 13f08c3bdfSopenharmony_ci * module entry. 14f08c3bdfSopenharmony_ci * 2. delete_module(2) returns -1 and sets errno to EFAULT, if 15f08c3bdfSopenharmony_ci * module name parameter is outside program's accessible address space. 16f08c3bdfSopenharmony_ci * 3. delete_module(2) returns -1 and sets errno to EPERM, if effective 17f08c3bdfSopenharmony_ci * user id of the caller is not superuser. 18f08c3bdfSopenharmony_ci */ 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci#include <errno.h> 21f08c3bdfSopenharmony_ci#include <pwd.h> 22f08c3bdfSopenharmony_ci#include <stdio.h> 23f08c3bdfSopenharmony_ci#include <string.h> 24f08c3bdfSopenharmony_ci 25f08c3bdfSopenharmony_ci#include "tst_test.h" 26f08c3bdfSopenharmony_ci#include "lapi/syscalls.h" 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_ci#define BASEMODNAME "dummy" 29f08c3bdfSopenharmony_ci#define LONGMODNAMECHAR 'm' 30f08c3bdfSopenharmony_ci 31f08c3bdfSopenharmony_ci/* 32f08c3bdfSopenharmony_ci * From kernel internal headers: include/linux/module.h 33f08c3bdfSopenharmony_ci * include/linux/moduleparam.h 34f08c3bdfSopenharmony_ci */ 35f08c3bdfSopenharmony_ci#define MODULE_NAME_LEN (64 - sizeof(unsigned long)) 36f08c3bdfSopenharmony_ci 37f08c3bdfSopenharmony_cistatic struct passwd *ltpuser; 38f08c3bdfSopenharmony_cistatic char longmodname[MODULE_NAME_LEN]; 39f08c3bdfSopenharmony_cistatic char modname[20]; 40f08c3bdfSopenharmony_ci 41f08c3bdfSopenharmony_cistatic struct test_case_t { 42f08c3bdfSopenharmony_ci char *modname; 43f08c3bdfSopenharmony_ci int experrno; 44f08c3bdfSopenharmony_ci char *desc; 45f08c3bdfSopenharmony_ci /* 1: nobody_user 0: root_user */ 46f08c3bdfSopenharmony_ci int nobody_user; 47f08c3bdfSopenharmony_ci} tdat[] = { 48f08c3bdfSopenharmony_ci { modname, ENOENT, "nonexistent module", 0}, 49f08c3bdfSopenharmony_ci { "", ENOENT, "null terminated module name", 0}, 50f08c3bdfSopenharmony_ci { NULL, EFAULT, "module name outside program's accessible address space", 0}, 51f08c3bdfSopenharmony_ci { longmodname, ENOENT, "long module name", 0}, 52f08c3bdfSopenharmony_ci { modname, EPERM, "non-superuser", 1}, 53f08c3bdfSopenharmony_ci}; 54f08c3bdfSopenharmony_ci 55f08c3bdfSopenharmony_cistatic void do_delete_module(unsigned int n) 56f08c3bdfSopenharmony_ci{ 57f08c3bdfSopenharmony_ci struct test_case_t *tc = &tdat[n]; 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_ci if (!tc->modname) 60f08c3bdfSopenharmony_ci tc->modname = tst_get_bad_addr(NULL); 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_ci if (tc->nobody_user) 63f08c3bdfSopenharmony_ci SAFE_SETEUID(ltpuser->pw_uid); 64f08c3bdfSopenharmony_ci 65f08c3bdfSopenharmony_ci tst_res(TINFO, "test %s", tc->desc); 66f08c3bdfSopenharmony_ci TEST(tst_syscall(__NR_delete_module, tc->modname, 0)); 67f08c3bdfSopenharmony_ci if (TST_RET != -1) { 68f08c3bdfSopenharmony_ci tst_res(TFAIL, "delete_module() succeeded unexpectedly"); 69f08c3bdfSopenharmony_ci } else if (TST_ERR == tc->experrno) { 70f08c3bdfSopenharmony_ci tst_res(TPASS | TTERRNO, "delete_module() failed as expected"); 71f08c3bdfSopenharmony_ci } else { 72f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "delete_module() failed unexpectedly;" 73f08c3bdfSopenharmony_ci " expected: %s", tst_strerrno(tc->experrno)); 74f08c3bdfSopenharmony_ci } 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_ci if (tc->nobody_user) 77f08c3bdfSopenharmony_ci SAFE_SETEUID(0); 78f08c3bdfSopenharmony_ci} 79f08c3bdfSopenharmony_ci 80f08c3bdfSopenharmony_cistatic void setup(void) 81f08c3bdfSopenharmony_ci{ 82f08c3bdfSopenharmony_ci ltpuser = SAFE_GETPWNAM("nobody"); 83f08c3bdfSopenharmony_ci 84f08c3bdfSopenharmony_ci /* Initialize longmodname to LONGMODNAMECHAR character */ 85f08c3bdfSopenharmony_ci memset(longmodname, LONGMODNAMECHAR, MODULE_NAME_LEN - 1); 86f08c3bdfSopenharmony_ci 87f08c3bdfSopenharmony_ci /* Get unique module name for each child process */ 88f08c3bdfSopenharmony_ci sprintf(modname, "%s_%d", BASEMODNAME, getpid()); 89f08c3bdfSopenharmony_ci} 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_cistatic struct tst_test test = { 92f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tdat), 93f08c3bdfSopenharmony_ci .needs_root = 1, 94f08c3bdfSopenharmony_ci .setup = setup, 95f08c3bdfSopenharmony_ci .test = do_delete_module, 96f08c3bdfSopenharmony_ci}; 97