From: David W. <dw...@in...> - 2000-08-22 19:45:04
|
jd...@ka... said: > The ethertap driver requires CAP_NET_ADMIN and ignores the bits on / > dev/tap*. I think Alexey would accept a patch that changes this. This patch does it. It looks like it's feasible to do it as non-root with PF_NETLINK sockets, but then it's available to _any_ user, which isn't much better. We need to be able to restrict it to a single user/group. Index: include/linux/netlink.h =================================================================== RCS file: /inst/cvs/linux/include/linux/netlink.h,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 netlink.h --- include/linux/netlink.h 2000/06/07 08:41:09 1.1.1.1 +++ include/linux/netlink.h 2000/08/22 19:08:11 @@ -141,6 +141,21 @@ return nlh; } +struct netlink_opt +{ + u32 pid; + unsigned groups; + u32 dst_pid; + unsigned dst_groups; + unsigned long state; + int netlink_dev; + int (*handler)(int unit, struct sk_buff *skb); + wait_queue_head_t wait; + struct netlink_callback *cb; + spinlock_t cb_lock; + void (*data_ready)(struct sock *sk, int bytes); +}; + #define NLMSG_PUT(skb, pid, seq, type, len) \ ({ if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) goto nlmsg_failure; \ __nlmsg_put(skb, pid, seq, type, len); }) Index: net/netlink/af_netlink.c =================================================================== RCS file: /inst/cvs/linux/net/netlink/af_netlink.c,v retrieving revision 1.4.2.10 diff -u -r1.4.2.10 af_netlink.c --- net/netlink/af_netlink.c 2000/07/06 15:28:51 1.4.2.10 +++ net/netlink/af_netlink.c 2000/08/22 19:31:08 @@ -46,20 +46,6 @@ #define BUG_TRAP(x) if (!(x)) { printk("Assertion (" #x ") failed at " __FILE__ "(%d):" __FUNCTION__ "\n", __LINE__); } -struct netlink_opt -{ - u32 pid; - unsigned groups; - u32 dst_pid; - unsigned dst_groups; - unsigned long state; - int (*handler)(int unit, struct sk_buff *skb); - wait_queue_head_t wait; - struct netlink_callback *cb; - spinlock_t cb_lock; - void (*data_ready)(struct sock *sk, int bytes); -}; - static struct sock *nl_table[MAX_LINKS]; static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait); @@ -309,7 +295,8 @@ return -EINVAL; /* Only superuser is allowed to listen multicasts */ - if (nladdr->nl_groups && !capable(CAP_NET_ADMIN)) + if (nladdr->nl_groups && !sk->protinfo.af_netlink->netlink_dev && + !capable(CAP_NET_ADMIN)) return -EPERM; if (sk->protinfo.af_netlink->pid) { @@ -563,7 +550,8 @@ return -EINVAL; dst_pid = addr->nl_pid; dst_groups = addr->nl_groups; - if (dst_groups && !capable(CAP_NET_ADMIN)) + if (dst_groups && !sk->protinfo.af_netlink->netlink_dev && + !capable(CAP_NET_ADMIN)) return -EPERM; } else { dst_pid = sk->protinfo.af_netlink->dst_pid; Index: net/netlink/netlink_dev.c =================================================================== RCS file: /inst/cvs/linux/net/netlink/netlink_dev.c,v retrieving revision 1.1.1.1.2.8 diff -u -r1.1.1.1.2.8 netlink_dev.c --- net/netlink/netlink_dev.c 2000/07/13 10:13:52 1.1.1.1.2.8 +++ net/netlink/netlink_dev.c 2000/08/22 19:16:24 @@ -27,6 +27,8 @@ #include <linux/init.h> #include <linux/devfs_fs_kernel.h> #include <linux/smp_lock.h> +#include <net/sock.h> +#include <linux/netlink.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -123,6 +125,7 @@ memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; nladdr.nl_groups = ~0; + sock->sk->protinfo.af_netlink->netlink_dev = 1; if ((err = sock->ops->bind(sock, (struct sockaddr*)&nladdr, sizeof(nladdr))) < 0) { sock_release(sock); goto out; -- dwmw2 |