我写了这段测试代码,发现这个程序在运行时取消了读取权限后,总能成功读取文件getchar()
。
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/types.h>
int main(){
int f = open("a.txt",O_RDONLY);
uint8_t data[200];
printf("Got %d from read", pread(f, (void *)data, 200, 0));
getchar();
printf("Got %d from read", pread(f, (void *)data, 200, 0));
}
该程序打印
从阅读中得到 9
两次,即使我chmod a-r a.txt
在暂停期间使用。
我很确定我只是一个普通用户,我的进程没有 CAP_DAC_OVERRIDE;为什么第二个不pread()
返回任何错误?
我的猜测是,在进行读/写时,内核只检查打开文件描述的文件权限,它是用创建的open()
,即使我更改了底层文件系统的文件权限也不会改变。
我的猜测正确吗?
额外的问题:
如果我是对的,那么映射区域呢?
当我读/写/执行那个映射区域时,内核是否只检查页表中记录的权限?
存储在文件系统中的真正 inode 数据是否仅在创建打开文件描述和 mmap 区域时使用?
是的,权限仅在开放时间检查并记录。因此,无论您是否有可能写入文件,您都无法写入您为只读访问打开的文件描述符。
内核查询内存中的 inode 而不是存储在文件系统中的那些。它们在打开文件的引用计数上有所不同,并且挂载点获取已挂载文件的 inode。
相同的。(PROT_* 标志传递给
mmap()
等效于 O_RDWR / O_RDONLY / O_WRONLY 标志传递给open()
)。我不确定它何时可以检查页表中记录的权限:-)。据我了解你的问题:是的。
还检查索引节点权限以进行元数据操作,例如(与 O_CREAT
mkdir()
类似)。open()
并且不要忘记
chdir()
,这与任何open()
电话都不同。(或者至少,它不同于open()
当前 Linux 上的任何调用)。我不确定 SELinux 特定的权限。