sin*_*ers 6 setuid permissions files
apue 的一个程序。
#include "apue.h"
#include <fcntl.h>
int main(int argc, char *argv[])
{
if(argc!=2)
err_quit("usage: a.out <pathname>");
if(access(argv[1], R_OK)<0)
err_ret("access error for %s",argv[1]);
else
printf("read access OK\n");
if (open(argv[1], O_RDONLY)) {
err_ret("open error for %s", argv[1]);
} else {
printf("open for reading OK\n");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我将它编译为一个名为的可执行文件,4-2并更改了所有者并设置了 suid,这是以下输出ls -l:
-rwsr-xr-x 1 root sinners 8490 Jan 7 18:50 4-2*
Run Code Online (Sandbox Code Playgroud)
和/etc/shadow:
-rw------- 1 root root 421 Jan 4 01:29 /etc/shadow
Run Code Online (Sandbox Code Playgroud)
但是当我运行它时:
user% ./4-2 /etc/shadow
access error for /etc/shadow: Permission denied
open error for /etc/shadow: Permission denied
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么我会收到这些access和open错误吗?
引用access() 联机帮助页:
检查是使用调用进程的真实 UID 和 GID 完成的,而不是实际尝试对文件进行操作(例如,open(2))时使用的有效 ID。这允许 set-user-ID 程序轻松确定调用用户的权限。
设置用户 ID 位使进程的有效 UID等于文件所有者,但实际用户 ID 保持不变(即保持以前的状态exec())。
您可以setreuid()用来修改进程的有效 UID 和真实 UID,也可以open()用来确定权限。我推荐第二种解决方案,特别是因为您已经打电话open()了。可以通过检查是否errno等于来EPERM判断权限不足是否是open()失败的原因。
open()在您的代码中调用失败,因为您使用返回值open()作为 if 条件。我猜调用实际上成功并返回一个有效的非零(标准输入已经取零)文件描述符,使控制进入错误处理分支。if 的错误处理分支显示EPERM错误消息,因为这是由于access()调用而发生的最后一个错误。进入错误处理分支的条件应该检查是否open()返回-1。
| 归档时间: |
|
| 查看次数: |
348 次 |
| 最近记录: |