我正在写一个C程序。我需要拥有fopen
sysfs文件的root权限,我仍然需要root权限才能从中读取。但是,由于我的程序需要不断读取sysfs文件,这意味着它需要一直具有提升的权限。我想尽快放弃root权限。接受这个问题的可接受方式是什么?
我正在编写一个与sysfs交互的程序。如果我在shell上运行命令,我会使用:
myuser@mymachine:~$ sudo su
root@mymachine:/home/myhomedir# cd /sys/class/gpio
root@mymachine:/sys/class/gpio# echo 971 > export
root@mymachine:/sys/class/gpio# cat gpio971/value
0
root@mymachine:/sys/class/gpio# exit
我需要在一个可由非特权用户调用的C程序中运行这些命令。一种方法是使用fopen
,fprintf
,fscanf
等以常规方式编写程序,并让用户通过sudo
运行程序。但是,这意味着用户需要成为一个sudoer,程序将始终具有root权限。
我非常喜欢的另一个解决方案(因为用户不必添加到sudoers)是将程序的所有者更改为root,并设置setuid
位。 (我是从here)学到的。
然而,我有些疑惑。我想要做的是在程序的euid
为0时打开sysfs文件,但是立即删除所有权限(为了安全起见)。然后,既然文件已经打开,我们只需setuid()
到用户的UID。但是,虽然我不能完全确定,但这不起作用。这是我的代码的相关部分:
//At this point, due to the file permissions on the executable,
//euid = 0 and ruid = 1000. I know the following 4 lines work.
FILE *export = fopen("/sys/class/gpio/export", "wb");
fprintf(export, "971\n");
fclose(export);
FILE *sw_gpio = fopen("/sys/class/gpio971/value", "rb");
setuid(1000);
//Now euid = 1000 and ruid = 1000
int switch_val = -1;
fscanf(sw_gpio, "%d", &switch_val);
printf("Switch value: %d\n", switch_val); //-1
//Even though the only possible values in this sysfs file are 0 and 1,
//switch_val is still equal to -1
fclose(sw_gpio);
所以我似乎需要保持提升权限才能从/sys/class/gpio/gpio971/value
读取。但这正是我不想要的!这个程序需要在整个程序执行过程中轮询值,而我一直不想要root权限。
最后,为了完成,以下是我在可执行文件上设置的权限:
-rwsr-xr-x 1 root myuser 10943 Jan 1 20:17 main*
那么如何删除root权限,但继续从访问控制的sysfs文件中读取?
答案 0 :(得分:0)
我还没有使用/sysfs
尝试此操作,但即使使用普通文件,我的理解是文件 streams 在调用setuid()
后仍未保留访问权限。但是,由于我不理解的原因,文件处理。因此,如果您的系统行为类似于我的(x64上的Fedora 20),您可以使用open()
/ read()
代替fopen()
/ fscanf()
。