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