Linux – able to write a module parameter with READ ONLY permissions

kernellinuxpermissionssysfs

I wrote the following simple linux kernel module to test the param feature:

#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");

Now when I try to echo a value to it, I get the "Permission Desnied" error, as expected:

[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

So far so good.

However, I can write to the file a using vim.

It does try to warn me with the follwing messages at the status line:

"/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

But I force the write with ! and get out of vim, and to my surprise the value of the parameter is re-written!

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

(Oriuginal value was 5 and I wrote 32 using vim).

Not only that, the value of the parameter in the module is changed as well!!:

[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]# 

What does this mean? READ Only permissions can just be overruled by a userland application like vim? What is the use of permission bits then..?

Best Answer

The /sys (sysfs) filesystem is somewhat special; many operations are not possible, for example creating or removing a file. Changing the permissions and ownership of a file or setting an ACL is permitted; that allows the system administrator to allow certain users or groups to access certain kernel entry points.

There is no special case that restricts a file that's initially read-only for everyone from being changed to being writable for some. That's what Vim does when it is thwarted in its initial attempt to save.

The permissions are the only thing that prevent the file from being written. Thus, if they're changed, the file content changes, which for a module parameter changes the parameter value inside the module.

Normally this doesn't have any security implication since only root can change the permissions on the file and root can change the value through /dev/kmem or by loading another module. It's something to keep in mind if root is restricted from loading modules or accessing physical memory directly by a security framework such as SELinux; the security framework needs to be configured to forbid problematic permission changes under /sys. If a user is given ownership of the file, they'll be able to change the permissions; to avoid this, if a specific user needs to have permission to read a parameter, don't chown the file to that user, but set an ACL (setfacl -m u:alice:r /sys/…).

Related Question