1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) Linux Test Project, 2020 4 * Copyright (c) Wipro Technologies Ltd, 2002 5 */ 6 7/* 8 * This is an error test for ioperm(2) system call. 9 * 10 * Verify that 11 * 1) ioperm(2) returns -1 and sets errno to EINVAL for I/O port 12 * address greater than 0x3ff. 13 * 2) ioperm(2) returns -1 and sets errno to EPERM if the current 14 * user is not the super-user. 15 * 16 * Author: Subhab Biswas <subhabrata.biswas@wipro.com> 17 */ 18 19#include <stdlib.h> 20#include <errno.h> 21#include <unistd.h> 22#include <pwd.h> 23#include "tst_test.h" 24#include "tst_safe_macros.h" 25 26#if defined __i386__ || defined(__x86_64__) 27#include <sys/io.h> 28 29#define NUM_BYTES 3 30#ifndef IO_BITMAP_BITS 31#define IO_BITMAP_BITS 1024 /* set to default value since some H/W may not support 0x10000 even with a 2.6.8 kernel */ 32#define IO_BITMAP_BITS_16 65536 33#endif 34 35static struct tcase_t { 36 long from; 37 long num; 38 int turn_on; 39 char *desc; 40 int exp_errno; 41} tcases[] = { 42 {0, NUM_BYTES, 1, "Invalid I/O address", EINVAL}, 43 {0, NUM_BYTES, 1, "Non super-user", EPERM}, 44}; 45 46static void setup(void) 47{ 48 tcases[0].from = (IO_BITMAP_BITS_16 - NUM_BYTES) + 1; 49 tcases[1].from = IO_BITMAP_BITS_16 - NUM_BYTES; 50 51 struct passwd *pw; 52 pw = SAFE_GETPWNAM("nobody"); 53 SAFE_SETEUID(pw->pw_uid); 54} 55 56static void cleanup(void) 57{ 58 SAFE_SETEUID(0); 59} 60 61static void verify_ioperm(unsigned int i) 62{ 63 TEST(ioperm(tcases[i].from, tcases[i].num, tcases[i].turn_on)); 64 65 if ((TST_RET == -1) && (TST_ERR == tcases[i].exp_errno)) { 66 tst_res(TPASS | TTERRNO, "Expected failure for %s, " 67 "errno: %d", tcases[i].desc, TST_ERR); 68 } else { 69 tst_res(TFAIL | TTERRNO, "Unexpected results for %s ; " 70 "returned %ld (expected -1), errno %d " 71 "(expected errno %d)", tcases[i].desc, 72 TST_RET, TST_ERR, tcases[i].exp_errno); 73 } 74} 75 76static struct tst_test test = { 77 .tcnt = ARRAY_SIZE(tcases), 78 .test = verify_ioperm, 79 .needs_root = 1, 80 /* ioperm() is restricted under kernel lockdown. */ 81 .skip_in_lockdown = 1, 82 .setup = setup, 83 .cleanup = cleanup, 84}; 85 86#else 87TST_TEST_TCONF("LSB v1.3 does not specify ioperm() for this architecture. (only for i386 or x86_64)"); 88#endif /* __i386_, __x86_64__*/ 89