Linux setuid使用

一、说明

2.1 背景说明

在上家公司的时候想实现应用进程不使用root用户启动,但开发反馈像配置网卡等命令就是得用root来执行的,领导朋友说可以通过setuid解决这个问题。

一方面当时自己对setuid并不是很清楚;另一方面物联网设备毕竟是和硬件强相关的改造动作可能比较大又可能遗漏某些意想不到的地方,所以并没有着手处理root启动的问题。

2.2 setuid的作用

setuid的程序,任何用户执行时,都以setuid程序文件所属的用户的身份运行。

一般使用场景是,对归属root的程序进行setuid,以便普通用户有root用户的权限。

二、setuid实现

演示操作:setuid前普通用户不能删除root用户的文件,setuid后普通用户可以删除root用户的文件。

2.1 环境准备

将以下代码保存成test.c:

#include <stdio.h>
#include <unistd.h>

int main()
{
    printf("the uid is: %d\n", geteuid());
    sleep(5);
    // system("rm -f test.txt");
    remove("test.txt");
    return 0;
 }

将其编译成可执行文件test:

gcc test.c -o test

创建搭配使用的test.txt:

touch test.txt

最终环境如下:

Linux setuid使用

2.2 未setuid前删除文件失败

Linux setuid使用

2.3 setuid后文件删除成功

Linux setuid使用

 此时使用也可以ps看到虽是普通用户执行,但ps显示的是root用户。

Linux setuid使用

三、setuid不可用的情况

3.1 shell脚本s权限无效

由于脚本s权限会导致较大的安全隐患,所以Linux调整成了只认可二进制可执行文件的s权限,而忽略脚本类可执行文件的s权限。脚本类包括shell、python等等。

 Linux setuid使用

3.2 子进程不继承s权限

脚本类文件s权限不受认可,那么可不可以先用C写个程序赋予s权限,然后在C里通过system()等函数调用脚本,从而通过“传递”实现脚本s权限呢。

答案是不行的。不仅system()调用脚本不行,system()调用二进制可执行文件也不具有s权限。

本质原因是,system()是通过fork()建立子进程,fork()建立子进程时把子进程归属uid而归属euid。

参考:

https://unix.stackexchange.com/a/2910

http://www.faqs.org/faqs/unix-faq/faq/part4/section-7.html

相关推荐