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