简体   繁体   中英

syscall(SYS_getuid) returns different result from getuid()

I would like to use syscalls to get the id of the current user. I tried it like this:

#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    int uid = syscall(SYS_getuid);
    
    printf("%d\n", uid);
    
    return 0;
}

I executed it with root, but it prints -1 instead of 0 .

If I replace it with int uid = syscall(SYS_getuid); , then it correctly returns 0 . What do I wrong? How to get the current user id using syscall ?

I run it on i686/ubuntu docker image, because I have to create 32bit executables.


Minimal reproducible example:

Dockerfile

FROM i686/ubuntu

RUN apt-get update
RUN apt-get install --assume-yes --no-install-recommends --quiet \
        gcc libc6-dev
RUN apt-get clean all

main.c

#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

int main(int argc, char *argv[])
{
    
    int uid = syscall(SYS_getuid);//getuid();//
    
    if(uid == -1)
        printf("Error: %s\n", strerror(errno));
    
    printf("%d\n", uid);
    
    return 0;
}

Run ( On x64 Windows10 ):

docker build --platform linux/386 -t my-gcc .
docker run --platform linux/386 --rm -v ${pwd}:/usr/local/src/:rw my-gcc gcc -m32 -xc /usr/local/src/main.c -o /usr/local/src/main
docker run --platform linux/386 --rm -v ${pwd}:/usr/local/src/:rw my-gcc /usr/local/src/main

The result is:

Error: Function not implemented
-1

Per getuid(2) :

The original Linux getuid() and geteuid() system calls supported only 16-bit user IDs. Subsequently, Linux 2.4 added getuid32() and geteuid32(), supporting 32-bit IDs. The glibc getuid() and geteuid() wrapper functions transparently deal with the variations across kernel versions.

Apparently you are running your program on a kernel that has the old getuid system call compiled out, and only getuid32 is available on x86-32. If you run fgrep CONFIG_UID16 "/boot/config-$(uname -r)" , you will be able to see if your running kernel supports the 16-bit syscall. If this command prints anything other than CONFIG_UID16=y , it means the old system call is unavailable.

If you invoke SYS_getuid32 instead, it should work fine. Note that SYS_getuid32 may fail to be available on other architectures.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM