mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
dccp: fix data-race around dp->dccps_mss_cache
commita47e598fbdupstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
00f033d451
commit
a6ddc1c774
@@ -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;
|
||||
}
|
||||
|
||||
@@ -627,7 +627,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);
|
||||
@@ -736,7 +736,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);
|
||||
@@ -769,6 +769,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)
|
||||
|
||||
Reference in New Issue
Block a user