diff options
Diffstat (limited to 'net/ipv4/af_inet.c')
-rw-r--r-- | net/ipv4/af_inet.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 967a47ff78a4..c31e5fa8f1a8 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -89,6 +89,7 @@ #include <linux/netfilter_ipv4.h> #include <linux/random.h> #include <linux/slab.h> +#include <linux/netfilter/xt_qtaguid.h> #include <asm/uaccess.h> @@ -121,6 +122,19 @@ #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 +274,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 +325,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; @@ -398,6 +414,9 @@ int inet_release(struct socket *sock) if (sk) { long timeout; +#ifdef CONFIG_NETFILTER_XT_MATCH_QTAGUID + qtaguid_untag(sock, true); +#endif /* Applications forget to leave groups before exiting */ ip_mc_drop_socket(sk); |