From 3032f692e56c724f077d4a5af24106c3f4793066 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Tue, 11 Sep 2018 18:41:41 +0200 Subject: netlink: check for CAP_NET_ADMIN manually --- src/netlink.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/netlink.c b/src/netlink.c index 18bebb8..364d4d8 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -163,6 +163,7 @@ err: static int wg_get_device_start(struct netlink_callback *cb) { struct nlattr **attrs = genl_family_attrbuf(&genl_family); + struct net *dev_net = sock_net(cb->skb->sk); struct wg_device *wg; int ret; @@ -170,6 +171,8 @@ static int wg_get_device_start(struct netlink_callback *cb) genl_family.maxattr, device_policy, NULL); if (ret < 0) return ret; + if (!netlink_ns_capable(cb->skb, dev_net->user_ns, CAP_NET_ADMIN)) + return -EPERM; cb->args[2] = (long)kzalloc(sizeof(struct allowedips_cursor), GFP_KERNEL); if (unlikely(!cb->args[2])) @@ -470,9 +473,17 @@ out: static int wg_set_device(struct sk_buff *skb, struct genl_info *info) { - struct wg_device *wg = lookup_interface(info->attrs, skb); + struct net *dev_net = sock_net(skb->sk); + struct wg_device *wg; int ret; + if (!netlink_ns_capable(skb, dev_net->user_ns, CAP_NET_ADMIN)) { + ret = -EPERM; + goto out_nodev; + } + + wg = lookup_interface(info->attrs, skb); + if (IS_ERR(wg)) { ret = PTR_ERR(wg); goto out_nodev; @@ -574,12 +585,10 @@ struct genl_ops genl_ops[] = { .dumpit = wg_get_device_dump, .done = wg_get_device_done, .policy = device_policy, - .flags = GENL_UNS_ADMIN_PERM }, { .cmd = WG_CMD_SET_DEVICE, .doit = wg_set_device, .policy = device_policy, - .flags = GENL_UNS_ADMIN_PERM } }; -- cgit v1.2.3-59-g8ed1b