brcompat_mod: Check if user has CAP_NET_ADMIN in ioctl handler
[sliver-openvswitch.git] / datapath / brcompat.c
index f68b698..2113eae 100644 (file)
@@ -6,6 +6,8 @@
  * kernel, by Linus Torvalds and others.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <asm/uaccess.h>
 #include <linux/completion.h>
@@ -82,6 +84,9 @@ static int brc_add_del_bridge(char __user *uname, int add)
        struct sk_buff *request;
        char name[IFNAMSIZ];
 
+       if (!capable(CAP_NET_ADMIN))
+               return -EPERM;
+
        if (copy_from_user(name, uname, IFNAMSIZ))
                return -EFAULT;
 
@@ -194,6 +199,9 @@ static int brc_add_del_port(struct net_device *dev, int port_ifindex, int add)
        struct net_device *port;
        int err;
 
+       if (!capable(CAP_NET_ADMIN))
+               return -EPERM;
+
        port = __dev_get_by_index(&init_net, port_ifindex);
        if (!port)
                return -EINVAL;
@@ -481,7 +489,7 @@ static struct sk_buff *brc_send_command(struct sk_buff *request,
        /* Wait for reply. */
        error = -ETIMEDOUT;
        if (!wait_for_completion_timeout(&brc_done, BRC_TIMEOUT)) {
-               printk(KERN_WARNING "brcompat: timed out waiting for userspace\n");
+               pr_warn("timed out waiting for userspace\n");
                goto error;
     }
 
@@ -551,7 +559,7 @@ static int __init brc_init(void)
 err_unregister:
        genl_unregister_family(&brc_genl_family);
 error:
-       printk(KERN_EMERG "brcompat: failed to install!");
+       pr_emerg("failed to install!\n");
        return err;
 }