Skip to content

id: Doesn't correctly report EUID #7749

Closed
@BenWiederhake

Description

@BenWiederhake

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions