hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/dccp/proto.c
....@@ -171,12 +171,18 @@
171171
172172 EXPORT_SYMBOL_GPL(dccp_packet_name);
173173
174
-static void dccp_sk_destruct(struct sock *sk)
174
+void dccp_destruct_common(struct sock *sk)
175175 {
176176 struct dccp_sock *dp = dccp_sk(sk);
177177
178178 ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
179179 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);
180186 inet_sock_destruct(sk);
181187 }
182188
....@@ -318,11 +324,15 @@
318324 __poll_t dccp_poll(struct file *file, struct socket *sock,
319325 poll_table *wait)
320326 {
321
- __poll_t mask;
322327 struct sock *sk = sock->sk;
328
+ __poll_t mask;
329
+ u8 shutdown;
330
+ int state;
323331
324332 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)
326336 return inet_csk_listen_poll(sk);
327337
328338 /* Socket is not locked. We are protected from async events
....@@ -331,20 +341,21 @@
331341 */
332342
333343 mask = 0;
334
- if (sk->sk_err)
344
+ if (READ_ONCE(sk->sk_err))
335345 mask = EPOLLERR;
346
+ shutdown = READ_ONCE(sk->sk_shutdown);
336347
337
- if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == DCCP_CLOSED)
348
+ if (shutdown == SHUTDOWN_MASK || state == DCCP_CLOSED)
338349 mask |= EPOLLHUP;
339
- if (sk->sk_shutdown & RCV_SHUTDOWN)
350
+ if (shutdown & RCV_SHUTDOWN)
340351 mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
341352
342353 /* Connected? */
343
- if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) {
354
+ if ((1 << state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) {
344355 if (atomic_read(&sk->sk_rmem_alloc) > 0)
345356 mask |= EPOLLIN | EPOLLRDNORM;
346357
347
- if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
358
+ if (!(shutdown & SEND_SHUTDOWN)) {
348359 if (sk_stream_is_writeable(sk)) {
349360 mask |= EPOLLOUT | EPOLLWRNORM;
350361 } else { /* send SIGIO later */
....@@ -362,7 +373,6 @@
362373 }
363374 return mask;
364375 }
365
-
366376 EXPORT_SYMBOL_GPL(dccp_poll);
367377
368378 int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
....@@ -633,7 +643,7 @@
633643 return dccp_getsockopt_service(sk, len,
634644 (__be32 __user *)optval, optlen);
635645 case DCCP_SOCKOPT_GET_CUR_MPS:
636
- val = dp->dccps_mss_cache;
646
+ val = READ_ONCE(dp->dccps_mss_cache);
637647 break;
638648 case DCCP_SOCKOPT_AVAILABLE_CCIDS:
639649 return ccid_getsockopt_builtin_ccids(sk, len, optval, optlen);
....@@ -742,7 +752,7 @@
742752
743753 trace_dccp_probe(sk, len);
744754
745
- if (len > dp->dccps_mss_cache)
755
+ if (len > READ_ONCE(dp->dccps_mss_cache))
746756 return -EMSGSIZE;
747757
748758 lock_sock(sk);
....@@ -775,6 +785,12 @@
775785 goto out_discard;
776786 }
777787
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
+
778794 skb_reserve(skb, sk->sk_prot->max_header);
779795 rc = memcpy_from_msg(skb_put(skb, len), msg, len);
780796 if (rc != 0)