Why is effective UID still not 0? - c

So I got this code below from here. However when I follow the commands:
sudo chown root:root a.out
sudo chmod u+s a.out
It still won't run with effective uid to 0.
This is the code:
#define _POSIX_C_SOURCE 200112L // Needed with glibc (e.g., linux).
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void report (uid_t real) {
printf ("Real UID: %d Effective UID: %d\n", real, geteuid());
}
int main (void) {
uid_t real = getuid();
report(real);
seteuid(real);
report(real);
return 0;
}
The output is:
Real UID: 1000 Effective UID: 1000
Real UID: 1000 Effective UID: 1000
Where I supposed it should have been:
Real UID: 1000 Effective UID: 0
Real UID: 1000 Effective UID: 1000

The getuid function returns the real user id only. The real user id of user process is still 1000. The 1000 is stored in the real variable.
So, while calling of seteuid function you again sets the 1000 as the effective user id.But actually you have to set the 0 in that place. So only the effective user id doesn't changed.
Try the below it will works fine.
#define _POSIX_C_SOURCE 200112L // Needed with glibc (e.g., linux).
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void report (uid_t real) {
printf ("Real UID: %d Effective UID: %d\n", real, geteuid());
}
int main (void) {
uid_t real = getuid();
report(real);
seteuid(0);
report(real);
return 0;
}

Apparently as #MarkPlotnick said.
cd to the directory where that a.out is. Run df . to get the mount
point. Run mount | grep themountpoint and see what the filesystem type
and mount options are.
If there is something saying nosuid then you need to remount that part of filesystem without the nosuid flag.
This website here gives a good explanation about how to do that.

Related

Not understanding setuid

I created a VERY simple script:
//#escalate.c - a setuid utility so that we can call shutdown
//# and other things safely without needing root access. We
//# do need to:
//# gcc escalate.c -o escalate.out
//# sudo chown root:root escalate.out
//# sudo chmod 4755 escalate.out
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
int main()
{
int status;
status = setuid( 0 ); // you can set it at run time also
system("date > /tmp/date.fil");
return errno;
}
On Raspian it generates the file in /tmp, owned by the root and returns 0 as expected.
On Ubuntu 22 it created the file owned by ME and the return status is 1. What am I missing about setuid(0); ?
I tried creating, modifying the permissions and ownership etc. On Raspian it works like a charm, on Ubuntu it does not.
==================
OK - solved it myself. On Ubuntu I was running with an encrypted home and so it was mounted with nosuid set.
the problem was that the file system was mounted nosuid

setuid() returns 0 but has no effect

I have the following code:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char* argv[]) {
printf("uid=%u euid=%u\n", getuid(), geteuid());
printf("%d = setuid(euid)\n", setuid(geteuid()));
printf("uid=%u euid=%u\n", getuid(), geteuid());
}
Compiled and run this way:
val#particle:/tmp $ sudo gcc foo.c
val#particle:/tmp $ sudo chown dev-misc:dev-misc a.out
val#particle:/tmp $ sudo chmod u+s a.out
val#particle:/tmp $ ./a.out
uid=1000 euid=1006
0 = setuid(euid)
uid=1000 euid=1006
Why does the uid remain unchanged? And why does setuid report success? (according to the man page, 0 means success)
setuid() sets the effective user ID, not the real process ID. From the manual:
setuid() sets the effective user ID of the calling process. If the
effective UID of the caller is root (more precisely: if the caller
has the CAP_SETUID capability), the real UID and saved set-user-ID
are also set.
To be able to change real user ID, the process must have effective user ID set to 0. Since, it's not the case in your example, it doesn't change. setuid() succeeds because you are just setting it to the same effective user ID the process already has.

Effective UID doesn't behave as expected

Code
I wrote the following c program to print the real and effective uid:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
void main() {
printf("real uid: %d\n", (int) getuid());
printf("effective uid: %d\n", (int) geteuid());
}
I compiled it using gcc:
jazz#kryptonite beyond_basics $ gcc -o uid_demo.out uid_demo.c
Afterwards I changed owner and permissions as following:
jazz#kryptonite beyond_basics $ sudo chown root:root uid_demo.out
jazz#kryptonite beyond_basics $ sudo chmod u+s uid_demo.out
Result
Now I got:
jazz#kryptonite beyond_basics $ ll uid_demo.out
-rwsr-xr-x 1 root root 8712 Sep 8 18:12 uid_demo.out*
When running the program I get the following result:
jazz#kryptonite beyond_basics $ ./uid_demo.out
real uid: 1000
effective uid: 1000
Question
I would expect the effective uid to be 0.
Can anyone explain why it is not?
Thanks
It is surprising, isn't it?
It's worth checking the mount options on your filesystem - it may have been mounted with the nosuid option. To inspect the options, try running the mount command, or cat /proc/mounts.
(I'm sure you know which filesystem you are in, but for completeness, if you are cd'ed there, as per your example, you can use df . )

setuid() C function changes euid value too?

This sample suid program
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
void main() {
int ret;
printf("uid=%d, euid=%d\n", getuid(), geteuid());
ret = setuid(1000);
printf("uid=%d, euid=%d\n", getuid(), geteuid());
}
has 'noemi' (id=1001) as owner:
sarah-$ logname
sarah
sarah-$ ls -l p.bin
-rwsr-xr-x 1 noemi noemi 7028 17 dic 10.30 p.bin
If started from user 'sarah' (id=1000) euid changes to 1000
Why? p.bin changes only uid (this should have no effect, since uid was 1000 when p.bin was started by 'sarah'):
sarah-$ ./p.bin
uid=1000, euid=1001
uid=1000, euid=1000
sarah-$
I am using Debian 6 64 bit.
Please help me understand.
Thank you
Check man 2 setuid:
setuid() sets the effective user ID of the calling process. If the effective UID of the caller
is root, the real UID and saved set-user-ID are also set.
So, as you already have observed, when you are executing setuid() as regular user it will only change the effective user id.

Why my own suid-ed program still holds the original uid?

I'm using the following program, and I've suid-ed it (by running chown root XXX; chmod 4755 XXX as root), but the output is still ruid 1000, euid 1000, suid 1000, shouldn't effect uid be zero here?
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
int main()
{
uid_t ruid, euid, suid;
if (! getresuid (&ruid, &euid, &suid))
printf ("ruid %d, euid %d, suid %d\n", ruid, euid, suid);
else
perror ("getresuid");
return 0;
}
Output of ls -l:
-rwsr-xr-x 1 root root 9.7K May 1 11:36 test*
Please check the mount command output, your file system could be mounted with nosuid option.
From mount man page
nosuid: Do not allow set-user-identifier or set-group-identifier bits
to take effect.

Resources