Reputation: 8839
I am working in Linux and trying to execute a C program with setuid
on Linux. Here is my code:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
int main()
{
int ret;
fprintf ( stderr, "Orig: %d Effective: %d\n", getuid(), geteuid() );
ret = setuid ( 122 );
if ( ret < 0 )
{
perror ( "Problem in setuid " );
return ( 1 );
}
fprintf ( stderr, "UID : %d Effective: %d\n", getuid(), geteuid() );
execlp ( "/bin/id", "/bin/id", NULL );
fprintf ( stderr, "Problem executing execlp\n" );
return ( 0 );
}
Upon execution, the UID is not changed. The output is:
[hauschild@hoare7 ~]$ ~sanjiv/bin/a.out
Orig: 155 Effective: 122
UID : 155 Effective: 122
uid=155(hauschild) gid=100(users) euid=122(sanjiv) groups=100(users)
[hauschild@hoare7 ~]$
I have looked at other questions in SO but unable to figure this one out. The permissions on executable are rwsr-sr-x
. Notice how the code runs to completion and the exit status is reported as 0
. However, when I run it through strace
, it gives me an error on setuid
and exists with a 1
. as follows:
geteuid() = 155
getuid() = 155
write(2, "Orig: 155 Effective: 155\n", 27Orig: 155 Effective: 155
) = 27
setuid(122) = -1 EPERM (Operation not permitted)
write(2, "Problem in setuid : Operation n"..., 45Problem in setuid : Operation not permitted
) = 45
exit_group(1) = ?
+++ exited with 1 +++
Can anyone see what I could be doing wrong?
Upvotes: 0
Views: 1689
Reputation: 780974
In POSIX and Linux, setuid()
only sets the effective UID of the process, unless the effective UID is root, in which case it also sets the real UID and the saved set-user-ID. To set the real UID, use setreuid()
. BSD setuid
sets all of them regardless of the effective UID of the process.
To set the real UID, use setreuid
:
ret = setreuid(122, 122);
Upvotes: 5