mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
tcp: fix more NULL deref after prequeue changes
When I cooked commitc3658e8d0f
("tcp: fix possible NULL dereference in tcp_vX_send_reset()") I missed other spots we could deref a NULL skb_dst(skb) Again, if a socket is provided, we do not need skb_dst() to get a pointer to network namespace : sock_net(sk) is good enough. [Backport of net-next 0f85feae6b710ced3abad5b2b47d31dfcb956b62] Bug: 16355602 Change-Id: Ibe1def7979625ee7902bff2f33ec8945b9945948 Reported-by: Dann Frazier <dann.frazier@canonical.com> Bisected-by: Dann Frazier <dann.frazier@canonical.com> Tested-by: Dann Frazier <dann.frazier@canonical.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Fixes:ca777eff51
("tcp: remove dst refcount false sharing for prequeue mode") Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e80824b3dd
commit
e336f6ab76
2 changed files with 12 additions and 10 deletions
|
@ -630,6 +630,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
|
|||
arg.iov[0].iov_base = (unsigned char *)&rep;
|
||||
arg.iov[0].iov_len = sizeof(rep.th);
|
||||
|
||||
net = sk ? sock_net(sk) : dev_net(skb_dst(skb)->dev);
|
||||
#ifdef CONFIG_TCP_MD5SIG
|
||||
hash_location = tcp_parse_md5sig_option(th);
|
||||
if (!sk && hash_location) {
|
||||
|
@ -640,7 +641,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
|
|||
* Incoming packet is checked with md5 hash with finding key,
|
||||
* no RST generated if md5 hash doesn't match.
|
||||
*/
|
||||
sk1 = __inet_lookup_listener(dev_net(skb_dst(skb)->dev),
|
||||
sk1 = __inet_lookup_listener(net,
|
||||
&tcp_hashinfo, ip_hdr(skb)->daddr,
|
||||
ntohs(th->source), inet_iif(skb));
|
||||
/* don't send rst if it can't find key */
|
||||
|
@ -687,7 +688,6 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
|
|||
if (sk)
|
||||
arg.bound_dev_if = sk->sk_bound_dev_if;
|
||||
|
||||
net = dev_net(skb_dst(skb)->dev);
|
||||
arg.tos = ip_hdr(skb)->tos;
|
||||
ip_send_reply(net->ipv4.tcp_sock, skb, ip_hdr(skb)->saddr,
|
||||
&arg, arg.iov[0].iov_len);
|
||||
|
|
|
@ -831,14 +831,15 @@ static int tcp6_gro_complete(struct sk_buff *skb)
|
|||
return tcp_gro_complete(skb);
|
||||
}
|
||||
|
||||
static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
|
||||
u32 ts, struct tcp_md5sig_key *key, int rst, u8 tclass)
|
||||
static void tcp_v6_send_response(struct sock *sk, struct sk_buff *skb, u32 seq,
|
||||
u32 ack, u32 win, u32 ts,
|
||||
struct tcp_md5sig_key *key, int rst, u8 tclass)
|
||||
{
|
||||
const struct tcphdr *th = tcp_hdr(skb);
|
||||
struct tcphdr *t1;
|
||||
struct sk_buff *buff;
|
||||
struct flowi6 fl6;
|
||||
struct net *net = dev_net(skb_dst(skb)->dev);
|
||||
struct net *net = sk ? sock_net(sk) : dev_net(skb_dst(skb)->dev);
|
||||
struct sock *ctl_sk = net->ipv6.tcp_sk;
|
||||
unsigned int tot_len = sizeof(struct tcphdr);
|
||||
struct dst_entry *dst;
|
||||
|
@ -982,7 +983,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
|
|||
ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len -
|
||||
(th->doff << 2);
|
||||
|
||||
tcp_v6_send_response(skb, seq, ack_seq, 0, 0, key, 1, 0);
|
||||
tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, key, 1, 0);
|
||||
|
||||
#ifdef CONFIG_TCP_MD5SIG
|
||||
release_sk1:
|
||||
|
@ -993,10 +994,11 @@ release_sk1:
|
|||
#endif
|
||||
}
|
||||
|
||||
static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts,
|
||||
static void tcp_v6_send_ack(struct sock *sk, struct sk_buff *skb,
|
||||
u32 seq, u32 ack, u32 win, u32 ts,
|
||||
struct tcp_md5sig_key *key, u8 tclass)
|
||||
{
|
||||
tcp_v6_send_response(skb, seq, ack, win, ts, key, 0, tclass);
|
||||
tcp_v6_send_response(sk, skb, seq, ack, win, ts, key, 0, tclass);
|
||||
}
|
||||
|
||||
static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
|
||||
|
@ -1004,7 +1006,7 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
|
|||
struct inet_timewait_sock *tw = inet_twsk(sk);
|
||||
struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
|
||||
|
||||
tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
|
||||
tcp_v6_send_ack(sk, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
|
||||
tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
|
||||
tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw),
|
||||
tw->tw_tclass);
|
||||
|
@ -1015,7 +1017,7 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
|
|||
static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
|
||||
struct request_sock *req)
|
||||
{
|
||||
tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent,
|
||||
tcp_v6_send_ack(sk, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent,
|
||||
tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr), 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue