1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Copyright (c) Kerlabs 2008.
3 * Copyright (c) International Business Machines Corp., 2008
4 * Copyright (c) 2022 SUSE LLC Avinesh Kumar <[email protected]>
5 */
6
7 /*\
8 * [Description]
9 *
10 * Verify that setresuid() behaves correctly with file permissions.
11 * The test creates a file as ROOT with permissions 0644, does a setresuid
12 * to change euid to a non-root user and tries to open the file with RDWR
13 * permissions, which should fail with EACCES errno.
14 * The same test is done in a fork also to check that child process also
15 * inherits new euid and open fails with EACCES.
16 * Test verifies the successful open action after reverting the euid back
17 * ROOT user.
18 */
19
20 #include <sys/wait.h>
21 #include <pwd.h>
22 #include "tst_test.h"
23 #include "compat_tst_16.h"
24
25 #define TEMP_FILE "testfile"
26 static char nobody_uid[] = "nobody";
27 static struct passwd *ltpuser;
28 static int fd = -1;
29
setup(void)30 static void setup(void)
31 {
32 ltpuser = SAFE_GETPWNAM(nobody_uid);
33 UID16_CHECK(ltpuser->pw_uid, "setresuid");
34
35 fd = SAFE_OPEN(TEMP_FILE, O_CREAT | O_RDWR, 0644);
36 }
37
run(void)38 static void run(void)
39 {
40 pid_t pid;
41 int status;
42
43 TST_EXP_PASS_SILENT(SETRESUID(-1, ltpuser->pw_uid, -1));
44 TST_EXP_FAIL2(open(TEMP_FILE, O_RDWR), EACCES);
45
46 pid = SAFE_FORK();
47 if (!pid) {
48 TST_EXP_FAIL2(open(TEMP_FILE, O_RDWR), EACCES);
49 return;
50 }
51 SAFE_WAITPID(pid, &status, 0);
52 if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
53 tst_res(TFAIL, "child process exited with status: %d", status);
54
55 TST_EXP_PASS_SILENT(SETRESUID(-1, 0, -1));
56 TST_EXP_FD(open(TEMP_FILE, O_RDWR));
57 SAFE_CLOSE(TST_RET);
58 }
59
cleanup(void)60 static void cleanup(void)
61 {
62 if (fd > 0)
63 SAFE_CLOSE(fd);
64 }
65
66 static struct tst_test test = {
67 .setup = setup,
68 .test_all = run,
69 .cleanup = cleanup,
70 .needs_root = 1,
71 .needs_tmpdir = 1,
72 .forks_child = 1
73 };
74