hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/dccp/proto.c
....@@ -1,12 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * net/dccp/proto.c
34 *
45 * An implementation of the DCCP protocol
56 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6
- *
7
- * This program is free software; you can redistribute it and/or modify it
8
- * under the terms of the GNU General Public License version 2 as
9
- * published by the Free Software Foundation.
107 */
118
129 #include <linux/dccp.h>
....@@ -104,7 +101,7 @@
104101 if (inet_csk(sk)->icsk_bind_hash != NULL &&
105102 !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
106103 inet_put_port(sk);
107
- /* fall through */
104
+ fallthrough;
108105 default:
109106 if (oldstate == DCCP_OPEN)
110107 DCCP_DEC_STATS(DCCP_MIB_CURRESTAB);
....@@ -174,12 +171,18 @@
174171
175172 EXPORT_SYMBOL_GPL(dccp_packet_name);
176173
177
-static void dccp_sk_destruct(struct sock *sk)
174
+void dccp_destruct_common(struct sock *sk)
178175 {
179176 struct dccp_sock *dp = dccp_sk(sk);
180177
181178 ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
182179 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);
183186 inet_sock_destruct(sk);
184187 }
185188
....@@ -263,7 +266,6 @@
263266 struct inet_connection_sock *icsk = inet_csk(sk);
264267 struct inet_sock *inet = inet_sk(sk);
265268 struct dccp_sock *dp = dccp_sk(sk);
266
- int err = 0;
267269 const int old_state = sk->sk_state;
268270
269271 if (old_state != DCCP_CLOSED)
....@@ -307,7 +309,7 @@
307309 WARN_ON(inet->inet_num && !icsk->icsk_bind_hash);
308310
309311 sk->sk_error_report(sk);
310
- return err;
312
+ return 0;
311313 }
312314
313315 EXPORT_SYMBOL_GPL(dccp_disconnect);
....@@ -322,11 +324,15 @@
322324 __poll_t dccp_poll(struct file *file, struct socket *sock,
323325 poll_table *wait)
324326 {
325
- __poll_t mask;
326327 struct sock *sk = sock->sk;
328
+ __poll_t mask;
329
+ u8 shutdown;
330
+ int state;
327331
328332 sock_poll_wait(file, sock, wait);
329
- if (sk->sk_state == DCCP_LISTEN)
333
+
334
+ state = inet_sk_state_load(sk);
335
+ if (state == DCCP_LISTEN)
330336 return inet_csk_listen_poll(sk);
331337
332338 /* Socket is not locked. We are protected from async events
....@@ -335,20 +341,21 @@
335341 */
336342
337343 mask = 0;
338
- if (sk->sk_err)
344
+ if (READ_ONCE(sk->sk_err))
339345 mask = EPOLLERR;
346
+ shutdown = READ_ONCE(sk->sk_shutdown);
340347
341
- if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == DCCP_CLOSED)
348
+ if (shutdown == SHUTDOWN_MASK || state == DCCP_CLOSED)
342349 mask |= EPOLLHUP;
343
- if (sk->sk_shutdown & RCV_SHUTDOWN)
350
+ if (shutdown & RCV_SHUTDOWN)
344351 mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
345352
346353 /* Connected? */
347
- if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) {
354
+ if ((1 << state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) {
348355 if (atomic_read(&sk->sk_rmem_alloc) > 0)
349356 mask |= EPOLLIN | EPOLLRDNORM;
350357
351
- if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
358
+ if (!(shutdown & SEND_SHUTDOWN)) {
352359 if (sk_stream_is_writeable(sk)) {
353360 mask |= EPOLLOUT | EPOLLWRNORM;
354361 } else { /* send SIGIO later */
....@@ -366,7 +373,6 @@
366373 }
367374 return mask;
368375 }
369
-
370376 EXPORT_SYMBOL_GPL(dccp_poll);
371377
372378 int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
....@@ -379,6 +385,15 @@
379385 goto out;
380386
381387 switch (cmd) {
388
+ case SIOCOUTQ: {
389
+ int amount = sk_wmem_alloc_get(sk);
390
+ /* Using sk_wmem_alloc here because sk_wmem_queued is not used by DCCP and
391
+ * always 0, comparably to UDP.
392
+ */
393
+
394
+ rc = put_user(amount, (int __user *)arg);
395
+ }
396
+ break;
382397 case SIOCINQ: {
383398 struct sk_buff *skb;
384399 unsigned long amount = 0;
....@@ -406,7 +421,7 @@
406421 EXPORT_SYMBOL_GPL(dccp_ioctl);
407422
408423 static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
409
- char __user *optval, unsigned int optlen)
424
+ sockptr_t optval, unsigned int optlen)
410425 {
411426 struct dccp_sock *dp = dccp_sk(sk);
412427 struct dccp_service_list *sl = NULL;
....@@ -421,9 +436,8 @@
421436 return -ENOMEM;
422437
423438 sl->dccpsl_nr = optlen / sizeof(u32) - 1;
424
- if (copy_from_user(sl->dccpsl_list,
425
- optval + sizeof(service),
426
- optlen - sizeof(service)) ||
439
+ if (copy_from_sockptr_offset(sl->dccpsl_list, optval,
440
+ sizeof(service), optlen - sizeof(service)) ||
427441 dccp_list_has_service(sl, DCCP_SERVICE_INVALID_VALUE)) {
428442 kfree(sl);
429443 return -EFAULT;
....@@ -477,7 +491,7 @@
477491 }
478492
479493 static int dccp_setsockopt_ccid(struct sock *sk, int type,
480
- char __user *optval, unsigned int optlen)
494
+ sockptr_t optval, unsigned int optlen)
481495 {
482496 u8 *val;
483497 int rc = 0;
....@@ -485,7 +499,7 @@
485499 if (optlen < 1 || optlen > DCCP_FEAT_MAX_SP_VALS)
486500 return -EINVAL;
487501
488
- val = memdup_user(optval, optlen);
502
+ val = memdup_sockptr(optval, optlen);
489503 if (IS_ERR(val))
490504 return PTR_ERR(val);
491505
....@@ -502,7 +516,7 @@
502516 }
503517
504518 static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
505
- char __user *optval, unsigned int optlen)
519
+ sockptr_t optval, unsigned int optlen)
506520 {
507521 struct dccp_sock *dp = dccp_sk(sk);
508522 int val, err = 0;
....@@ -524,7 +538,7 @@
524538 if (optlen < (int)sizeof(int))
525539 return -EINVAL;
526540
527
- if (get_user(val, (int __user *)optval))
541
+ if (copy_from_sockptr(&val, optval, sizeof(int)))
528542 return -EFAULT;
529543
530544 if (optname == DCCP_SOCKOPT_SERVICE)
....@@ -567,8 +581,8 @@
567581 return err;
568582 }
569583
570
-int dccp_setsockopt(struct sock *sk, int level, int optname,
571
- char __user *optval, unsigned int optlen)
584
+int dccp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
585
+ unsigned int optlen)
572586 {
573587 if (level != SOL_DCCP)
574588 return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level,
....@@ -578,19 +592,6 @@
578592 }
579593
580594 EXPORT_SYMBOL_GPL(dccp_setsockopt);
581
-
582
-#ifdef CONFIG_COMPAT
583
-int compat_dccp_setsockopt(struct sock *sk, int level, int optname,
584
- char __user *optval, unsigned int optlen)
585
-{
586
- if (level != SOL_DCCP)
587
- return inet_csk_compat_setsockopt(sk, level, optname,
588
- optval, optlen);
589
- return do_dccp_setsockopt(sk, level, optname, optval, optlen);
590
-}
591
-
592
-EXPORT_SYMBOL_GPL(compat_dccp_setsockopt);
593
-#endif
594595
595596 static int dccp_getsockopt_service(struct sock *sk, int len,
596597 __be32 __user *optval,
....@@ -642,7 +643,7 @@
642643 return dccp_getsockopt_service(sk, len,
643644 (__be32 __user *)optval, optlen);
644645 case DCCP_SOCKOPT_GET_CUR_MPS:
645
- val = dp->dccps_mss_cache;
646
+ val = READ_ONCE(dp->dccps_mss_cache);
646647 break;
647648 case DCCP_SOCKOPT_AVAILABLE_CCIDS:
648649 return ccid_getsockopt_builtin_ccids(sk, len, optval, optlen);
....@@ -700,19 +701,6 @@
700701
701702 EXPORT_SYMBOL_GPL(dccp_getsockopt);
702703
703
-#ifdef CONFIG_COMPAT
704
-int compat_dccp_getsockopt(struct sock *sk, int level, int optname,
705
- char __user *optval, int __user *optlen)
706
-{
707
- if (level != SOL_DCCP)
708
- return inet_csk_compat_getsockopt(sk, level, optname,
709
- optval, optlen);
710
- return do_dccp_getsockopt(sk, level, optname, optval, optlen);
711
-}
712
-
713
-EXPORT_SYMBOL_GPL(compat_dccp_getsockopt);
714
-#endif
715
-
716704 static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb)
717705 {
718706 struct cmsghdr *cmsg;
....@@ -764,15 +752,10 @@
764752
765753 trace_dccp_probe(sk, len);
766754
767
- if (len > dp->dccps_mss_cache)
755
+ if (len > READ_ONCE(dp->dccps_mss_cache))
768756 return -EMSGSIZE;
769757
770758 lock_sock(sk);
771
-
772
- if (dccp_qpolicy_full(sk)) {
773
- rc = -EAGAIN;
774
- goto out_release;
775
- }
776759
777760 timeo = sock_sndtimeo(sk, noblock);
778761
....@@ -792,8 +775,19 @@
792775 if (skb == NULL)
793776 goto out_release;
794777
778
+ if (dccp_qpolicy_full(sk)) {
779
+ rc = -EAGAIN;
780
+ goto out_discard;
781
+ }
782
+
795783 if (sk->sk_state == DCCP_CLOSED) {
796784 rc = -ENOTCONN;
785
+ goto out_discard;
786
+ }
787
+
788
+ /* We need to check dccps_mss_cache after socket is locked. */
789
+ if (len > dp->dccps_mss_cache) {
790
+ rc = -EMSGSIZE;
797791 goto out_discard;
798792 }
799793
....@@ -856,7 +850,7 @@
856850 case DCCP_PKT_CLOSEREQ:
857851 if (!(flags & MSG_PEEK))
858852 dccp_finish_passive_close(sk);
859
- /* fall through */
853
+ fallthrough;
860854 case DCCP_PKT_RESET:
861855 dccp_pr_debug("found fin (%s) ok!\n",
862856 dccp_packet_name(dh->dccph_type));
....@@ -948,6 +942,7 @@
948942 if (!((1 << old_state) & (DCCPF_CLOSED | DCCPF_LISTEN)))
949943 goto out;
950944
945
+ WRITE_ONCE(sk->sk_max_ack_backlog, backlog);
951946 /* Really, if the socket is already in listen state
952947 * we can only allow the backlog to be adjusted.
953948 */
....@@ -960,7 +955,6 @@
960955 if (err)
961956 goto out;
962957 }
963
- sk->sk_max_ack_backlog = backlog;
964958 err = 0;
965959
966960 out:
....@@ -982,7 +976,7 @@
982976 case DCCP_PARTOPEN:
983977 dccp_pr_debug("Stop PARTOPEN timer (%p)\n", sk);
984978 inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
985
- /* fall through */
979
+ fallthrough;
986980 case DCCP_OPEN:
987981 dccp_send_close(sk, 1);
988982
....@@ -991,7 +985,7 @@
991985 next_state = DCCP_ACTIVE_CLOSEREQ;
992986 else
993987 next_state = DCCP_CLOSING;
994
- /* fall through */
988
+ fallthrough;
995989 default:
996990 dccp_set_state(sk, next_state);
997991 }
....@@ -1131,22 +1125,26 @@
11311125 static int __init dccp_init(void)
11321126 {
11331127 unsigned long goal;
1128
+ unsigned long nr_pages = totalram_pages();
11341129 int ehash_order, bhash_order, i;
11351130 int rc;
11361131
11371132 BUILD_BUG_ON(sizeof(struct dccp_skb_cb) >
1138
- FIELD_SIZEOF(struct sk_buff, cb));
1133
+ sizeof_field(struct sk_buff, cb));
11391134 rc = percpu_counter_init(&dccp_orphan_count, 0, GFP_KERNEL);
11401135 if (rc)
11411136 goto out_fail;
1142
- rc = -ENOBUFS;
11431137 inet_hashinfo_init(&dccp_hashinfo);
1138
+ rc = inet_hashinfo2_init_mod(&dccp_hashinfo);
1139
+ if (rc)
1140
+ goto out_free_percpu;
1141
+ rc = -ENOBUFS;
11441142 dccp_hashinfo.bind_bucket_cachep =
11451143 kmem_cache_create("dccp_bind_bucket",
11461144 sizeof(struct inet_bind_bucket), 0,
11471145 SLAB_HWCACHE_ALIGN, NULL);
11481146 if (!dccp_hashinfo.bind_bucket_cachep)
1149
- goto out_free_percpu;
1147
+ goto out_free_hashinfo2;
11501148
11511149 /*
11521150 * Size and allocate the main established and bind bucket
....@@ -1154,10 +1152,10 @@
11541152 *
11551153 * The methodology is similar to that of the buffer cache.
11561154 */
1157
- if (totalram_pages >= (128 * 1024))
1158
- goal = totalram_pages >> (21 - PAGE_SHIFT);
1155
+ if (nr_pages >= (128 * 1024))
1156
+ goal = nr_pages >> (21 - PAGE_SHIFT);
11591157 else
1160
- goal = totalram_pages >> (23 - PAGE_SHIFT);
1158
+ goal = nr_pages >> (23 - PAGE_SHIFT);
11611159
11621160 if (thash_entries)
11631161 goal = (thash_entries *
....@@ -1242,6 +1240,8 @@
12421240 free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order);
12431241 out_free_bind_bucket_cachep:
12441242 kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
1243
+out_free_hashinfo2:
1244
+ inet_hashinfo2_free_mod(&dccp_hashinfo);
12451245 out_free_percpu:
12461246 percpu_counter_destroy(&dccp_orphan_count);
12471247 out_fail:
....@@ -1265,6 +1265,7 @@
12651265 kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
12661266 dccp_ackvec_exit();
12671267 dccp_sysctl_exit();
1268
+ inet_hashinfo2_free_mod(&dccp_hashinfo);
12681269 percpu_counter_destroy(&dccp_orphan_count);
12691270 }
12701271