I have a simple C program that does this
int
main(void)
{
printf("getuid: %d\n", getuid());
printf("geteuid: %d\n", geteuid();
return 0;
}
The owner of the executable of my program is the user "A", this executable have special permissions on user and group fields (sticky bits), and can be executed by anyone.
Here is the output with my user "A".
getuid: 1000 geteuid: 1000
Which corresponds to the id's of A.
If I run it with another user "B" I have this as output:
getuid: 1001 geteuid: 1000
So far so good since a file with SUID always runs as the user owning the file, regardless of which user issues the command.
However if I run the file with the ltrace program, I get:
getuid: 1001 geteuid: 1001
Can someone explain this behavior to me, is this normal ?
Yes, this is normal and expected behaviour. The reason for this discrepancy is due to the way the
ltrace
utility operates.When you run a program in the usual way, the operating system loads the executable into memory and starts executing it directly. If the program has the SUID bit set, the OS will run the program with the privileges of the file owner.
On the other hand,
ltrace
doesn't directly execute the target program. Instead, they use theptrace
system call to control the execution of the target program. When a process is being ptraced, the operating system ignores the SUID bit. The reason for this is security: if the SUID bit wasn't ignored, then any user could useltrace
to gain elevated privileges by tracing a SUID program.That's why when you run your program under
ltrace
, both the real UID (fromgetuid()
) and the effective UID (fromgeteuid()
) are the ID of the user running theltrace
command, not the owner of the file.This feature can be used as a safety mechanism. For instance, if you're investigating a program and you're not sure if it's safe, you can use
ltrace
to run it without worrying about the program doing anything harmful with elevated privileges.