简体   繁体   English

syscall(SYS_getuid) 从 getuid() 返回不同的结果

[英]syscall(SYS_getuid) returns different result from getuid()

I would like to use syscalls to get the id of the current user.我想使用系统调用来获取当前用户的 id。 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 .我用 root 执行它,但它打印-1而不是0

If I replace it with int uid = syscall(SYS_getuid);如果我将其替换为int uid = syscall(SYS_getuid); , then it correctly returns 0 . ,然后它正确返回0 What do I wrong?我错了什么? How to get the current user id using syscall ?如何使用syscall获取当前用户 ID?

I run it on i686/ubuntu docker image, because I have to create 32bit executables.我在i686/ubuntu docker 映像上运行它,因为我必须创建 32 位可执行文件。


Minimal reproducible example:最小的可重现示例:

Dockerfile 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 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 ):运行(在 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) :每个getuid(2)

The original Linux getuid() and geteuid() system calls supported only 16-bit user IDs.最初的 Linux getuid() 和 geteuid() 系统调用仅支持 16 位用户 ID。 Subsequently, Linux 2.4 added getuid32() and geteuid32(), supporting 32-bit IDs.随后,Linux 2.4 增加了 getuid32() 和 geteuid32(),支持 32 位 ID。 The glibc getuid() and geteuid() wrapper functions transparently deal with the variations across kernel versions. glibc getuid() 和 geteuid() 包装函数透明地处理 kernel 版本之间的变化。

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.显然,您正在 kernel 上运行程序,该程序已编译出旧的getuid系统调用,并且 x86-32 上只有getuid32可用。 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.如果您运行fgrep CONFIG_UID16 "/boot/config-$(uname -r)" ,您将能够查看您运行的 kernel 是否支持 16 位系统调用。 If this command prints anything other than CONFIG_UID16=y , it means the old system call is unavailable.如果此命令打印CONFIG_UID16=y以外的任何内容,则表示旧的系统调用不可用。

If you invoke SYS_getuid32 instead, it should work fine.如果您改为调用SYS_getuid32 ,它应该可以正常工作。 Note that SYS_getuid32 may fail to be available on other architectures.请注意, SYS_getuid32可能无法在其他架构上使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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