Merge tag 'v3.10.107' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / packet / af_packet.c
index 7926934e6f0235f57ed5deb56ae84d08651f1da6..0bbb3470fa7854aabd9c0b07499945127c019901 100644 (file)
@@ -2242,7 +2242,7 @@ static int packet_snd(struct socket *sock,
        int vnet_hdr_len;
        struct packet_sock *po = pkt_sk(sk);
        unsigned short gso_type = 0;
-       int hlen, tlen;
+       int hlen, tlen, linear;
        int extra_len = 0;
 
        /*
@@ -2336,7 +2336,9 @@ static int packet_snd(struct socket *sock,
        err = -ENOBUFS;
        hlen = LL_RESERVED_SPACE(dev);
        tlen = dev->needed_tailroom;
-       skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, vnet_hdr.hdr_len,
+       linear = vnet_hdr.hdr_len;
+       linear = max(linear, min_t(int, len, dev->hard_header_len));
+       skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, linear,
                               msg->msg_flags & MSG_DONTWAIT, &err);
        if (skb == NULL)
                goto out_unlock;
@@ -2556,7 +2558,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr,
                            int addr_len)
 {
        struct sock *sk = sock->sk;
-       char name[15];
+       char name[sizeof(uaddr->sa_data) + 1];
        struct net_device *dev;
        int err = -ENODEV;
 
@@ -2566,7 +2568,11 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr,
 
        if (addr_len != sizeof(struct sockaddr))
                return -EINVAL;
-       strlcpy(name, uaddr->sa_data, sizeof(name));
+       /* uaddr->sa_data comes from the userspace, it's not guaranteed to be
+        * zero-terminated.
+        */
+       memcpy(name, uaddr->sa_data, sizeof(uaddr->sa_data));
+       name[sizeof(uaddr->sa_data)] = 0;
 
        dev = dev_get_by_name(sock_net(sk), name);
        if (dev)
@@ -3668,8 +3674,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
                if (unlikely(req->tp_block_size & (PAGE_SIZE - 1)))
                        goto out;
                if (po->tp_version >= TPACKET_V3 &&
-                   (int)(req->tp_block_size -
-                         BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0)
+                   req->tp_block_size <=
+                         BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv))
                        goto out;
                if (unlikely(req->tp_frame_size < po->tp_hdrlen +
                                        po->tp_reserve))
@@ -3698,7 +3704,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
                 */
                        if (!tx_ring)
                                init_prb_bdqc(po, rb, pg_vec, req_u, tx_ring);
-                               break;
+                       break;
                default:
                        break;
                }