mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
dccp: fix data-race around dp->dccps_mss_cache
dccp_sendmsg() reads dp->dccps_mss_cache before locking the socket.
Same thing in do_dccp_getsockopt().
Add READ_ONCE()/WRITE_ONCE() annotations,
and change dccp_sendmsg() to check again dccps_mss_cache
after socket is locked.
Fixes: 7c657876b6
("[DCCP]: Initial implementation")
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20230803163021.2958262-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
fc2ea6ab0a
commit
a47e598fbd
@ -187,7 +187,7 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
|
||||
|
||||
/* And store cached results */
|
||||
icsk->icsk_pmtu_cookie = pmtu;
|
||||
dp->dccps_mss_cache = cur_mps;
|
||||
WRITE_ONCE(dp->dccps_mss_cache, cur_mps);
|
||||
|
||||
return cur_mps;
|
||||
}
|
||||
|
@ -630,7 +630,7 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
|
||||
return dccp_getsockopt_service(sk, len,
|
||||
(__be32 __user *)optval, optlen);
|
||||
case DCCP_SOCKOPT_GET_CUR_MPS:
|
||||
val = dp->dccps_mss_cache;
|
||||
val = READ_ONCE(dp->dccps_mss_cache);
|
||||
break;
|
||||
case DCCP_SOCKOPT_AVAILABLE_CCIDS:
|
||||
return ccid_getsockopt_builtin_ccids(sk, len, optval, optlen);
|
||||
@ -739,7 +739,7 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
|
||||
trace_dccp_probe(sk, len);
|
||||
|
||||
if (len > dp->dccps_mss_cache)
|
||||
if (len > READ_ONCE(dp->dccps_mss_cache))
|
||||
return -EMSGSIZE;
|
||||
|
||||
lock_sock(sk);
|
||||
@ -772,6 +772,12 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
goto out_discard;
|
||||
}
|
||||
|
||||
/* We need to check dccps_mss_cache after socket is locked. */
|
||||
if (len > dp->dccps_mss_cache) {
|
||||
rc = -EMSGSIZE;
|
||||
goto out_discard;
|
||||
}
|
||||
|
||||
skb_reserve(skb, sk->sk_prot->max_header);
|
||||
rc = memcpy_from_msg(skb_put(skb, len), msg, len);
|
||||
if (rc != 0)
|
||||
|
Loading…
Reference in New Issue
Block a user