econet: fix CVE-2010-3850
[firefly-linux-kernel-4.4.55.git] / net / econet / af_econet.c
index dc54bd0d083ba63f9cdec105d38d05d304007357..d41ba8e56c1053a52eb22fb793a05afd45f7c55f 100644 (file)
@@ -297,23 +297,14 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 
        mutex_lock(&econet_mutex);
 
-       if (saddr == NULL) {
-               struct econet_sock *eo = ec_sk(sk);
-
-               addr.station = eo->station;
-               addr.net     = eo->net;
-               port         = eo->port;
-               cb           = eo->cb;
-       } else {
-               if (msg->msg_namelen < sizeof(struct sockaddr_ec)) {
-                       mutex_unlock(&econet_mutex);
-                       return -EINVAL;
-               }
-               addr.station = saddr->addr.station;
-               addr.net = saddr->addr.net;
-               port = saddr->port;
-               cb = saddr->cb;
-       }
+        if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) {
+                mutex_unlock(&econet_mutex);
+                return -EINVAL;
+        }
+        addr.station = saddr->addr.station;
+        addr.net = saddr->addr.net;
+        port = saddr->port;
+        cb = saddr->cb;
 
        /* Look for a device with the right network number. */
        dev = net2dev_map[addr.net];
@@ -351,7 +342,6 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
 
                eb = (struct ec_cb *)&skb->cb;
 
-               /* BUG: saddr may be NULL */
                eb->cookie = saddr->cookie;
                eb->sec = *saddr;
                eb->sent = ec_tx_done;
@@ -392,7 +382,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
                dev_queue_xmit(skb);
                dev_put(dev);
                mutex_unlock(&econet_mutex);
-               return(len);
+               return len;
 
        out_free:
                kfree_skb(skb);
@@ -637,7 +627,7 @@ static int econet_create(struct net *net, struct socket *sock, int protocol,
        eo->num = protocol;
 
        econet_insert_socket(&econet_sklist, sk);
-       return(0);
+       return 0;
 out:
        return err;
 }
@@ -671,6 +661,9 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
        err = 0;
        switch (cmd) {
        case SIOCSIFADDR:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+
                edev = dev->ec_ptr;
                if (edev == NULL) {
                        /* Magic up a new one. */
@@ -1009,7 +1002,6 @@ static int __init aun_udp_initialise(void)
        struct sockaddr_in sin;
 
        skb_queue_head_init(&aun_queue);
-       spin_lock_init(&aun_queue_lock);
        setup_timer(&ab_cleanup_timer, ab_cleanup, 0);
        ab_cleanup_timer.expires = jiffies + (HZ*2);
        add_timer(&ab_cleanup_timer);
@@ -1167,7 +1159,6 @@ static int __init econet_proto_init(void)
                goto out;
        sock_register(&econet_family_ops);
 #ifdef CONFIG_ECONET_AUNUDP
-       spin_lock_init(&aun_queue_lock);
        aun_udp_initialise();
 #endif
 #ifdef CONFIG_ECONET_NATIVE