Linux内核启动后动态设置变量属性为ro

在Linux内核中,若要在启动后动态将模块参数的属性设置为只读(ro),可以通过修改sysfs中对应文件的权限来实现。以下是具体步骤:

方法概述

  1. 定位模块参数:找到模块参数对应的sysfs属性结构。
  2. 修改权限:使用内核API sysfs_chmod_file 动态更改文件权限为只读。

实现步骤

  1. 定义模块参数:使用 module_param 宏声明参数并设置初始权限。
  2. 模块初始化时修改权限
    • 获取模块的kobject。
    • 遍历模块参数属性,找到目标参数。
    • 调用 sysfs_chmod_file 修改权限。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <linux/module.h>
#include <linux/sysfs.h>

static int my_param = 0;
module_param(my_param, int, 0644); // 初始为可读写

static int __init my_module_init(void)
{
struct module *mod = THIS_MODULE;
struct kobject *kobj = &mod->mkobj.kobj;
int err = 0;

#ifdef CONFIG_SYSFS
if (mod->param_attrs) {
struct module_param_attrs *param_attrs = mod->param_attrs;
struct attribute **attrs = param_attrs->grp.attrs;
int i;

for (i = 0; attrs[i] != NULL; i++) {
if (strcmp(attrs[i]->name, "my_param") == 0) {
// 修改权限为只读
err = sysfs_chmod_file(kobj, attrs[i], 0444);
if (err)
pr_err("Failed to set my_param to ro: %d\n", err);
else
pr_info("my_param is now read-only\n");
break;
}
}
}
#endif

return 0;
}

module_init(my_module_init);

MODULE_LICENSE("GPL");

注意事项

  • 内核版本兼容性:确保使用的内核版本支持 sysfs_chmod_file 函数及相关的结构体。
  • 模块参数遍历:正确遍历模块参数属性数组,确保找到目标参数。
  • 错误处理:检查函数返回值,处理可能的错误情况。
  • 用户空间限制:此方法仅限制通过sysfs的修改,内核代码仍可更改变量。若需内核级保护,需另寻方法(如内存页保护,但风险较高)。

通过上述方法,可以在模块加载后将指定的参数动态设置为只读,增强系统的安全性和稳定性。