Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel...
[firefly-linux-kernel-4.4.55.git] / net / can / raw.c
index da99cf153b33737ce45a06e71fc89037b96096b3..a10e3338f084aaf15eb73b40d46f1f28e96aaaf7 100644 (file)
@@ -436,14 +436,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
 
                if (count > 1) {
                        /* filter does not fit into dfilter => alloc space */
-                       filter = kmalloc(optlen, GFP_KERNEL);
-                       if (!filter)
-                               return -ENOMEM;
-
-                       if (copy_from_user(filter, optval, optlen)) {
-                               kfree(filter);
-                               return -EFAULT;
-                       }
+                       filter = memdup_user(optval, optlen);
+                       if (IS_ERR(filter))
+                               return PTR_ERR(filter);
                } else if (count == 1) {
                        if (copy_from_user(&sfilter, optval, sizeof(sfilter)))
                                return -EFAULT;
@@ -655,6 +650,10 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
        err = sock_tx_timestamp(msg, sk, skb_tx(skb));
        if (err < 0)
                goto free_skb;
+
+       /* to be able to check the received tx sock reference in raw_rcv() */
+       skb_tx(skb)->prevent_sk_orphan = 1;
+
        skb->dev = dev;
        skb->sk  = sk;