Closed
Description
When running with UID != EUID, id
reports the wrong UID, and doesn't report the EUID at all, despite the code existing.
$ ls -l gnu_id cargo_id # Both need to be chmod'ed to be setuid.
-rwsrwsr-x 1 root root 15482872 13. Apr 18:43 cargo_id
-rwsr-sr-x 1 root root 52240 13. Apr 18:44 gnu_id
$ ./cargo_id
uid=0(root) gid=0(root) groups=0(root),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),112(bluetooth),116(lpadmin),117(scanner),132(docker),1000(user)
$ LC_ALL=C ./gnu_id
uid=1000(user) gid=1000(user) euid=0(root) egid=0(root) groups=0(root),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),112(bluetooth),116(lpadmin),117(scanner),132(docker),1000(user)
The setup is a bit difficult:
$ cargo build -p uu_id
$ ls -l target/debug/id # Make sure it's fresh
-rwxrwxr-x 2 user user 15486824 13. Apr 18:47 target/debug/id
$ cp target/debug/id cargo_id
$ cp /usr/bin/id gnu_id
$ sudo chown root: cargo_id gnu_id
$ sudo chmod +s cargo_id gnu_id
I'm not certain how to trigger this bug more easily. Another method is to exec("id")
(where "id" here is regular, i.e. without setuid) from a different setuid binary, e.g.:
// clang -Weverything -O3 run_id.c -D CALL_CARGO -o run_cargo_id
// clang -Weverything -O3 run_id.c -o run_installed_id
// sudo chown root: run_cargo_id run_installed_id
// sudo chmod +s run_cargo_id run_installed_id
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
printf("Before: UID=%u, EUID=%u\n", getuid(), geteuid());
#ifdef CALL_CARGO
printf("+ ./target/debug/id\n");
execl("./target/debug/id", "id");
#else
printf("+ /usr/bin/id\n");
execl("/usr/bin/id", "id");
#endif
return 0;
}
Example:
$ ./run_cargo_id
Before: UID=1000, EUID=0
+ ./target/debug/id
uid=0(root) gid=0(root) groups=0(root),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),112(bluetooth),116(lpadmin),117(scanner),132(docker),1000(user)
$ ./run_installed_id
Before: UID=1000, EUID=0
+ /usr/bin/id
uid=1000(user) gid=1000(user) euid=0(root) egid=0(root) Gruppen=0(root),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),112(bluetooth),116(lpadmin),117(scanner),132(docker),1000(user)
Found while reading #7696, because it didn't include a test. When fixing this issue, PLEASE include a test.
Also, that binary is HUGE, why?!
Ping @nyurik, in case you want to tackle it.