1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
4 * Copyright (c) Linux Test Project, 2002-2023
5 */
6
7 /*\
8 * [Description]
9 *
10 * This test case checks whether swapon(2) system call returns
11 * - ENOENT when the path does not exist
12 * - EINVAL when the path exists but is invalid
13 * - EPERM when user is not a superuser
14 * - EBUSY when the specified path is already being used as a swap area
15 */
16
17 #include <pwd.h>
18
19 #include "tst_test.h"
20 #include "lapi/syscalls.h"
21 #include "libswap.h"
22
23 static uid_t nobody_uid;
24 static int do_swapoff;
25
26 static struct tcase {
27 char *err_desc;
28 int exp_errno;
29 char *path;
30 } tcases[] = {
31 {"Path does not exist", ENOENT, "./doesnotexist"},
32 {"Invalid path", EINVAL, "./notswap"},
33 {"Permission denied", EPERM, "./swapfile01"},
34 {"File already used", EBUSY, "./alreadyused"},
35 };
36
setup(void)37 static void setup(void)
38 {
39 struct passwd *nobody;
40
41 nobody = SAFE_GETPWNAM("nobody");
42 nobody_uid = nobody->pw_uid;
43
44 is_swap_supported("./tstswap");
45
46 SAFE_TOUCH("notswap", 0777, NULL);
47 make_swapfile("swapfile01", 0);
48 make_swapfile("alreadyused", 0);
49
50 if (tst_syscall(__NR_swapon, "alreadyused", 0))
51 tst_res(TWARN | TERRNO, "swapon(alreadyused) failed");
52 else
53 do_swapoff = 1;
54 }
55
cleanup(void)56 static void cleanup(void)
57 {
58 if (do_swapoff && tst_syscall(__NR_swapoff, "alreadyused"))
59 tst_res(TWARN | TERRNO, "swapoff(alreadyused) failed");
60 }
61
verify_swapon(unsigned int i)62 static void verify_swapon(unsigned int i)
63 {
64 struct tcase *tc = tcases + i;
65 if (tc->exp_errno == EPERM)
66 SAFE_SETEUID(nobody_uid);
67
68 TST_EXP_FAIL(tst_syscall(__NR_swapon, tc->path, 0), tc->exp_errno,
69 "swapon(2) fail with %s", tc->err_desc);
70
71 if (tc->exp_errno == EPERM)
72 SAFE_SETEUID(0);
73
74 if (TST_RET != -1) {
75 tst_res(TFAIL, "swapon(2) failed unexpectedly, expected: %s",
76 tst_strerrno(tc->exp_errno));
77 }
78 }
79
80 static struct tst_test test = {
81 .needs_root = 1,
82 .needs_tmpdir = 1,
83 .test = verify_swapon,
84 .tcnt = ARRAY_SIZE(tcases),
85 .setup = setup,
86 .cleanup = cleanup
87 };
88