.. | .. |
---|
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) |
---|