| .. | .. |
|---|
| 171 | 171 | |
|---|
| 172 | 172 | EXPORT_SYMBOL_GPL(dccp_packet_name); |
|---|
| 173 | 173 | |
|---|
| 174 | | -static void dccp_sk_destruct(struct sock *sk) |
|---|
| 174 | +void dccp_destruct_common(struct sock *sk) |
|---|
| 175 | 175 | { |
|---|
| 176 | 176 | struct dccp_sock *dp = dccp_sk(sk); |
|---|
| 177 | 177 | |
|---|
| 178 | 178 | ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk); |
|---|
| 179 | 179 | dp->dccps_hc_tx_ccid = NULL; |
|---|
| 180 | +} |
|---|
| 181 | +EXPORT_SYMBOL_GPL(dccp_destruct_common); |
|---|
| 182 | + |
|---|
| 183 | +static void dccp_sk_destruct(struct sock *sk) |
|---|
| 184 | +{ |
|---|
| 185 | + dccp_destruct_common(sk); |
|---|
| 180 | 186 | inet_sock_destruct(sk); |
|---|
| 181 | 187 | } |
|---|
| 182 | 188 | |
|---|
| .. | .. |
|---|
| 318 | 324 | __poll_t dccp_poll(struct file *file, struct socket *sock, |
|---|
| 319 | 325 | poll_table *wait) |
|---|
| 320 | 326 | { |
|---|
| 321 | | - __poll_t mask; |
|---|
| 322 | 327 | struct sock *sk = sock->sk; |
|---|
| 328 | + __poll_t mask; |
|---|
| 329 | + u8 shutdown; |
|---|
| 330 | + int state; |
|---|
| 323 | 331 | |
|---|
| 324 | 332 | sock_poll_wait(file, sock, wait); |
|---|
| 325 | | - if (sk->sk_state == DCCP_LISTEN) |
|---|
| 333 | + |
|---|
| 334 | + state = inet_sk_state_load(sk); |
|---|
| 335 | + if (state == DCCP_LISTEN) |
|---|
| 326 | 336 | return inet_csk_listen_poll(sk); |
|---|
| 327 | 337 | |
|---|
| 328 | 338 | /* Socket is not locked. We are protected from async events |
|---|
| .. | .. |
|---|
| 331 | 341 | */ |
|---|
| 332 | 342 | |
|---|
| 333 | 343 | mask = 0; |
|---|
| 334 | | - if (sk->sk_err) |
|---|
| 344 | + if (READ_ONCE(sk->sk_err)) |
|---|
| 335 | 345 | mask = EPOLLERR; |
|---|
| 346 | + shutdown = READ_ONCE(sk->sk_shutdown); |
|---|
| 336 | 347 | |
|---|
| 337 | | - if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == DCCP_CLOSED) |
|---|
| 348 | + if (shutdown == SHUTDOWN_MASK || state == DCCP_CLOSED) |
|---|
| 338 | 349 | mask |= EPOLLHUP; |
|---|
| 339 | | - if (sk->sk_shutdown & RCV_SHUTDOWN) |
|---|
| 350 | + if (shutdown & RCV_SHUTDOWN) |
|---|
| 340 | 351 | mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; |
|---|
| 341 | 352 | |
|---|
| 342 | 353 | /* Connected? */ |
|---|
| 343 | | - if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) { |
|---|
| 354 | + if ((1 << state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) { |
|---|
| 344 | 355 | if (atomic_read(&sk->sk_rmem_alloc) > 0) |
|---|
| 345 | 356 | mask |= EPOLLIN | EPOLLRDNORM; |
|---|
| 346 | 357 | |
|---|
| 347 | | - if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { |
|---|
| 358 | + if (!(shutdown & SEND_SHUTDOWN)) { |
|---|
| 348 | 359 | if (sk_stream_is_writeable(sk)) { |
|---|
| 349 | 360 | mask |= EPOLLOUT | EPOLLWRNORM; |
|---|
| 350 | 361 | } else { /* send SIGIO later */ |
|---|
| .. | .. |
|---|
| 362 | 373 | } |
|---|
| 363 | 374 | return mask; |
|---|
| 364 | 375 | } |
|---|
| 365 | | - |
|---|
| 366 | 376 | EXPORT_SYMBOL_GPL(dccp_poll); |
|---|
| 367 | 377 | |
|---|
| 368 | 378 | int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg) |
|---|
| .. | .. |
|---|
| 633 | 643 | return dccp_getsockopt_service(sk, len, |
|---|
| 634 | 644 | (__be32 __user *)optval, optlen); |
|---|
| 635 | 645 | case DCCP_SOCKOPT_GET_CUR_MPS: |
|---|
| 636 | | - val = dp->dccps_mss_cache; |
|---|
| 646 | + val = READ_ONCE(dp->dccps_mss_cache); |
|---|
| 637 | 647 | break; |
|---|
| 638 | 648 | case DCCP_SOCKOPT_AVAILABLE_CCIDS: |
|---|
| 639 | 649 | return ccid_getsockopt_builtin_ccids(sk, len, optval, optlen); |
|---|
| .. | .. |
|---|
| 742 | 752 | |
|---|
| 743 | 753 | trace_dccp_probe(sk, len); |
|---|
| 744 | 754 | |
|---|
| 745 | | - if (len > dp->dccps_mss_cache) |
|---|
| 755 | + if (len > READ_ONCE(dp->dccps_mss_cache)) |
|---|
| 746 | 756 | return -EMSGSIZE; |
|---|
| 747 | 757 | |
|---|
| 748 | 758 | lock_sock(sk); |
|---|
| .. | .. |
|---|
| 775 | 785 | goto out_discard; |
|---|
| 776 | 786 | } |
|---|
| 777 | 787 | |
|---|
| 788 | + /* We need to check dccps_mss_cache after socket is locked. */ |
|---|
| 789 | + if (len > dp->dccps_mss_cache) { |
|---|
| 790 | + rc = -EMSGSIZE; |
|---|
| 791 | + goto out_discard; |
|---|
| 792 | + } |
|---|
| 793 | + |
|---|
| 778 | 794 | skb_reserve(skb, sk->sk_prot->max_header); |
|---|
| 779 | 795 | rc = memcpy_from_msg(skb_put(skb, len), msg, len); |
|---|
| 780 | 796 | if (rc != 0) |
|---|