kobject_uevent,uevent_helper,/sys/kernel/uevent_helper,/proc/sys/kernel/hotplug

本文深入解析了Linux内核中UEVENT_HELPER的实现机制及其应用场景,包括/sys/kernel/uevent_helper和/proc/sys/kernel/hotplug文件的操作方式。通过具体代码示例介绍了如何通过这些文件配置UEVENT_HELPER来触发用户空间的事件处理程序。
class_device_create
	class_device_register
		class_device_add
			kobject_uevent(&class_dev->kobj, KOBJ_ADD);
				kobject_uevent_env
					action_string = action_to_string(action);

					uevent_ops->filter
					subsystem = uevent_ops->name(kset, kobj);

					envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
					buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
					
					devpath = kobject_get_path(kobj, GFP_KERNEL);
					
					envp[i++] = "HOME=/";...
					
					#if defined(CONFIG_NET)
					/* send netlink message */
					
					if (uevent_helper[0]) {
						char *argv [3];

						argv [0] = uevent_helper;
						argv [1] = (char *)subsystem;
						argv [2] = NULL;
						call_usermodehelper (argv[0], argv, envp, 0);
					}

关于uevent_helper(在Source Insight中搜索)
1.对/sys/kernel/uevent_helper 文件的读写就是对uevent_helper的读写
	linux/kernel/ksysfs.c
	
static ssize_t uevent_helper_show(struct kset *kset, char *page)
{
	return sprintf(page, "%s\n", uevent_helper);
}
static ssize_t uevent_helper_store(struct kset *kset, const char *page, size_t count)
{
	if (count+1 > UEVENT_HELPER_PATH_LEN)
		return -ENOENT;
	memcpy(uevent_helper, page, count);
	uevent_helper[count] = '\0';
	if (count && uevent_helper[count-1] == '\n')
		uevent_helper[count-1] = '\0';
	return count;
}

KERNEL_ATTR_RW(uevent_helper);//声明一个subsys_attribute变量 uevent_helper_attr
				//它对应sysfs 中的一个文件,文件名是uevent_helper
				//它的读写函数分别是uevent_helper_show,uevent_helper_store
	#define KERNEL_ATTR_RW(_name) \
		static struct subsys_attribute _name##_attr = __ATTR(_name, 0644, _name##_show, _name##_store)
			#define __ATTR(_name,_mode,_show,_store) { \
				.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },	\
				.show	= _show,					\
				.store	= _store,					\
			}

int error = subsystem_register(&kernel_subsys);//注册子系统
	//kernel_subsys的创建使用decl_subsys宏
	decl_subsys(kernel, NULL, NULL);//创建了/sys/kernel目录

error = sysfs_create_group(&kernel_subsys.kobj,&kernel_attr_group);//在子系统中创建一组文件
	static struct attribute_group kernel_attr_group = {
		.attrs = kernel_attrs,
	};
		
		static struct attribute * kernel_attrs[] = {
			#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
			&uevent_seqnum_attr.attr,
			&uevent_helper_attr.attr,//uevent_helper文件
			#endif
			#ifdef CONFIG_KEXEC
			&kexec_loaded_attr.attr,
			&kexec_crash_loaded_attr.attr,
			#endif
			NULL
		};



2.对/proc/sys/kernel/hotplug 文件的读写就是对uevent_helper的读写
	/linux/kernel/sysctl.c
	#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
	{
		.ctl_name	= KERN_HOTPLUG,
		.procname	= "hotplug",//创建/proc/sys/kernel/hotplug文件
		.data		= &uevent_helper,//对文件读写的数据对象,读写/proc/sys/kernel/hotplug就是对uevent_helper的读写
		.maxlen		= UEVENT_HELPER_PATH_LEN,
		.mode		= 0644,
		.proc_handler	= &proc_dostring,
		.strategy	= &sysctl_string,
	},

	

	所以,在使用mdev时,在/etc/init.d/rc.S 写入 echo "/sbin/mdev" > /proc/sys/kernel/hotplug
					和 写入 echo "/sbin/mdev" > /sys/kernel/uevent_helper作用应该是相同的

