|
18 | 18 | #define __NR_getresuid 148 |
19 | 19 | #define __NR_getresgid 150 |
20 | 20 | #define __NR_setreuid 145 |
| 21 | +#define __NR_setfsuid 151 |
| 22 | +#define __NR_setfsgid 152 |
21 | 23 | #define __NR_capset 91 |
22 | 24 | #define __NR_setpriority 140 |
23 | 25 | #define __NR_getpriority 141 |
@@ -119,6 +121,39 @@ int main(void) |
119 | 121 | TEST("setgid(0) returns -EPERM"); |
120 | 122 | EXPECT_TRUE(raw_syscall1(__NR_setgid, 0) == -1, "expected -EPERM"); |
121 | 123 |
|
| 124 | + /* setfsuid / setfsgid: Linux contract is to return the previous fsuid / |
| 125 | + * fsgid. elfuse reports the current euid / egid (1000) on every call, |
| 126 | + * with no state mutation, which is what procps relies on when it |
| 127 | + * brackets /proc reads with setfsuid(uid) / setfsuid(0). |
| 128 | + */ |
| 129 | + TEST("setfsuid(0) returns 1000"); |
| 130 | + EXPECT_TRUE(raw_syscall1(__NR_setfsuid, 0) == 1000, |
| 131 | + "setfsuid(0) did not return current euid"); |
| 132 | + |
| 133 | + TEST("setfsuid(1000) returns 1000"); |
| 134 | + EXPECT_TRUE(raw_syscall1(__NR_setfsuid, 1000) == 1000, |
| 135 | + "setfsuid(1000) did not return current euid"); |
| 136 | + |
| 137 | + TEST("setfsgid(0) returns 1000"); |
| 138 | + EXPECT_TRUE(raw_syscall1(__NR_setfsgid, 0) == 1000, |
| 139 | + "setfsgid(0) did not return current egid"); |
| 140 | + |
| 141 | + TEST("setfsgid(1000) returns 1000"); |
| 142 | + EXPECT_TRUE(raw_syscall1(__NR_setfsgid, 1000) == 1000, |
| 143 | + "setfsgid(1000) did not return current egid"); |
| 144 | + |
| 145 | + /* setfsuid(-1) / setfsgid(-1) is the canonical glibc "read fsuid without |
| 146 | + * changing it" idiom: -1 is never a valid uid, so the kernel only |
| 147 | + * reports the current fsuid. |
| 148 | + */ |
| 149 | + TEST("setfsuid(-1) reports current fsuid"); |
| 150 | + EXPECT_TRUE(raw_syscall1(__NR_setfsuid, (long) (unsigned) -1) == 1000, |
| 151 | + "setfsuid(-1) did not report current euid"); |
| 152 | + |
| 153 | + TEST("setfsgid(-1) reports current fsgid"); |
| 154 | + EXPECT_TRUE(raw_syscall1(__NR_setfsgid, (long) (unsigned) -1) == 1000, |
| 155 | + "setfsgid(-1) did not report current egid"); |
| 156 | + |
122 | 157 | /* capset: unprivileged process cannot set capabilities */ |
123 | 158 | TEST("capset returns -EPERM"); |
124 | 159 | { |
|
0 commit comments