forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/net/netlink/af_netlink.c
....@@ -1,14 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * NETLINK Kernel-user communication protocol.
34 *
45 * Authors: Alan Cox <alan@lxorguk.ukuu.org.uk>
56 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
67 * Patrick McHardy <kaber@trash.net>
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License
10
- * as published by the Free Software Foundation; either version
11
- * 2 of the License, or (at your option) any later version.
128 *
139 * Tue Jun 26 14:36:48 MEST 2001 Herbert "herp" Rosmanith
1410 * added netlink_proto_exit
....@@ -64,6 +60,7 @@
6460 #include <linux/genetlink.h>
6561 #include <linux/net_namespace.h>
6662 #include <linux/nospec.h>
63
+#include <linux/btf_ids.h>
6764
6865 #include <net/net_namespace.h>
6966 #include <net/netns/generic.h>
....@@ -75,7 +72,7 @@
7572
7673 struct listeners {
7774 struct rcu_head rcu;
78
- unsigned long masks[0];
75
+ unsigned long masks[];
7976 };
8077
8178 /* state bits */
....@@ -152,6 +149,8 @@
152149
153150 static inline u32 netlink_group_mask(u32 group)
154151 {
152
+ if (group > 32)
153
+ return 0;
155154 return group ? 1 << (group - 1) : 0;
156155 }
157156
....@@ -245,13 +244,8 @@
245244 return 0;
246245 }
247246
248
-static void __net_exit netlink_tap_exit_net(struct net *net)
249
-{
250
-}
251
-
252247 static struct pernet_operations netlink_tap_net_ops = {
253248 .init = netlink_tap_init_net,
254
- .exit = netlink_tap_exit_net,
255249 .id = &netlink_tap_net_id,
256250 .size = sizeof(struct netlink_tap_net),
257251 };
....@@ -361,7 +355,7 @@
361355 {
362356 struct netlink_sock *nlk = nlk_sk(sk);
363357
364
- if (skb_queue_empty(&sk->sk_receive_queue))
358
+ if (skb_queue_empty_lockless(&sk->sk_receive_queue))
365359 clear_bit(NETLINK_S_CONGESTED, &nlk->state);
366360 if (!test_bit(NETLINK_S_CONGESTED, &nlk->state))
367361 wake_up_interruptible(&nlk->wait);
....@@ -574,11 +568,6 @@
574568
575569 err = nlk_sk(sk)->portid == portid ? 0 : -EBUSY;
576570 if (nlk_sk(sk)->bound)
577
- goto err;
578
-
579
- err = -ENOMEM;
580
- if (BITS_PER_LONG > 32 &&
581
- unlikely(atomic_read(&table->hash.nelems) >= UINT_MAX))
582571 goto err;
583572
584573 nlk_sk(sk)->portid = portid;
....@@ -866,7 +855,7 @@
866855 *
867856 * Test to see if the opener of the socket we received the message
868857 * from had when the netlink socket was created and the sender of the
869
- * message has has the capability @cap in the user namespace @user_ns.
858
+ * message has the capability @cap in the user namespace @user_ns.
870859 */
871860 bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
872861 struct user_namespace *user_ns, int cap)
....@@ -885,7 +874,7 @@
885874 *
886875 * Test to see if the opener of the socket we received the message
887876 * from had when the netlink socket was created and the sender of the
888
- * message has has the capability @cap in the user namespace @user_ns.
877
+ * message has the capability @cap in the user namespace @user_ns.
889878 */
890879 bool netlink_ns_capable(const struct sk_buff *skb,
891880 struct user_namespace *user_ns, int cap)
....@@ -901,7 +890,7 @@
901890 *
902891 * Test to see if the opener of the socket we received the message
903892 * from had when the netlink socket was created and the sender of the
904
- * message has has the capability @cap in all user namespaces.
893
+ * message has the capability @cap in all user namespaces.
905894 */
906895 bool netlink_capable(const struct sk_buff *skb, int cap)
907896 {
....@@ -916,7 +905,7 @@
916905 *
917906 * Test to see if the opener of the socket we received the message
918907 * from had when the netlink socket was created and the sender of the
919
- * message has has the capability @cap over the network namespace of
908
+ * message has the capability @cap over the network namespace of
920909 * the socket we received the message from.
921910 */
922911 bool netlink_net_capable(const struct sk_buff *skb, int cap)
....@@ -998,7 +987,7 @@
998987 struct netlink_sock *nlk = nlk_sk(sk);
999988 struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
1000989 int err = 0;
1001
- long unsigned int groups = nladdr->nl_groups;
990
+ unsigned long groups;
1002991 bool bound;
1003992
1004993 if (addr_len < sizeof(struct sockaddr_nl))
....@@ -1006,6 +995,7 @@
1006995
1007996 if (nladdr->nl_family != AF_NETLINK)
1008997 return -EINVAL;
998
+ groups = nladdr->nl_groups;
1009999
10101000 /* Only superuser is allowed to listen multicasts */
10111001 if (groups) {
....@@ -1016,9 +1006,7 @@
10161006 return err;
10171007 }
10181008
1019
- if (nlk->ngroups == 0)
1020
- groups = 0;
1021
- else if (nlk->ngroups < 8*sizeof(groups))
1009
+ if (nlk->ngroups < BITS_PER_LONG)
10221010 groups &= (1UL << nlk->ngroups) - 1;
10231011
10241012 /* Paired with WRITE_ONCE() in netlink_insert() */
....@@ -1386,6 +1374,14 @@
13861374 }
13871375 EXPORT_SYMBOL_GPL(netlink_has_listeners);
13881376
1377
+bool netlink_strict_get_check(struct sk_buff *skb)
1378
+{
1379
+ const struct netlink_sock *nlk = nlk_sk(NETLINK_CB(skb).sk);
1380
+
1381
+ return nlk->flags & NETLINK_F_STRICT_CHK;
1382
+}
1383
+EXPORT_SYMBOL_GPL(netlink_strict_get_check);
1384
+
13891385 static int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb)
13901386 {
13911387 struct netlink_sock *nlk = nlk_sk(sk);
....@@ -1634,7 +1630,7 @@
16341630 }
16351631
16361632 static int netlink_setsockopt(struct socket *sock, int level, int optname,
1637
- char __user *optval, unsigned int optlen)
1633
+ sockptr_t optval, unsigned int optlen)
16381634 {
16391635 struct sock *sk = sock->sk;
16401636 struct netlink_sock *nlk = nlk_sk(sk);
....@@ -1645,7 +1641,7 @@
16451641 return -ENOPROTOOPT;
16461642
16471643 if (optlen >= sizeof(int) &&
1648
- get_user(val, (unsigned int __user *)optval))
1644
+ copy_from_sockptr(&val, optval, sizeof(val)))
16491645 return -EFAULT;
16501646
16511647 switch (optname) {
....@@ -1719,6 +1715,13 @@
17191715 nlk->flags |= NETLINK_F_EXT_ACK;
17201716 else
17211717 nlk->flags &= ~NETLINK_F_EXT_ACK;
1718
+ err = 0;
1719
+ break;
1720
+ case NETLINK_GET_STRICT_CHK:
1721
+ if (val)
1722
+ nlk->flags |= NETLINK_F_STRICT_CHK;
1723
+ else
1724
+ nlk->flags &= ~NETLINK_F_STRICT_CHK;
17221725 err = 0;
17231726 break;
17241727 default:
....@@ -1814,6 +1817,15 @@
18141817 return -EFAULT;
18151818 err = 0;
18161819 break;
1820
+ case NETLINK_GET_STRICT_CHK:
1821
+ if (len < sizeof(int))
1822
+ return -EINVAL;
1823
+ len = sizeof(int);
1824
+ val = nlk->flags & NETLINK_F_STRICT_CHK ? 1 : 0;
1825
+ if (put_user(len, optlen) || put_user(val, optval))
1826
+ return -EFAULT;
1827
+ err = 0;
1828
+ break;
18171829 default:
18181830 err = -ENOPROTOOPT;
18191831 }
....@@ -1850,7 +1862,7 @@
18501862 struct scm_cookie scm;
18511863 u32 netlink_skb_flags = 0;
18521864
1853
- if (msg->msg_flags&MSG_OOB)
1865
+ if (msg->msg_flags & MSG_OOB)
18541866 return -EOPNOTSUPP;
18551867
18561868 if (len == 0) {
....@@ -1919,7 +1931,7 @@
19191931 refcount_inc(&skb->users);
19201932 netlink_broadcast(sk, skb, dst_portid, dst_group, GFP_KERNEL);
19211933 }
1922
- err = netlink_unicast(sk, skb, dst_portid, msg->msg_flags&MSG_DONTWAIT);
1934
+ err = netlink_unicast(sk, skb, dst_portid, msg->msg_flags & MSG_DONTWAIT);
19231935
19241936 out:
19251937 scm_destroy(&scm);
....@@ -1932,12 +1944,12 @@
19321944 struct scm_cookie scm;
19331945 struct sock *sk = sock->sk;
19341946 struct netlink_sock *nlk = nlk_sk(sk);
1935
- int noblock = flags&MSG_DONTWAIT;
1947
+ int noblock = flags & MSG_DONTWAIT;
19361948 size_t copied;
19371949 struct sk_buff *skb, *data_skb;
19381950 int err, ret;
19391951
1940
- if (flags&MSG_OOB)
1952
+ if (flags & MSG_OOB)
19411953 return -EOPNOTSUPP;
19421954
19431955 copied = 0;
....@@ -1976,7 +1988,6 @@
19761988 copied = len;
19771989 }
19781990
1979
- skb_reset_transport_header(data_skb);
19801991 err = skb_copy_datagram_msg(data_skb, 0, msg, copied);
19811992
19821993 if (msg->msg_name) {
....@@ -2189,12 +2200,35 @@
21892200 * It would be better to create kernel thread.
21902201 */
21912202
2203
+static int netlink_dump_done(struct netlink_sock *nlk, struct sk_buff *skb,
2204
+ struct netlink_callback *cb,
2205
+ struct netlink_ext_ack *extack)
2206
+{
2207
+ struct nlmsghdr *nlh;
2208
+
2209
+ nlh = nlmsg_put_answer(skb, cb, NLMSG_DONE, sizeof(nlk->dump_done_errno),
2210
+ NLM_F_MULTI | cb->answer_flags);
2211
+ if (WARN_ON(!nlh))
2212
+ return -ENOBUFS;
2213
+
2214
+ nl_dump_check_consistent(cb, nlh);
2215
+ memcpy(nlmsg_data(nlh), &nlk->dump_done_errno, sizeof(nlk->dump_done_errno));
2216
+
2217
+ if (extack->_msg && nlk->flags & NETLINK_F_EXT_ACK) {
2218
+ nlh->nlmsg_flags |= NLM_F_ACK_TLVS;
2219
+ if (!nla_put_string(skb, NLMSGERR_ATTR_MSG, extack->_msg))
2220
+ nlmsg_end(skb, nlh);
2221
+ }
2222
+
2223
+ return 0;
2224
+}
2225
+
21922226 static int netlink_dump(struct sock *sk)
21932227 {
21942228 struct netlink_sock *nlk = nlk_sk(sk);
2229
+ struct netlink_ext_ack extack = {};
21952230 struct netlink_callback *cb;
21962231 struct sk_buff *skb = NULL;
2197
- struct nlmsghdr *nlh;
21982232 struct module *module;
21992233 int err = -ENOBUFS;
22002234 int alloc_min_size;
....@@ -2241,10 +2275,20 @@
22412275 * single netdev. The outcome is MSG_TRUNC error.
22422276 */
22432277 skb_reserve(skb, skb_tailroom(skb) - alloc_size);
2278
+
2279
+ /* Make sure malicious BPF programs can not read unitialized memory
2280
+ * from skb->head -> skb->data
2281
+ */
2282
+ skb_reset_network_header(skb);
2283
+ skb_reset_mac_header(skb);
2284
+
22442285 netlink_skb_set_owner_r(skb, sk);
22452286
2246
- if (nlk->dump_done_errno > 0)
2287
+ if (nlk->dump_done_errno > 0) {
2288
+ cb->extack = &extack;
22472289 nlk->dump_done_errno = cb->dump(skb, cb);
2290
+ cb->extack = NULL;
2291
+ }
22482292
22492293 if (nlk->dump_done_errno > 0 ||
22502294 skb_tailroom(skb) < nlmsg_total_size(sizeof(nlk->dump_done_errno))) {
....@@ -2257,15 +2301,19 @@
22572301 return 0;
22582302 }
22592303
2260
- nlh = nlmsg_put_answer(skb, cb, NLMSG_DONE,
2261
- sizeof(nlk->dump_done_errno), NLM_F_MULTI);
2262
- if (WARN_ON(!nlh))
2304
+ if (netlink_dump_done(nlk, skb, cb, &extack))
22632305 goto errout_skb;
22642306
2265
- nl_dump_check_consistent(cb, nlh);
2266
-
2267
- memcpy(nlmsg_data(nlh), &nlk->dump_done_errno,
2268
- sizeof(nlk->dump_done_errno));
2307
+#ifdef CONFIG_COMPAT_NETLINK_MESSAGES
2308
+ /* frag_list skb's data is used for compat tasks
2309
+ * and the regular skb's data for normal (non-compat) tasks.
2310
+ * See netlink_recvmsg().
2311
+ */
2312
+ if (unlikely(skb_shinfo(skb)->frag_list)) {
2313
+ if (netlink_dump_done(nlk, skb_shinfo(skb)->frag_list, cb, &extack))
2314
+ goto errout_skb;
2315
+ }
2316
+#endif
22692317
22702318 if (sk_filter(sk, skb))
22712319 kfree_skb(skb);
....@@ -2293,9 +2341,9 @@
22932341 const struct nlmsghdr *nlh,
22942342 struct netlink_dump_control *control)
22952343 {
2344
+ struct netlink_sock *nlk, *nlk2;
22962345 struct netlink_callback *cb;
22972346 struct sock *sk;
2298
- struct netlink_sock *nlk;
22992347 int ret;
23002348
23012349 refcount_inc(&skb->users);
....@@ -2328,6 +2376,9 @@
23282376 cb->module = control->module;
23292377 cb->min_dump_alloc = control->min_dump_alloc;
23302378 cb->skb = skb;
2379
+
2380
+ nlk2 = nlk_sk(NETLINK_CB(skb).sk);
2381
+ cb->strict_check = !!(nlk2->flags & NETLINK_F_STRICT_CHK);
23312382
23322383 if (control->start) {
23332384 ret = control->start(cb);
....@@ -2382,19 +2433,16 @@
23822433 if (nlk_has_extack && extack && extack->_msg)
23832434 tlvlen += nla_total_size(strlen(extack->_msg) + 1);
23842435
2385
- if (err) {
2386
- if (!(nlk->flags & NETLINK_F_CAP_ACK))
2387
- payload += nlmsg_len(nlh);
2388
- else
2389
- flags |= NLM_F_CAPPED;
2390
- if (nlk_has_extack && extack && extack->bad_attr)
2391
- tlvlen += nla_total_size(sizeof(u32));
2392
- } else {
2436
+ if (err && !(nlk->flags & NETLINK_F_CAP_ACK))
2437
+ payload += nlmsg_len(nlh);
2438
+ else
23932439 flags |= NLM_F_CAPPED;
2394
-
2395
- if (nlk_has_extack && extack && extack->cookie_len)
2396
- tlvlen += nla_total_size(extack->cookie_len);
2397
- }
2440
+ if (err && nlk_has_extack && extack && extack->bad_attr)
2441
+ tlvlen += nla_total_size(sizeof(u32));
2442
+ if (nlk_has_extack && extack && extack->cookie_len)
2443
+ tlvlen += nla_total_size(extack->cookie_len);
2444
+ if (err && nlk_has_extack && extack && extack->policy)
2445
+ tlvlen += netlink_policy_dump_attr_size_estimate(extack->policy);
23982446
23992447 if (tlvlen)
24002448 flags |= NLM_F_ACK_TLVS;
....@@ -2417,20 +2465,19 @@
24172465 WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG,
24182466 extack->_msg));
24192467 }
2420
- if (err) {
2421
- if (extack->bad_attr &&
2422
- !WARN_ON((u8 *)extack->bad_attr < in_skb->data ||
2423
- (u8 *)extack->bad_attr >= in_skb->data +
2424
- in_skb->len))
2425
- WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS,
2426
- (u8 *)extack->bad_attr -
2427
- (u8 *)nlh));
2428
- } else {
2429
- if (extack->cookie_len)
2430
- WARN_ON(nla_put(skb, NLMSGERR_ATTR_COOKIE,
2431
- extack->cookie_len,
2432
- extack->cookie));
2433
- }
2468
+ if (err && extack->bad_attr &&
2469
+ !WARN_ON((u8 *)extack->bad_attr < in_skb->data ||
2470
+ (u8 *)extack->bad_attr >= in_skb->data +
2471
+ in_skb->len))
2472
+ WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS,
2473
+ (u8 *)extack->bad_attr -
2474
+ (u8 *)nlh));
2475
+ if (extack->cookie_len)
2476
+ WARN_ON(nla_put(skb, NLMSGERR_ATTR_COOKIE,
2477
+ extack->cookie_len, extack->cookie));
2478
+ if (extack->policy)
2479
+ netlink_policy_dump_write_attr(skb, extack->policy,
2480
+ NLMSGERR_ATTR_POLICY);
24342481 }
24352482
24362483 nlmsg_end(skb, rep);
....@@ -2532,20 +2579,10 @@
25322579 int link;
25332580 };
25342581
2535
-static int netlink_walk_start(struct nl_seq_iter *iter)
2582
+static void netlink_walk_start(struct nl_seq_iter *iter)
25362583 {
2537
- int err;
2538
-
2539
- err = rhashtable_walk_init(&nl_table[iter->link].hash, &iter->hti,
2540
- GFP_KERNEL);
2541
- if (err) {
2542
- iter->link = MAX_LINKS;
2543
- return err;
2544
- }
2545
-
2584
+ rhashtable_walk_enter(&nl_table[iter->link].hash, &iter->hti);
25462585 rhashtable_walk_start(&iter->hti);
2547
-
2548
- return 0;
25492586 }
25502587
25512588 static void netlink_walk_stop(struct nl_seq_iter *iter)
....@@ -2561,8 +2598,6 @@
25612598
25622599 do {
25632600 for (;;) {
2564
- int err;
2565
-
25662601 nlk = rhashtable_walk_next(&iter->hti);
25672602
25682603 if (IS_ERR(nlk)) {
....@@ -2579,9 +2614,7 @@
25792614 if (++iter->link >= MAX_LINKS)
25802615 return NULL;
25812616
2582
- err = netlink_walk_start(iter);
2583
- if (err)
2584
- return ERR_PTR(err);
2617
+ netlink_walk_start(iter);
25852618 }
25862619 } while (sock_net(&nlk->sk) != seq_file_net(seq));
25872620
....@@ -2589,17 +2622,15 @@
25892622 }
25902623
25912624 static void *netlink_seq_start(struct seq_file *seq, loff_t *posp)
2625
+ __acquires(RCU)
25922626 {
25932627 struct nl_seq_iter *iter = seq->private;
25942628 void *obj = SEQ_START_TOKEN;
25952629 loff_t pos;
2596
- int err;
25972630
25982631 iter->link = 0;
25992632
2600
- err = netlink_walk_start(iter);
2601
- if (err)
2602
- return ERR_PTR(err);
2633
+ netlink_walk_start(iter);
26032634
26042635 for (pos = *posp; pos && obj && !IS_ERR(obj); pos--)
26052636 obj = __netlink_seq_next(seq);
....@@ -2613,7 +2644,7 @@
26132644 return __netlink_seq_next(seq);
26142645 }
26152646
2616
-static void netlink_seq_stop(struct seq_file *seq, void *v)
2647
+static void netlink_native_seq_stop(struct seq_file *seq, void *v)
26172648 {
26182649 struct nl_seq_iter *iter = seq->private;
26192650
....@@ -2624,7 +2655,7 @@
26242655 }
26252656
26262657
2627
-static int netlink_seq_show(struct seq_file *seq, void *v)
2658
+static int netlink_native_seq_show(struct seq_file *seq, void *v)
26282659 {
26292660 if (v == SEQ_START_TOKEN) {
26302661 seq_puts(seq,
....@@ -2634,7 +2665,7 @@
26342665 struct sock *s = v;
26352666 struct netlink_sock *nlk = nlk_sk(s);
26362667
2637
- seq_printf(seq, "%pK %-3d %-10u %08x %-8d %-8d %-5d %-8d %-8d %-8lu\n",
2668
+ seq_printf(seq, "%pK %-3d %-10u %08x %-8d %-8d %-5d %-8d %-8u %-8lu\n",
26382669 s,
26392670 s->sk_protocol,
26402671 nlk->portid,
....@@ -2650,6 +2681,68 @@
26502681 }
26512682 return 0;
26522683 }
2684
+
2685
+#ifdef CONFIG_BPF_SYSCALL
2686
+struct bpf_iter__netlink {
2687
+ __bpf_md_ptr(struct bpf_iter_meta *, meta);
2688
+ __bpf_md_ptr(struct netlink_sock *, sk);
2689
+};
2690
+
2691
+DEFINE_BPF_ITER_FUNC(netlink, struct bpf_iter_meta *meta, struct netlink_sock *sk)
2692
+
2693
+static int netlink_prog_seq_show(struct bpf_prog *prog,
2694
+ struct bpf_iter_meta *meta,
2695
+ void *v)
2696
+{
2697
+ struct bpf_iter__netlink ctx;
2698
+
2699
+ meta->seq_num--; /* skip SEQ_START_TOKEN */
2700
+ ctx.meta = meta;
2701
+ ctx.sk = nlk_sk((struct sock *)v);
2702
+ return bpf_iter_run_prog(prog, &ctx);
2703
+}
2704
+
2705
+static int netlink_seq_show(struct seq_file *seq, void *v)
2706
+{
2707
+ struct bpf_iter_meta meta;
2708
+ struct bpf_prog *prog;
2709
+
2710
+ meta.seq = seq;
2711
+ prog = bpf_iter_get_info(&meta, false);
2712
+ if (!prog)
2713
+ return netlink_native_seq_show(seq, v);
2714
+
2715
+ if (v != SEQ_START_TOKEN)
2716
+ return netlink_prog_seq_show(prog, &meta, v);
2717
+
2718
+ return 0;
2719
+}
2720
+
2721
+static void netlink_seq_stop(struct seq_file *seq, void *v)
2722
+{
2723
+ struct bpf_iter_meta meta;
2724
+ struct bpf_prog *prog;
2725
+
2726
+ if (!v) {
2727
+ meta.seq = seq;
2728
+ prog = bpf_iter_get_info(&meta, true);
2729
+ if (prog)
2730
+ (void)netlink_prog_seq_show(prog, &meta, v);
2731
+ }
2732
+
2733
+ netlink_native_seq_stop(seq, v);
2734
+}
2735
+#else
2736
+static int netlink_seq_show(struct seq_file *seq, void *v)
2737
+{
2738
+ return netlink_native_seq_show(seq, v);
2739
+}
2740
+
2741
+static void netlink_seq_stop(struct seq_file *seq, void *v)
2742
+{
2743
+ netlink_native_seq_stop(seq, v);
2744
+}
2745
+#endif
26532746
26542747 static const struct seq_operations netlink_seq_ops = {
26552748 .start = netlink_seq_start,
....@@ -2757,6 +2850,34 @@
27572850 .automatic_shrinking = true,
27582851 };
27592852
2853
+#if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS)
2854
+BTF_ID_LIST(btf_netlink_sock_id)
2855
+BTF_ID(struct, netlink_sock)
2856
+
2857
+static const struct bpf_iter_seq_info netlink_seq_info = {
2858
+ .seq_ops = &netlink_seq_ops,
2859
+ .init_seq_private = bpf_iter_init_seq_net,
2860
+ .fini_seq_private = bpf_iter_fini_seq_net,
2861
+ .seq_priv_size = sizeof(struct nl_seq_iter),
2862
+};
2863
+
2864
+static struct bpf_iter_reg netlink_reg_info = {
2865
+ .target = "netlink",
2866
+ .ctx_arg_info_size = 1,
2867
+ .ctx_arg_info = {
2868
+ { offsetof(struct bpf_iter__netlink, sk),
2869
+ PTR_TO_BTF_ID_OR_NULL },
2870
+ },
2871
+ .seq_info = &netlink_seq_info,
2872
+};
2873
+
2874
+static int __init bpf_iter_register(void)
2875
+{
2876
+ netlink_reg_info.ctx_arg_info[0].btf_id = *btf_netlink_sock_id;
2877
+ return bpf_iter_reg_target(&netlink_reg_info);
2878
+}
2879
+#endif
2880
+
27602881 static int __init netlink_proto_init(void)
27612882 {
27622883 int i;
....@@ -2765,7 +2886,13 @@
27652886 if (err != 0)
27662887 goto out;
27672888
2768
- BUILD_BUG_ON(sizeof(struct netlink_skb_parms) > FIELD_SIZEOF(struct sk_buff, cb));
2889
+#if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS)
2890
+ err = bpf_iter_register();
2891
+ if (err)
2892
+ goto out;
2893
+#endif
2894
+
2895
+ BUILD_BUG_ON(sizeof(struct netlink_skb_parms) > sizeof_field(struct sk_buff, cb));
27692896
27702897 nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL);
27712898 if (!nl_table)
....@@ -2794,8 +2921,4 @@
27942921 panic("netlink_init: Cannot allocate nl_table\n");
27952922 }
27962923
2797
-#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
2798
-core_initcall_sync(netlink_proto_init);
2799
-#else
28002924 core_initcall(netlink_proto_init);
2801
-#endif