1 /*
2 * Copyright (c) International Business Machines Corp., 2001
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 * the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 /*
19 * DESCRIPTION
20 * Check if setuid behaves correctly with file permissions. The test
21 * creates a file as ROOT with permissions 0644, does a setuid and then
22 * tries to open the file with RDWR permissions. The same test is done
23 * in a fork to check if new UIDs are correctly passed to the son.
24 */
25
26 #include <errno.h>
27 #include <pwd.h>
28 #include <unistd.h>
29 #include <sys/types.h>
30 #include <fcntl.h>
31 #include "tst_test.h"
32 #include "compat_tst_16.h"
33
34 #define FILENAME "setuid04_testfile"
35
36 static void dosetuid(void);
37
verify_setuid(void)38 static void verify_setuid(void)
39 {
40 pid_t pid;
41
42 pid = SAFE_FORK();
43 if (!pid)
44 dosetuid();
45 else
46 dosetuid();
47 }
48
dosetuid(void)49 static void dosetuid(void)
50 {
51 int tst_fd;
52
53 TEST(tst_fd = open(FILENAME, O_RDWR));
54 if (TST_RET != -1) {
55 tst_res(TFAIL, "open() succeeded unexpectedly");
56 close(tst_fd);
57 return;
58 }
59
60 if (TST_ERR == EACCES)
61 tst_res(TPASS, "open() returned errno EACCES");
62 else
63 tst_res(TFAIL | TTERRNO, "open() returned unexpected errno");
64 }
65
setup(void)66 static void setup(void)
67 {
68 struct passwd *pw;
69 uid_t uid;
70
71 pw = SAFE_GETPWNAM("nobody");
72 uid = pw->pw_uid;
73
74 UID16_CHECK(uid, setuid);
75 /* Create test file */
76 SAFE_TOUCH(FILENAME, 0644, NULL);
77
78 if (SETUID(uid) == -1) {
79 tst_brk(TBROK,
80 "setuid() failed to set the effective uid to %d", uid);
81 }
82 }
83
84 static struct tst_test test = {
85 .setup = setup,
86 .needs_root = 1,
87 .test_all = verify_setuid,
88 .needs_tmpdir = 1,
89 .forks_child = 1,
90 };
91