Skip to content

Commit

Permalink
dccp: fix data-race around dp->dccps_mss_cache
Browse files Browse the repository at this point in the history
commit a47e598 upstream.

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: 7c65787 ("[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>
  • Loading branch information
Eric Dumazet authored and gregkh committed Aug 16, 2023
1 parent eef72d9 commit d1f38d3
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 3 deletions.
2 changes: 1 addition & 1 deletion net/dccp/output.c
Expand Up @@ -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;
}
Expand Down
10 changes: 8 additions & 2 deletions net/dccp/proto.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit d1f38d3

Please sign in to comment.