unxnut
unxnut

Reputation: 8839

setuid not changing uid

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

Answers (1)

Barmar
Barmar

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

Related Questions