我编写了一个发送通用Netlink多播的内核模块,并使用接收它们的libmnl编写了一个userland客户端。
一切正常,但我的客户端即使不是root用户也能工作,我想阻止它。
man 7 netlink说:
Only processes with an effective UID of 0 or the CAP_NET_ADMIN capability
may send or listen to a netlink multicast group.
显然,听取此部分并非如此。我已经尝试过CentOS 5(2.6.18),CentOS 6(2.6.32)和Ubuntu 14.04(3.13)。
我知道使用GENL_ADMIN_PERM标志可以限制接收传入内核的通用netlink命令只能来自root用户,但是是否可以从内核发送只能由root接收的多播?
编辑:我在https://github.com/craig65535/mcast-exmpl分享了一些内核模块的代码,这些内核模块发送netlink多播,以及接收它们的客户端。构建说明在README.md中,但我会在这里粘贴它们。
在一个终端:
$ make
$ sudo insmod mcast-exmpl.ko
$ cd client
$ make
$ ./client
genl ctrl msg
Family ID: 26
Mcast group ID: 4
(ID可能不同)
在另一个终端中,运行将执行TCP连接的命令。 mcast-exmpl hooks通过jprobe连接,所以这样做会导致它发送netlink组播。
$ nc yahoo.com 80
^C
$
在第一个终端中,即使您没有以root用户身份运行客户端,您也会看到收到netlink多播:
mcast-exmpl msg
SEND_NUM 55555
我想修改它,以便仅在client
以root身份运行时收到多播,或者,如果失败,则确认我在Linux文档或Linux本身中发现了错误。< / p>
答案 0 :(得分:2)
首先,我不熟悉netlink IPC机制。但是,我相信我有一些有用的信息可供分享。
尽管非root用户能够接收的原因是因为this change在一段时间内对内核做了一次,这使得非root用户能够读取uevents。
查看Multicast from kernel to user space via Netlink in C,似乎内核模块可以/应该指定struct netlink_kernel_cfg
。
从LXR开始,它似乎被定义为
struct netlink_kernel_cfg {
unsigned int groups;
unsigned int flags;
void (*input)(struct sk_buff *skb);
struct mutex *cb_mutex;
int (*bind)(struct net *net, int group);
void (*unbind)(struct net *net, int group);
bool (*compare)(struct net *net, struct sock *sk);
};
Google搜索flags
属性产生this结果,表示
标志成员可以是
NL_CFG_F_NONROOT_RECV
或NL_CFG_F_NONROOT_SEND
。 设置NL_CFG_F_NONROOT_RECV
时,非超级用户可以绑定到组播组。