Pixel 8内核模块字符设备与Sysfs权限配置问题求助
Android 14(Pixel 8)内核模块:字符设备与Sysfs非root权限配置方案
一、字符设备权限问题解决
你尝试的devnode和dev_uevent方法在标准Linux内核中有效,但Android的init进程与vold服务会强制覆盖设备节点权限,需结合Android特有机制处理:
1. 修复devnode+uevent配置
确保在class_create后立即绑定devnode回调,同时添加Android专属uevent变量阻止权限重置:
static char *custom_devnode(struct device *dev, umode_t *mode) { if (mode) { *mode = S_IRUGO | S_IWUGO; // 0666权限,允许所有用户读写 } return NULL; } static int custom_dev_uevent(struct device *dev, struct kobj_uevent_env *env) { add_uevent_var(env, "DEVMODE=%#o", 0666); // 告知Android init不要强制修改设备权限 add_uevent_var(env, "SECUREMODE=0"); return 0; } // 初始化流程 new_class = class_create(THIS_MODULE, DEVICE_CLASS_NAME); if (IS_ERR(new_class)) { // 错误处理逻辑 } new_class->devnode = custom_devnode; new_class->dev_uevent = custom_dev_uevent; // 创建设备节点 device_create(new_class, NULL, MKDEV(major, minor), NULL, DEVICE_NAME);
2. 备选:通过用户组控制访问
如果上述方法无效,可直接指定设备节点归属system组(GID=1000),让非root用户加入该组即可访问:
static const struct group_info my_dev_groups = { .ngroups = 1, .groups = { 1000 }, // Android system组GID }; // 创建设备时绑定组信息 device_create_with_groups(new_class, NULL, MKDEV(major, minor), NULL, &my_dev_groups, DEVICE_NAME);
二、Sysfs权限问题解决
权限显示正确但非root用户访问被拒、无法手动修改,核心原因是Android SELinux强制访问控制,辅以sysfs属性函数的权限校验:
1. 移除属性函数的root限制
检查__ATTR对应的show/store函数,若存在capable(CAP_SYS_ADMIN)这类root校验,需移除或替换为宽松规则:
// 错误示例:仅允许root读取 static ssize_t my_sysfs_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { if (!capable(CAP_SYS_ADMIN)) { return -EPERM; } // 读取逻辑 } // 修改后:允许所有用户读取 static ssize_t my_sysfs_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { return sprintf(buf, "%d\n", my_value); }
2. 配置SELinux策略(关键)
Android默认SELinux会拦截非root用户访问自定义sysfs节点,需添加自定义策略:
- 编写策略文件
my_module.te:
# 允许普通应用读写sysfs节点 allow untrusted_app my_module_sysfs:file { read write }; # 允许系统应用读写 allow system_app my_module_sysfs:file { read write };
- 将策略编译为
.pp文件后,通过semodule -i加载到设备(需设备解锁并具备SELinux修改权限)。
3. 修正Sysfs SELinux上下文
使用ls -Z /sys/class/your_class/your_attr查看节点上下文,若不属于允许非root访问的类型,可在创建属性时手动设置:
static struct kobj_attribute my_attr = __ATTR(my_attr, 0666, my_sysfs_show, my_sysfs_store); int ret = sysfs_create_file(kobj, &my_attr.attr); if (ret == 0) { // 设置为system_sysfs上下文,允许非root访问 security_setsecctx(&my_attr.attr.kobj, "u:object_r:system_sysfs:s0", strlen("u:object_r:system_sysfs:s0")); }
内容的提问来源于stack exchange,提问作者Gal Kaptsenel
相关产品推荐
相关产品推荐

