hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/netfilter/nfnetlink.c
....@@ -33,6 +33,7 @@
3333 MODULE_LICENSE("GPL");
3434 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
3535 MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NETFILTER);
36
+MODULE_DESCRIPTION("Netfilter messages via netlink socket");
3637
3738 #define nfnl_dereference_protected(id) \
3839 rcu_dereference_protected(table[(id)].subsys, \
....@@ -44,6 +45,23 @@
4445 struct mutex mutex;
4546 const struct nfnetlink_subsystem __rcu *subsys;
4647 } table[NFNL_SUBSYS_COUNT];
48
+
49
+static struct lock_class_key nfnl_lockdep_keys[NFNL_SUBSYS_COUNT];
50
+
51
+static const char *const nfnl_lockdep_names[NFNL_SUBSYS_COUNT] = {
52
+ [NFNL_SUBSYS_NONE] = "nfnl_subsys_none",
53
+ [NFNL_SUBSYS_CTNETLINK] = "nfnl_subsys_ctnetlink",
54
+ [NFNL_SUBSYS_CTNETLINK_EXP] = "nfnl_subsys_ctnetlink_exp",
55
+ [NFNL_SUBSYS_QUEUE] = "nfnl_subsys_queue",
56
+ [NFNL_SUBSYS_ULOG] = "nfnl_subsys_ulog",
57
+ [NFNL_SUBSYS_OSF] = "nfnl_subsys_osf",
58
+ [NFNL_SUBSYS_IPSET] = "nfnl_subsys_ipset",
59
+ [NFNL_SUBSYS_ACCT] = "nfnl_subsys_acct",
60
+ [NFNL_SUBSYS_CTNETLINK_TIMEOUT] = "nfnl_subsys_cttimeout",
61
+ [NFNL_SUBSYS_CTHELPER] = "nfnl_subsys_cthelper",
62
+ [NFNL_SUBSYS_NFTABLES] = "nfnl_subsys_nftables",
63
+ [NFNL_SUBSYS_NFT_COMPAT] = "nfnl_subsys_nftcompat",
64
+};
4765
4866 static const int nfnl_group2type[NFNLGRP_MAX+1] = {
4967 [NFNLGRP_CONNTRACK_NEW] = NFNL_SUBSYS_CTNETLINK,
....@@ -211,8 +229,9 @@
211229 return -ENOMEM;
212230 }
213231
214
- err = nla_parse(cda, ss->cb[cb_id].attr_count, attr, attrlen,
215
- ss->cb[cb_id].policy, extack);
232
+ err = nla_parse_deprecated(cda, ss->cb[cb_id].attr_count,
233
+ attr, attrlen,
234
+ ss->cb[cb_id].policy, extack);
216235 if (err < 0) {
217236 rcu_read_unlock();
218237 return err;
....@@ -314,7 +333,7 @@
314333 return netlink_ack(skb, nlh, -EINVAL, NULL);
315334 replay:
316335 status = 0;
317
-
336
+replay_abort:
318337 skb = netlink_skb_clone(oskb, GFP_KERNEL);
319338 if (!skb)
320339 return netlink_ack(oskb, nlh, -ENOMEM, NULL);
....@@ -426,8 +445,10 @@
426445 goto ack;
427446 }
428447
429
- err = nla_parse(cda, ss->cb[cb_id].attr_count, attr,
430
- attrlen, ss->cb[cb_id].policy, NULL);
448
+ err = nla_parse_deprecated(cda,
449
+ ss->cb[cb_id].attr_count,
450
+ attr, attrlen,
451
+ ss->cb[cb_id].policy, NULL);
431452 if (err < 0)
432453 goto ack;
433454
....@@ -452,7 +473,8 @@
452473 * processed, this avoids that the same error is
453474 * reported several times when replaying the batch.
454475 */
455
- if (nfnl_err_add(&err_list, nlh, err, &extack) < 0) {
476
+ if (err == -ENOMEM ||
477
+ nfnl_err_add(&err_list, nlh, err, &extack) < 0) {
456478 /* We failed to enqueue an error, reset the
457479 * list of errors and send OOM to userspace
458480 * pointing to the batch header.
....@@ -478,7 +500,7 @@
478500 }
479501 done:
480502 if (status & NFNL_BATCH_REPLAY) {
481
- ss->abort(net, oskb);
503
+ ss->abort(net, oskb, NFNL_ABORT_AUTOLOAD);
482504 nfnl_err_reset(&err_list);
483505 kfree_skb(skb);
484506 module_put(ss->owner);
....@@ -489,14 +511,26 @@
489511 status |= NFNL_BATCH_REPLAY;
490512 goto done;
491513 } else if (err) {
492
- ss->abort(net, oskb);
514
+ ss->abort(net, oskb, NFNL_ABORT_NONE);
493515 netlink_ack(oskb, nlmsg_hdr(oskb), err, NULL);
494516 }
495517 } else {
496
- ss->abort(net, oskb);
518
+ enum nfnl_abort_action abort_action;
519
+
520
+ if (status & NFNL_BATCH_FAILURE)
521
+ abort_action = NFNL_ABORT_NONE;
522
+ else
523
+ abort_action = NFNL_ABORT_VALIDATE;
524
+
525
+ err = ss->abort(net, oskb, abort_action);
526
+ if (err == -EAGAIN) {
527
+ nfnl_err_reset(&err_list);
528
+ kfree_skb(skb);
529
+ module_put(ss->owner);
530
+ status |= NFNL_BATCH_FAILURE;
531
+ goto replay_abort;
532
+ }
497533 }
498
- if (ss->cleanup)
499
- ss->cleanup(net);
500534
501535 nfnl_err_deliver(&err_list, oskb);
502536 kfree_skb(skb);
....@@ -525,8 +559,8 @@
525559 if (skb->len < NLMSG_HDRLEN + sizeof(struct nfgenmsg))
526560 return;
527561
528
- err = nla_parse(cda, NFNL_BATCH_MAX, attr, attrlen, nfnl_batch_policy,
529
- NULL);
562
+ err = nla_parse_deprecated(cda, NFNL_BATCH_MAX, attr, attrlen,
563
+ nfnl_batch_policy, NULL);
530564 if (err < 0) {
531565 netlink_ack(skb, nlh, err, NULL);
532566 return;
....@@ -628,7 +662,7 @@
628662 BUG_ON(nfnl_group2type[i] == NFNL_SUBSYS_NONE);
629663
630664 for (i=0; i<NFNL_SUBSYS_COUNT; i++)
631
- mutex_init(&table[i].mutex);
665
+ __mutex_init(&table[i].mutex, nfnl_lockdep_names[i], &nfnl_lockdep_keys[i]);
632666
633667 return register_pernet_subsys(&nfnetlink_net_ops);
634668 }