diff -drupN a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c --- a/net/ipv4/af_inet.c 2018-08-06 17:23:04.000000000 +0300 +++ b/net/ipv4/af_inet.c 2022-06-12 05:28:14.000000000 +0300 @@ -89,6 +89,7 @@ #include #include #include +#include #include @@ -121,6 +122,19 @@ #endif #include +#ifdef CONFIG_ANDROID_PARANOID_NETWORK +#include + +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. @@ -255,6 +269,9 @@ static int inet_create(struct net *net, 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. */ @@ -303,8 +320,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; @@ -397,6 +413,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); @@ -566,13 +585,24 @@ int __inet_stream_connect(struct socket int err; long timeo; - if (addr_len < sizeof(uaddr->sa_family)) - return -EINVAL; + /* + * uaddr can be NULL and addr_len can be 0 if: + * sk is a TCP fastopen active socket and + * TCP_FASTOPEN_CONNECT sockopt is set and + * we already have a valid cookie for this socket. + * In this case, user can call write() after connect(). + * write() will invoke tcp_sendmsg_fastopen() which calls + * __inet_stream_connect(). + */ + if (uaddr) { + if (addr_len < sizeof(uaddr->sa_family)) + return -EINVAL; - if (uaddr->sa_family == AF_UNSPEC) { - err = sk->sk_prot->disconnect(sk, flags); - sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED; - goto out; + if (uaddr->sa_family == AF_UNSPEC) { + err = sk->sk_prot->disconnect(sk, flags); + sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED; + goto out; + } } switch (sock->state) { @@ -583,7 +613,10 @@ int __inet_stream_connect(struct socket err = -EISCONN; goto out; case SS_CONNECTING: - err = -EALREADY; + if (inet_sk(sk)->defer_connect) + err = -EINPROGRESS; + else + err = -EALREADY; /* Fall out of switch with err, set for this state */ break; case SS_UNCONNECTED: @@ -597,6 +630,9 @@ int __inet_stream_connect(struct socket sock->state = SS_CONNECTING; + if (!err && inet_sk(sk)->defer_connect) + goto out; + /* Just entered SS_CONNECTING state; the only * difference is that return value in non-blocking * case is EINPROGRESS, rather than EALREADY. @@ -1011,6 +1047,7 @@ static struct inet_protosw inetsw_array[ .flags = INET_PROTOSW_PERMANENT, }, +#ifdef CONFIG_IP_PING { .type = SOCK_DGRAM, .protocol = IPPROTO_ICMP, @@ -1018,6 +1055,7 @@ static struct inet_protosw inetsw_array[ .ops = &inet_sockraw_ops, .flags = INET_PROTOSW_REUSE, }, +#endif { .type = SOCK_RAW, @@ -1445,7 +1483,7 @@ int inet_recv_error(struct sock *sk, str { if (sk->sk_family == AF_INET) return ip_recv_error(sk, msg, len, addr_len); -#if IS_ENABLED(CONFIG_IPV6) +#if IS_ENABLED(CONFIG_IPV6) && IS_ENABLED(CONFIG_IP_PING) if (sk->sk_family == AF_INET6) return pingv6_ops.ipv6_recv_error(sk, msg, len, addr_len); #endif @@ -1782,7 +1820,9 @@ static int __init inet_init(void) if (rc) goto out_unregister_udp_proto; +#ifdef CONFIG_IP_PING rc = proto_register(&ping_prot, 1); +#endif if (rc) goto out_unregister_raw_proto; @@ -1902,15 +1942,11 @@ static int __init ipv4_proc_init(void) goto out_tcp; if (udp4_proc_init()) goto out_udp; - if (ping_proc_init()) - goto out_ping; if (ip_misc_proc_init()) goto out_misc; out: return rc; out_misc: - ping_proc_exit(); -out_ping: udp4_proc_exit(); out_udp: tcp4_proc_exit();