OpenBSD 7.5中SCM_RIGHTS类功能实现内核相关问题咨询
实现OpenBSD 7.5风格SCM_RIGHTS功能的内核代码指南
核心概念回顾
SCM_RIGHTS是和cmsg_type配合的宏,用于UNIX域套接字的控制消息中,实现跨进程传递文件描述符——本质是通过控制消息携带fd的引用,在接收端为目标进程分配新的fd并关联到同一内核文件对象。
需要查看的核心内核文件
sys/sys/socket.h:定义了SCM_RIGHTS宏、cmsghdr控制消息头结构体,是整个控制消息机制的基础定义,先搞清楚这里的结构逻辑。sys/net/unix.c:UNIX域套接字的核心实现文件,unix_sendmsg和unix_recvmsg函数里包含了SCM_RIGHTS的完整处理流程,是重点。sys/sys/uio.h:定义iovec、msghdr等套接字消息传递的基础数据结构,理解这些才能看懂消息怎么在用户态和内核态之间流转。sys/kern/uipc_socket.c:通用套接字层的sendmsg/recvmsg入口,能帮你梳理从用户态调用到具体域套接字实现的整体流程。sys/kern/kern_descrip.c:文件描述符管理的核心代码,比如fget(获取fd的内核对象引用)、fdrop(释放引用),传递fd的核心就是操作这些引用计数。
代码入手步骤
- 先啃
sys/sys/socket.h:重点看cmsghdr结构体和SCM_RIGHTS的定义,以及msghdr里的msg_control字段——控制消息就是通过这个字段从用户态传入内核,再从内核传递到接收端用户态的。
核心结构示例:struct cmsghdr { socklen_t cmsg_len; /* 包含头部的数据总字节数 */ int cmsg_level; /* 协议层级,这里是SOL_SOCKET */ int cmsg_type; /* 控制消息类型,SCM_RIGHTS就对应这里 */ /* 后面跟着实际数据:u_char cmsg_data[]; */ }; - 看
unix.c里的unix_sendmsg:找到处理SCM_RIGHTS的代码块,这里会遍历用户传入的fd数组,调用fget增加内核文件对象的引用计数,然后把fd值复制到控制消息的数据区。 - 再看
unix.c里的unix_recvmsg:对应接收端逻辑,从控制消息里取出fd值,为接收进程分配一个未使用的fd,关联到同一个内核文件对象,再调整引用计数。 - 对照
kern_descrip.c的fd操作函数,搞清楚引用计数的管理逻辑——这是避免fd泄漏、保证资源正确回收的关键。
需要修改的文件
如果是新增类似SCM_RIGHTS的自定义控制消息(比如传递其他资源)
sys/sys/socket.h:新增自定义的SCM_XXX宏(比如SCM_MY_RESOURCE),注意取值不要和现有cmsg_type冲突。sys/net/unix.c:在unix_sendmsg和unix_recvmsg中添加新cmsg_type的处理分支:- 发送端:验证权限、处理要传递的资源(比如fd、句柄或自定义数据)、打包进控制消息。
- 接收端:解析控制消息、为接收进程分配对应资源的句柄、更新引用计数或关联关系。
- 若涉及新类型资源的管理,可能需要修改对应内核文件(比如传递进程句柄要改
kern_proc.c,传递信号量要改kern_sem.c)。
如果是修改现有SCM_RIGHTS的行为(比如扩展fd传递数量、增加权限检查)
- 主要修改
sys/net/unix.c中的处理逻辑:比如调整fd数组的长度限制,或者在发送前增加额外的权限验证步骤(比如检查进程是否有权限操作目标fd)。
内容的提问来源于stack exchange,提问作者seenchan
相关产品推荐
相关产品推荐