<think>我们正在处理关于SELinux策略配置的问题,特别是针对unionpnp_service使用netlink_kobject_uevent_socket的权限配置验证。根据用户提供的引用[1],我们知道LinuxNetlink通信机制的注册过程,而netlink_kobject_uevent_socket是一种用于内核与用户空间通信的套接字。用户的问题是验证SELinux策略中unionpnp_service对netlink_kobject_uevent_socket的权限配置是否正确。步骤:1.确认当前SELinux策略是否允许unionpnp_service域(domain)使用netlink_kobject_uevent_socket。2.检查相关的类型强制规则(TErules)和访问向量(AV,accessvectors)。我们可以通过以下命令来验证:首先,我们需要知道unionpnp_service的域(domain)是什么。假设我们已经知道域名为`unionpnp_service_t`(通常SELinux策略中类型后缀为_t)。然后,我们需要检查是否允许`unionpnp_service_t`域对`netlink_kobject_uevent_socket`类型的套接字有创建、绑定、发送和接收的权限。具体命令:-使用`semanage`查看策略模块:-使用`sesearch`来搜索策略规则:例如,检查允许发送netlink_kobject_uevent消息的规则:sesearch-A-sunionpnp_service_t-tnetlink_kobject_uevent_socket-csocket-psend_msg同时,我们还需要检查其他相关权限,比如创建套接字(create)、绑定(bind)等。然而,用户并没有提供具体的策略规则,所以我们需要指导用户如何检查。另外,引用[2]和[3]似乎与编译内核和Android构建有关,可能与当前问题关系不大,但考虑到用户之前的问题可能涉及内核编译,我们需要保持警惕。因此,回答将集中于如何验证SELinux策略配置。注意:在SELinux中,netlink_kobject_uevent_socket对应的类型通常为`netlink_kobject_uevent_socket_t`,但具体名称可能因策略而异。我们可以通过查看套接字的安全上下文来确认。操作步骤:1.查看unionpnp_service进程的域(安全上下文):`ps-eZ|grepunionpnp_service`2.查看netlink_kobject_uevent套接字的安全上下文:通常,我们可以先找到netlink套接字的文件描述符(在/proc/<pid>/fd/下),然后用`ls-Z`查看上下文。但更直接的是,我们可以查看策略文件中定义的套接字类型。3.使用`sesearch`检查策略中是否允许从unionpnp_service域访问netlink_kobject_uevent_socket类型的套接字,以及具体的权限。假设域名是`unionpnp_service_t`,套接字类型是`netlink_kobject_uevent_socket_t`,我们可以检查:sesearch-A-sunionpnp_service_t-tnetlink_kobject_uevent_socket_t这个命令会列出所有允许从源类型(unionpnp_service_t)到目标类型(netlink_kobject_uevent_socket_t)的访问规则。我们关心的是socket类的操作,特别是:create,bind,send_msg,recv_msg等如果没有找到相关规则,则说明策略配置可能缺失,需要添加。另外,还可以检查是否有布尔值(boolean)控制该权限。但是,对于netlink_kobject_uevent_socket,通常没有预定义的布尔值。如果用户遇到权限被拒绝(avc:denied)的日志,则可以通过查看/var/log/audit/audit.log或dmesg来确认具体缺失的权限。例如:`grepavc:/var/log/audit/audit.log|grepunionpnp_service|grepnetlink_kobject_uevent`根据日志中缺失的权限,可以添加相应的SELinux策略规则。因此,验证配置的正确性需要结合策略规则和实际运行时的日志。总结步骤:a.检查进程域和套接字类型。b.使用sesearch检查策略规则。c.查看系统日志以确认是否有权限拒绝。如果用户没有看到avc拒绝消息,并且服务运行正常,那么策略配置可能是正确的。但为了确保,我们应明确检查。另外,如果用户正在开发SELinux策略,可能需要使用工具如`audit2allow`来生成规则。现在,我们可以根据以上思路回答用户问题。</think> ### SELinux策略配置验证:`unionpnp_service`访问`netlink_kobject_uevent_socket` #### 1. **确认策略是否存在** - **关键命令**: ```bash sesearch -A -s unionpnp_service_t -t netlink_kobject_uevent_socket_type -c socket ``` - **输出分析**: - 若返回类似 `allow unionpnp_service_t netlink_kobject_uevent_socket_type:socket { send_msg recv_msg }` 的规则,表示基础权限已配置。 - **无输出**表示策略缺失,需手动添加规则。 #### 2. **检查权限明细** - **必需权限**: - `create`:创建套接字 - `bind`:绑定地址 - `send_msg`:发送事件消息 - `recv_msg`:接收内核事件 - **验证命令**: ```bash sesearch -A -s unionpnp_service_t -t netlink_kobject_uevent_socket_type -c socket -p create,bind,send_msg,recv_msg ``` #### 3. **通过日志实时诊断** - **模拟操作并监控日志**: ```bash # 1. 清空审计日志 echo > /var/log/audit/audit.log # 2. 重启 unionpnp_service systemctl restart unionpnp_service # 3. 检查拒绝日志 ausearch -m avc -ts recent | grep unionpnp_service | grep netlink_kobject_uevent ``` - **日志示例**: ``` avc: denied { send_msg } for pid=1234 comm="unionpnp" scontext=system_u:system_r:unionpnp_service_t tcontext=system_u:system_r:kernel_t tclass=netlink_kobject_uevent_socket ``` *表示缺少 `send_msg` 权限*[^1]。 #### 4. **策略修正方法** - **修复缺失权限**(例如缺少 `send_msg`): ```bash # 生成.te规则文件 grep unionpnp_service /var/log/audit/audit.log | audit2allow -m unionpnp > unionpnp.te # 编译并加载模块 checkmodule -M -m -o unionpnp.mod unionpnp.te semodule_package -o unionpnp.pp -m unionpnp.mod semodule -i unionpnp.pp ``` #### 5. **完整性验证** - **生效后测试**: ```bash # 检查AVC日志是否出现新拒绝 ausearch -m avc -ts recent | grep netlink_kobject_uevent # 验证服务功能 systemctl status unionpnp_service --no-pager -l ``` #### 重要提示 - **上下文匹配**:确保服务进程的上下文为 `unionpnp_service_t`(可通过 `ps -eZ | grep unionpnp` 确认)。 - **套接字类型**:确认目标套接字类型为 `netlink_kobject_uevent_socket_type`(参考内核文档)[^1]。 - **策略模式**:Enforcing模式下拒绝行为才会触发审计日志。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值