diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5425d7b100ee..6469b741cf5a 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -117,6 +117,21 @@ static u32 tcp_v6_init_ts_off(const struct net *net, const struct sk_buff *skb) | |||
117 | ipv6_hdr(skb)->saddr.s6_addr32); | 117 | ipv6_hdr(skb)->saddr.s6_addr32); |
118 | } | 118 | } |
119 | 119 | ||
120 | static int tcp_v6_pre_connect(struct sock *sk, struct sockaddr *uaddr, | ||
121 | int addr_len) | ||
122 | { | ||
123 | /* This check is replicated from tcp_v6_connect() and intended to | ||
124 | * prevent BPF program called below from accessing bytes that are out | ||
125 | * of the bound specified by user in addr_len. | ||
126 | */ | ||
127 | if (addr_len < SIN6_LEN_RFC2133) | ||
128 | return -EINVAL; | ||
129 | |||
130 | sock_owned_by_me(sk); | ||
131 | |||
132 | return BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr); | ||
133 | } | ||
134 | |||
120 | static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | 135 | static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, |
121 | int addr_len) | 136 | int addr_len) |
122 | { | 137 | { |
@@ -1925,6 +1940,7 @@ struct proto tcpv6_prot = { | |||
1925 | .name = "TCPv6", | 1940 | .name = "TCPv6", |
1926 | .owner = THIS_MODULE, | 1941 | .owner = THIS_MODULE, |
1927 | .close = tcp_close, | 1942 | .close = tcp_close, |
1943 | .pre_connect = tcp_v6_pre_connect, | ||
1928 | .connect = tcp_v6_connect, | 1944 | .connect = tcp_v6_connect, |
1929 | .disconnect = tcp_disconnect, | 1945 | .disconnect = tcp_disconnect, |
1930 | .accept = inet_csk_accept, | 1946 | .accept = inet_csk_accept, |