Merge branch 'linux-linaro-lsk-v4.4' into linux-linaro-lsk-v4.4-android
[firefly-linux-kernel-4.4.55.git] / net / ipv4 / af_inet.c
index 5c5db6636704daa0c49fc13e84b2c5b282a44ed3..caa6f158a0775d5dd86b6e76198dbca5290c33b0 100644 (file)
 #endif
 #include <net/l3mdev.h>
 
+#ifdef CONFIG_ANDROID_PARANOID_NETWORK
+#include <linux/android_aid.h>
+
+static inline int current_has_network(void)
+{
+       return in_egroup_p(AID_INET) || capable(CAP_NET_RAW);
+}
+#else
+static inline int current_has_network(void)
+{
+       return 1;
+}
+#endif
 
 /* The inetsw table contains everything that inet_create needs to
  * build a new socket.
@@ -260,6 +273,9 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,
        if (protocol < 0 || protocol >= IPPROTO_MAX)
                return -EINVAL;
 
+       if (!current_has_network())
+               return -EACCES;
+
        sock->state = SS_UNCONNECTED;
 
        /* Look for the requested type/protocol pair. */
@@ -308,8 +324,7 @@ lookup_protocol:
        }
 
        err = -EPERM;
-       if (sock->type == SOCK_RAW && !kern &&
-           !ns_capable(net->user_ns, CAP_NET_RAW))
+       if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW))
                goto out_rcu_unlock;
 
        sock->ops = answer->ops;
@@ -1383,6 +1398,19 @@ out:
        return pp;
 }
 
+static struct sk_buff **ipip_gro_receive(struct sk_buff **head,
+                                        struct sk_buff *skb)
+{
+       if (NAPI_GRO_CB(skb)->encap_mark) {
+               NAPI_GRO_CB(skb)->flush = 1;
+               return NULL;
+       }
+
+       NAPI_GRO_CB(skb)->encap_mark = 1;
+
+       return inet_gro_receive(head, skb);
+}
+
 int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
 {
        if (sk->sk_family == AF_INET)
@@ -1425,6 +1453,13 @@ out_unlock:
        return err;
 }
 
+static int ipip_gro_complete(struct sk_buff *skb, int nhoff)
+{
+       skb->encapsulation = 1;
+       skb_shinfo(skb)->gso_type |= SKB_GSO_IPIP;
+       return inet_gro_complete(skb, nhoff);
+}
+
 int inet_ctl_sock_create(struct sock **sk, unsigned short family,
                         unsigned short type, unsigned char protocol,
                         struct net *net)
@@ -1652,8 +1687,8 @@ static struct packet_offload ip_packet_offload __read_mostly = {
 static const struct net_offload ipip_offload = {
        .callbacks = {
                .gso_segment    = inet_gso_segment,
-               .gro_receive    = inet_gro_receive,
-               .gro_complete   = inet_gro_complete,
+               .gro_receive    = ipip_gro_receive,
+               .gro_complete   = ipip_gro_complete,
        },
 };