为什么我能够写入具有只读权限的模块参数?

为什么我能够写入具有只读权限的模块参数?

我编写了以下简单的 Linux 内核模块来测试参数功能:

#include<linux/module.h>

int a = 5;
module_param(a, int, S_IRUGO);

int f1(void){

        printk(KERN_ALERT "hello world\n");
        printk(KERN_ALERT "  value passed: %d \n", a);
        return 0;
}

void f2(void){

        printk(KERN_ALERT "value of parameter a now is:  %d \n", a);
        printk(KERN_ALERT "bye bye qworld\n");

}

module_init(f1);
module_exit(f2);


MODULE_AUTHOR("l");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("experimanting with parameters");

现在,当我尝试向它回显一个值时,我收到“Permission Desnied”错误,如预期的那样:

[root@localhost param]# insmod p.ko 
[root@localhost param]# dmesg -c
[ 7247.734491] hello world
[ 7247.734498]   value passed: 5 
[root@localhost param]# echo 32 >/sys/module/
Display all 145 possibilities? (y or n)
[root@localhost param]# echo 32 >/sys/module/p/parameters/a 
bash: /sys/module/p/parameters/a: Permission denied

到目前为止,一切都很好。

但是,我可以使用 vim 写入文件 a。

它确实尝试在状态行中使用以下消息来警告我:

"/sys/module/p/parameters/a"
"/sys/module/p/parameters/a" E667: Fsync failed
WARNING: Original file may be lost or damaged
don't quit the editor until the file is successfully written!
Press ENTER or type command to continue

但我强迫用 !退出vim,令我惊讶的是参数的值被重写了!

[root@localhost param]# vim /sys/module/p/parameters/a 
[root@localhost param]# cat /sys/module/p/parameters/a 
32

(原来的值是5,我用vim写成了32)。

不仅如此,模块中的参数值也发生了变化!!:

[root@localhost param]# rmmod p.ko
[root@localhost param]# dmesg -c
[ 7616.109704] value of parameter a now is:  32 
[ 7616.109709] bye bye qworld
[root@localhost param]# 

这是什么意思?只读权限可以被 vim 这样的用户态应用程序否决吗?那么权限位有什么用呢?

答案1

(sysfs)文件/sys系统有些特殊;许多操作是不可能的,例如创建或删除文件。允许更改文件的权限和所有权或设置 ACL;它允许系统管理员允许某些用户或组访问某些内核入口点。

没有特殊情况会限制最初对每个人只读的文件被更改为对某些人可写。这就是 Vim 在最初的保存尝试受阻时所做的事情。

权限是阻止写入文件的唯一因素。因此,如果它们发生更改,文件内容就会发生变化,这对于模块参数来说会更改模块内的参数值。

通常这没有任何安全隐患,因为只有 root 可以更改文件的权限,并且 root 可以通过/dev/kmem或加载另一个模块来更改值。如果 root 被 SELinux 等安全框架限制加载模块或直接访问物理内存,则需要记住这一点;需要配置安全框架以禁止有问题的权限更改/sys。如果用户被授予文件的所有权,他们将能够更改权限;为了避免这种情况,如果特定用户需要具有读取参数的权限,请不要将该chown文件发送给该用户,而是设置 ACL ( setfacl -m u:alice:r /sys/…)。

相关内容