mirror of https://github.com/OpenIPC/firmware.git
166 lines
4.3 KiB
Diff
166 lines
4.3 KiB
Diff
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 <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.
|
|
@@ -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();
|