From 2eb5ae57ec2b59671bb92228571d28a7913856b6 Mon Sep 17 00:00:00 2001 From: Eduard Abdullin Date: Fri, 21 Aug 2026 11:02:10 +0000 Subject: [PATCH] Debrand for AlmaLinux OS Use AlmaLinux OS secure boot cert Enable Btrfs support for all kernel variants af_unix: set gc_in_progress to true in unix_gc() {CVE-2026-53361} hpsa: bring back deprecated PCI ids #CFHack #CFHack2024 mptsas: bring back deprecated PCI ids #CFHack #CFHack2024 megaraid_sas: bring back deprecated PCI ids #CFHack #CFHack2024 qla2xxx: bring back deprecated PCI ids #CFHack #CFHack2024 qla4xxx: bring back deprecated PCI ids be2iscsi: bring back deprecated PCI ids kernel/rh_messages.h: enable all disabled pci devices by moving to unmaintained gve: update QPL page registration logic to honor max_registered_pages (backport from upstream) gve: enable reading max ring size from the device in DQO-QPL mode (backport from upstream) --- .gitignore | 6 +- ...lit-gc-into-unlink-and-reclaim-phase.patch | 214 ------ ...s-walk-all-pending-catchall-elements.patch | 58 -- ...hash-fix-get-operation-on-big-endian.patch | 57 -- ...k-h323-fix-oob-read-in-decode-choice.patch | 65 -- ...lly-bump-set-nelems-before-insertion.patch | 106 --- ...ck-out-of-bounds-read-in-pipapo-drop.patch | 65 -- ...ry-leak-in-bridge-verdict-error-path.patch | 52 -- ...-after-free-in-ctnetlink-dump-exp-ct.patch | 124 ---- ...d-missing-netlink-policy-validations.patch | 63 -- ...ength-u32-truncation-in-sip-help-tcp.patch | 66 -- ...fix-oob-read-in-decode-int-cons-case.patch | 49 -- ...ful-expression-memleak-in-error-path.patch | 105 --- ...-return-non-matching-entry-on-expiry.patch | 161 ----- ...alized-padding-leak-in-nfula-payload.patch | 58 -- ...xpect-honor-expectation-helper-field.patch | 206 ------ ...f-conntrack-expect-use-expect-helper.patch | 144 ---- ...-store-netns-and-zone-in-expectation.patch | 155 ----- ...ect-oversized-addrnr-in-rt-mt6-check.patch | 48 -- ...link-use-netlink-policy-range-checks.patch | 125 ---- ...-log-account-for-netlink-header-size.patch | 40 -- ...bles-ensure-names-are-nul-terminated.patch | 65 -- ...-nla-strcmp-for-ipset-attr-name-attr.patch | 83 --- ...at-fields-when-cta-expect-nat-absent.patch | 58 -- ...-explicit-helper-on-new-expectations.patch | 169 ----- ...t-check-target-extensions-for-nfprot.patch | 101 --- ...es-reject-immediate-nf-queue-verdict.patch | 52 -- ...ze-nfgenmsg-in-nlmsg-done-terminator.patch | 52 -- ...alidate-range-encoding-in-checkentry.patch | 100 --- ...after-free-in-timeout-object-destroy.patch | 80 --- ...etfilter-nft-osf-restrict-it-to-ipv4.patch | 47 -- ...idual-option-lengths-in-fingerprints.patch | 84 --- ...fix-divide-by-zero-in-osf-wss-modulo.patch | 68 -- ...ilter-conntrack-remove-sprintf-usage.patch | 181 ----- ...ter-nat-use-kfree-rcu-to-release-ops.patch | 112 ---- ...ut-of-bounds-read-on-option-matching.patch | 101 --- ...ential-null-dereference-in-ttl-check.patch | 75 --- ...s-use-list-del-rcu-for-netlink-hooks.patch | 137 ---- ...dd-list-splice-rcu-for-private-lists.patch | 78 --- ...-via-splice-list-rcu-in-commit-phase.patch | 51 -- ...ok-transactions-for-device-deletions.patch | 82 --- ...-strict-mode-inbound-policy-matching.patch | 47 -- ...nntrack-sip-don-t-use-simple-strtoul.patch | 351 ---------- ...make-writable-by-skb-ensure-writable.patch | 81 --- ...droom-validate-with-neigh-forwarding.patch | 63 -- ...cursion-counter-in-neigh-egress-path.patch | 124 ---- ...trict-several-matches-to-inet-family.patch | 205 ------ ...d-check-hooks-to-matches-and-targets.patch | 487 -------------- ...eck-hooks-match-target-from-validate.patch | 148 ---- ...-fix-usersize-for-v1-and-v2-revision.patch | 69 -- ...location-memleak-with-dormant-tables.patch | 631 ------------------ ...e-helper-propagation-via-expectation.patch | 260 -------- ...-in-expectations-created-via-nfqueue.patch | 37 - ...helper-before-allocating-expectation.patch | 56 -- ...t-fix-missing-expect-put-in-obj-eval.patch | 39 -- ...possible-null-deref-during-error-log.patch | 65 -- ...6t-hbh-reject-oversized-option-lists.patch | 56 -- ...room-if-necessary-in-neigh-hh-bridge.patch | 141 ---- ...eue-hold-bridge-skb-dev-while-queued.patch | 97 --- ...n-invalid-seq-rst-without-direction-.patch | 55 -- ...esh-tcphdr-after-skb-ensure-writable.patch | 68 -- ...k-gre-fix-gre-keymap-list-corruption.patch | 246 ------- ...r-disable-payload-mangling-in-userns.patch | 69 -- ...tex-to-guard-hook-reference-counting.patch | 106 --- ...-irc-fix-possible-out-of-bounds-read.patch | 42 -- ...fix-use-after-free-on-object-destroy.patch | 40 -- ...-bail-out-on-template-ct-in-get-eval.patch | 87 --- 1166-netfilter-revalidate-bridge-ports.patch | 228 ------- ...-expectfn-expectations-on-unregister.patch | 138 ---- ...mac-header-was-set-before-dumping-it.patch | 63 -- ...register-tracking-for-f-present-flag.patch | 38 -- ...-stack-leak-via-the-oifname-register.patch | 83 --- ...-xmit-recursion-helpers-and-use-them.patch | 185 ----- ...se-nf-ct-exp-net-in-expectation-dump.patch | 37 - ...e-sh-add-check-for-double-create-bug.patch | 116 ---- ...-add-check-for-overlap-detection-bug.patch | 102 --- ...ge-sh-add-check-for-flush-reload-bug.patch | 136 ---- ...ct-store-master-tuple-in-expectation.patch | 128 ---- ...ed-integer-truncation-in-ipc-receive.patch | 36 - ...ter-fails-due-to-invalid-guest-state.patch | 45 -- ...oot-after-making-mmu-pages-available.patch | 88 --- ...hide-shadow-vmcs-right-after-vmclear.patch | 54 -- ...ot-before-checking-max-mapping-level.patch | 131 ---- ...alidate-all-gvas-during-pv-tlb-flush.patch | 65 -- ...-do-a-full-asid-flush-if-npt-enabled.patch | 217 ------ ...eferred-freeing-for-action-lifecycle.patch | 85 --- 1185-perf-aux-fix-page-uaf-in-map-range.patch | 51 -- ...ncode-text-output-appends-to-rsp-buf.patch | 200 ------ Makefile.rhelver | 2 +- kernel.changelog | 49 ++ kernel.spec | 239 ++----- sources | 6 +- 92 files changed, 110 insertions(+), 9825 deletions(-) delete mode 100644 1100-netfilter-nft-set-pipapo-split-gc-into-unlink-and-reclaim-phase.patch delete mode 100644 1101-netfilter-nf-tables-always-walk-all-pending-catchall-elements.patch delete mode 100644 1102-netfilter-nft-set-hash-fix-get-operation-on-big-endian.patch delete mode 100644 1103-netfilter-nf-conntrack-h323-fix-oob-read-in-decode-choice.patch delete mode 100644 1104-netfilter-nf-tables-unconditionally-bump-set-nelems-before-insertion.patch delete mode 100644 1105-netfilter-nft-set-pipapo-fix-stack-out-of-bounds-read-in-pipapo-drop.patch delete mode 100644 1106-netfilter-nfnetlink-queue-fix-entry-leak-in-bridge-verdict-error-path.patch delete mode 100644 1107-netfilter-ctnetlink-fix-use-after-free-in-ctnetlink-dump-exp-ct.patch delete mode 100644 1108-netfilter-conntrack-add-missing-netlink-policy-validations.patch delete mode 100644 1109-netfilter-nf-conntrack-sip-fix-content-length-u32-truncation-in-sip-help-tcp.patch delete mode 100644 1110-netfilter-nf-conntrack-h323-fix-oob-read-in-decode-int-cons-case.patch delete mode 100644 1111-nf-tables-nft-dynset-fix-possible-stateful-expression-memleak-in-error-path.patch delete mode 100644 1112-netfilter-nft-set-pipapo-avx2-don-t-return-non-matching-entry-on-expiry.patch delete mode 100644 1113-netfilter-nfnetlink-log-fix-uninitialized-padding-leak-in-nfula-payload.patch delete mode 100644 1114-netfilter-nf-conntrack-expect-honor-expectation-helper-field.patch delete mode 100644 1115-netfilter-nf-conntrack-expect-use-expect-helper.patch delete mode 100644 1116-netfilter-nf-conntrack-expect-store-netns-and-zone-in-expectation.patch delete mode 100644 1117-netfilter-ip6t-rt-reject-oversized-addrnr-in-rt-mt6-check.patch delete mode 100644 1118-netfilter-ctnetlink-use-netlink-policy-range-checks.patch delete mode 100644 1119-netfilter-nfnetlink-log-account-for-netlink-header-size.patch delete mode 100644 1120-netfilter-x-tables-ensure-names-are-nul-terminated.patch delete mode 100644 1121-netfilter-ipset-use-nla-strcmp-for-ipset-attr-name-attr.patch delete mode 100644 1122-netfilter-ctnetlink-zero-expect-nat-fields-when-cta-expect-nat-absent.patch delete mode 100644 1123-netfilter-ctnetlink-ignore-explicit-helper-on-new-expectations.patch delete mode 100644 1124-netfilter-x-tables-restrict-xt-check-match-xt-check-target-extensions-for-nfprot.patch delete mode 100644 1125-netfilter-nf-tables-reject-immediate-nf-queue-verdict.patch delete mode 100644 1126-netfilter-nfnetlink-log-initialize-nfgenmsg-in-nlmsg-done-terminator.patch delete mode 100644 1127-netfilter-xt-multiport-validate-range-encoding-in-checkentry.patch delete mode 100644 1128-netfilter-nft-ct-fix-use-after-free-in-timeout-object-destroy.patch delete mode 100644 1129-netfilter-nft-osf-restrict-it-to-ipv4.patch delete mode 100644 1130-nfnetlink-osf-validate-individual-option-lengths-in-fingerprints.patch delete mode 100644 1131-netfilter-nfnetlink-osf-fix-divide-by-zero-in-osf-wss-modulo.patch delete mode 100644 1132-netfilter-conntrack-remove-sprintf-usage.patch delete mode 100644 1133-netfilter-nat-use-kfree-rcu-to-release-ops.patch delete mode 100644 1134-netfilter-nfnetlink-osf-fix-out-of-bounds-read-on-option-matching.patch delete mode 100644 1135-netfilter-nfnetlink-osf-fix-potential-null-dereference-in-ttl-check.patch delete mode 100644 1136-netfilter-nf-tables-use-list-del-rcu-for-netlink-hooks.patch delete mode 100644 1137-rculist-add-list-splice-rcu-for-private-lists.patch delete mode 100644 1138-netfilter-nf-tables-join-hook-list-via-splice-list-rcu-in-commit-phase.patch delete mode 100644 1139-netfilter-nf-tables-add-hook-transactions-for-device-deletions.patch delete mode 100644 1140-netfilter-xt-policy-fix-strict-mode-inbound-policy-matching.patch delete mode 100644 1141-netfilter-nf-conntrack-sip-don-t-use-simple-strtoul.patch delete mode 100644 1142-netfilter-replace-skb-try-make-writable-by-skb-ensure-writable.patch delete mode 100644 1143-netfilter-nft-fwd-netdev-add-device-and-headroom-validate-with-neigh-forwarding.patch delete mode 100644 1144-netfilter-nft-fwd-netdev-use-recursion-counter-in-neigh-egress-path.patch delete mode 100644 1145-netfilter-xtables-restrict-several-matches-to-inet-family.patch delete mode 100644 1146-netfilter-x-tables-add-check-hooks-to-matches-and-targets.patch delete mode 100644 1147-netfilter-nft-compat-run-xt-check-hooks-match-target-from-validate.patch delete mode 100644 1148-netfilter-xt-ct-fix-usersize-for-v1-and-v2-revision.patch delete mode 100644 1149-netfilter-nf-tables-fix-netdev-hook-allocation-memleak-with-dormant-tables.patch delete mode 100644 1150-netfilter-nf-conntrack-expect-restore-helper-propagation-via-expectation.patch delete mode 100644 1151-netfilter-ctnetlink-check-tuple-and-mask-in-expectations-created-via-nfqueue.patch delete mode 100644 1152-netfilter-nf-conntrack-sip-get-helper-before-allocating-expectation.patch delete mode 100644 1153-netfilter-nft-ct-fix-missing-expect-put-in-obj-eval.patch delete mode 100644 1154-netfilter-nf-conntrack-helper-fix-possible-null-deref-during-error-log.patch delete mode 100644 1155-netfilter-ip6t-hbh-reject-oversized-option-lists.patch delete mode 100644 1156-netfilter-br-netfilter-reallocate-headroom-if-necessary-in-neigh-hh-bridge.patch delete mode 100644 1157-netfilter-nf-queue-hold-bridge-skb-dev-while-queued.patch delete mode 100644 1158-netfilter-conntrack-tcp-do-not-force-close-on-invalid-seq-rst-without-direction-.patch delete mode 100644 1159-netfilter-synproxy-refresh-tcphdr-after-skb-ensure-writable.patch delete mode 100644 1160-netfilter-nf-conntrack-gre-fix-gre-keymap-list-corruption.patch delete mode 100644 1161-netfilter-disable-payload-mangling-in-userns.patch delete mode 100644 1162-netfilter-synproxy-add-mutex-to-guard-hook-reference-counting.patch delete mode 100644 1163-netfilter-conntrack-irc-fix-possible-out-of-bounds-read.patch delete mode 100644 1164-netfilter-nft-tunnel-fix-use-after-free-on-object-destroy.patch delete mode 100644 1165-netfilter-nft-ct-bail-out-on-template-ct-in-get-eval.patch delete mode 100644 1166-netfilter-revalidate-bridge-ports.patch delete mode 100644 1167-netfilter-nf-conntrack-destroy-stale-expectfn-expectations-on-unregister.patch delete mode 100644 1168-netfilter-nf-log-validate-mac-header-was-set-before-dumping-it.patch delete mode 100644 1169-netfilter-nft-exthdr-fix-register-tracking-for-f-present-flag.patch delete mode 100644 1170-netfilter-nft-fib-fix-stale-stack-leak-via-the-oifname-register.patch delete mode 100644 1171-netfilter-nf-dup-netdev-add-nf-dev-xmit-recursion-helpers-and-use-them.patch delete mode 100644 1172-netfilter-ctnetlink-use-nf-ct-exp-net-in-expectation-dump.patch delete mode 100644 1173-selftests-netfilter-nft-concat-range-sh-add-check-for-double-create-bug.patch delete mode 100644 1174-selftests-netfilter-nft-concat-range-sh-add-check-for-overlap-detection-bug.patch delete mode 100644 1175-selftests-netfilter-nft-concat-range-sh-add-check-for-flush-reload-bug.patch delete mode 100644 1176-netfilter-nf-conntrack-expect-store-master-tuple-in-expectation.patch delete mode 100644 1177-accel-ivpu-fix-signed-integer-truncation-in-ipc-receive.patch delete mode 100644 1178-kvm-nvmx-put-vmcs12-pages-if-nested-vm-enter-fails-due-to-invalid-guest-state.patch delete mode 100644 1179-kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch delete mode 100644 1180-kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch delete mode 100644 1181-kvm-x86-mmu-ensure-hugepage-is-in-by-slot-before-checking-max-mapping-level.patch delete mode 100644 1182-kvm-x86-hyper-v-validate-all-gvas-during-pv-tlb-flush.patch delete mode 100644 1183-kvm-svm-make-svm-flush-tlb-gva-do-a-full-asid-flush-if-npt-enabled.patch delete mode 100644 1184-net-sched-act-api-use-rcu-with-deferred-freeing-for-action-lifecycle.patch delete mode 100644 1185-perf-aux-fix-page-uaf-in-map-range.patch delete mode 100644 1186-scsi-target-iscsi-bound-iscsi-encode-text-output-appends-to-rsp-buf.patch diff --git a/.gitignore b/.gitignore index 24c02cb73..12a378b0f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ fedoraimaca.x509 -kernel-abi-stablelists-6.12.0-211.46.1.el10_2.tar.xz -kernel-kabi-dw-6.12.0-211.46.1.el10_2.tar.xz -linux-6.12.0-211.46.1.el10_2.tar.xz +kernel-abi-stablelists-6.12.0-211.49.1.el10_2.tar.xz +kernel-kabi-dw-6.12.0-211.49.1.el10_2.tar.xz +linux-6.12.0-211.49.1.el10_2.tar.xz nvidiabfdpu.x509 nvidiagpuoot001.x509 nvidiajetsonsoc.x509 diff --git a/1100-netfilter-nft-set-pipapo-split-gc-into-unlink-and-reclaim-phase.patch b/1100-netfilter-nft-set-pipapo-split-gc-into-unlink-and-reclaim-phase.patch deleted file mode 100644 index 75d354f29..000000000 --- a/1100-netfilter-nft-set-pipapo-split-gc-into-unlink-and-reclaim-phase.patch +++ /dev/null @@ -1,214 +0,0 @@ -From 4655e3eac77838a9e585416ef176e1d1799287c0 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:15:52 +0200 -Subject: [PATCH] netfilter: nft_set_pipapo: split gc into unlink and reclaim - phase - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 9df95785d3d8 - -commit 9df95785d3d8302f7c066050117b04cd3c2048c2 -Author: Florian Westphal -Date: Tue Mar 3 16:31:32 2026 +0100 - - netfilter: nft_set_pipapo: split gc into unlink and reclaim phase - - Yiming Qian reports Use-after-free in the pipapo set type: - Under a large number of expired elements, commit-time GC can run for a very - long time in a non-preemptible context, triggering soft lockup warnings and - RCU stall reports (local denial of service). - - We must split GC in an unlink and a reclaim phase. - - We cannot queue elements for freeing until pointers have been swapped. - Expired elements are still exposed to both the packet path and userspace - dumpers via the live copy of the data structure. - - call_rcu() does not protect us: dump operations or element lookups starting - after call_rcu has fired can still observe the free'd element, unless the - commit phase has made enough progress to swap the clone and live pointers - before any new reader has picked up the old version. - - This a similar approach as done recently for the rbtree backend in commit - 35f83a75529a ("netfilter: nft_set_rbtree: don't gc elements on insert"). - - Fixes: 3c4287f62044 ("nf_tables: Add set type for arbitrary concatenation of ranges") - Reported-by: Yiming Qian - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h -index 38b3be3..81b52cd 100644 ---- a/include/net/netfilter/nf_tables.h -+++ b/include/net/netfilter/nf_tables.h -@@ -1856,6 +1856,11 @@ struct nft_trans_gc { - struct rcu_head rcu; - }; - -+static inline int nft_trans_gc_space(const struct nft_trans_gc *trans) -+{ -+ return NFT_TRANS_GC_BATCHCOUNT - trans->count; -+} -+ - static inline void nft_ctx_update(struct nft_ctx *ctx, - const struct nft_trans *trans) - { -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 6411001..5d244d3 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -10623,11 +10623,6 @@ static void nft_trans_gc_queue_work(struct nft_trans_gc *trans) - schedule_work(&trans_gc_work); - } - --static int nft_trans_gc_space(struct nft_trans_gc *trans) --{ -- return NFT_TRANS_GC_BATCHCOUNT - trans->count; --} -- - struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc, - unsigned int gc_seq, gfp_t gfp) - { -diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c -index 2824944..308af52 100644 ---- a/net/netfilter/nft_set_pipapo.c -+++ b/net/netfilter/nft_set_pipapo.c -@@ -1666,11 +1666,11 @@ static void nft_pipapo_gc_deactivate(struct net *net, struct nft_set *set, - } - - /** -- * pipapo_gc() - Drop expired entries from set, destroy start and end elements -+ * pipapo_gc_scan() - Drop expired entries from set and link them to gc list - * @set: nftables API set representation - * @m: Matching data - */ --static void pipapo_gc(struct nft_set *set, struct nft_pipapo_match *m) -+static void pipapo_gc_scan(struct nft_set *set, struct nft_pipapo_match *m) - { - struct nft_pipapo *priv = nft_set_priv(set); - struct net *net = read_pnet(&set->net); -@@ -1683,6 +1683,8 @@ static void pipapo_gc(struct nft_set *set, struct nft_pipapo_match *m) - if (!gc) - return; - -+ list_add(&gc->list, &priv->gc_head); -+ - while ((rules_f0 = pipapo_rules_same_key(m->f, first_rule))) { - union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS]; - const struct nft_pipapo_field *f; -@@ -1710,9 +1712,13 @@ static void pipapo_gc(struct nft_set *set, struct nft_pipapo_match *m) - * NFT_SET_ELEM_DEAD_BIT. - */ - if (__nft_set_elem_expired(&e->ext, tstamp)) { -- gc = nft_trans_gc_queue_sync(gc, GFP_KERNEL); -- if (!gc) -- return; -+ if (!nft_trans_gc_space(gc)) { -+ gc = nft_trans_gc_alloc(set, 0, GFP_KERNEL); -+ if (!gc) -+ return; -+ -+ list_add(&gc->list, &priv->gc_head); -+ } - - nft_pipapo_gc_deactivate(net, set, e); - pipapo_drop(m, rulemap); -@@ -1726,10 +1732,30 @@ static void pipapo_gc(struct nft_set *set, struct nft_pipapo_match *m) - } - } - -- gc = nft_trans_gc_catchall_sync(gc); -+ priv->last_gc = jiffies; -+} -+ -+/** -+ * pipapo_gc_queue() - Free expired elements -+ * @set: nftables API set representation -+ */ -+static void pipapo_gc_queue(struct nft_set *set) -+{ -+ struct nft_pipapo *priv = nft_set_priv(set); -+ struct nft_trans_gc *gc, *next; -+ -+ /* always do a catchall cycle: */ -+ gc = nft_trans_gc_alloc(set, 0, GFP_KERNEL); - if (gc) { -+ gc = nft_trans_gc_catchall_sync(gc); -+ if (gc) -+ nft_trans_gc_queue_sync_done(gc); -+ } -+ -+ /* always purge queued gc elements. */ -+ list_for_each_entry_safe(gc, next, &priv->gc_head, list) { -+ list_del(&gc->list); - nft_trans_gc_queue_sync_done(gc); -- priv->last_gc = jiffies; - } - } - -@@ -1783,6 +1809,10 @@ static void pipapo_reclaim_match(struct rcu_head *rcu) - * - * We also need to create a new working copy for subsequent insertions and - * deletions. -+ * -+ * After the live copy has been replaced by the clone, we can safely queue -+ * expired elements that have been collected by pipapo_gc_scan() for -+ * memory reclaim. - */ - static void nft_pipapo_commit(struct nft_set *set) - { -@@ -1793,7 +1823,7 @@ static void nft_pipapo_commit(struct nft_set *set) - return; - - if (time_after_eq(jiffies, priv->last_gc + nft_set_gc_interval(set))) -- pipapo_gc(set, priv->clone); -+ pipapo_gc_scan(set, priv->clone); - - old = rcu_replace_pointer(priv->match, priv->clone, - nft_pipapo_transaction_mutex_held(set)); -@@ -1801,6 +1831,8 @@ static void nft_pipapo_commit(struct nft_set *set) - - if (old) - call_rcu(&old->rcu, pipapo_reclaim_match); -+ -+ pipapo_gc_queue(set); - } - - static void nft_pipapo_abort(const struct nft_set *set) -@@ -2258,6 +2290,7 @@ static int nft_pipapo_init(const struct nft_set *set, - f->mt = NULL; - } - -+ INIT_LIST_HEAD(&priv->gc_head); - rcu_assign_pointer(priv->match, m); - - return 0; -@@ -2307,6 +2340,8 @@ static void nft_pipapo_destroy(const struct nft_ctx *ctx, - struct nft_pipapo *priv = nft_set_priv(set); - struct nft_pipapo_match *m; - -+ WARN_ON_ONCE(!list_empty(&priv->gc_head)); -+ - m = rcu_dereference_protected(priv->match, true); - - if (priv->clone) { -diff --git a/net/netfilter/nft_set_pipapo.h b/net/netfilter/nft_set_pipapo.h -index 4a2ff85..49000f5 100644 ---- a/net/netfilter/nft_set_pipapo.h -+++ b/net/netfilter/nft_set_pipapo.h -@@ -156,12 +156,14 @@ struct nft_pipapo_match { - * @clone: Copy where pending insertions and deletions are kept - * @width: Total bytes to be matched for one packet, including padding - * @last_gc: Timestamp of last garbage collection run, jiffies -+ * @gc_head: list of nft_trans_gc to queue up for mem reclaim - */ - struct nft_pipapo { - struct nft_pipapo_match __rcu *match; - struct nft_pipapo_match *clone; - int width; - unsigned long last_gc; -+ struct list_head gc_head; - }; - - struct nft_pipapo_elem; diff --git a/1101-netfilter-nf-tables-always-walk-all-pending-catchall-elements.patch b/1101-netfilter-nf-tables-always-walk-all-pending-catchall-elements.patch deleted file mode 100644 index 49013c0c1..000000000 --- a/1101-netfilter-nf-tables-always-walk-all-pending-catchall-elements.patch +++ /dev/null @@ -1,58 +0,0 @@ -From ee1d70170aaa417e064d9f98e029e5aef0dd4397 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:15:53 +0200 -Subject: [PATCH] netfilter: nf_tables: always walk all pending catchall - elements - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 7cb9a23d7ae4 - -commit 7cb9a23d7ae40a702577d3d8bacb7026f04ac2a9 -Author: Florian Westphal -Date: Thu Mar 5 21:32:00 2026 +0100 - - netfilter: nf_tables: always walk all pending catchall elements - - During transaction processing we might have more than one catchall element: - 1 live catchall element and 1 pending element that is coming as part of the - new batch. - - If the map holding the catchall elements is also going away, its - required to toggle all catchall elements and not just the first viable - candidate. - - Otherwise, we get: - WARNING: ./include/net/netfilter/nf_tables.h:1281 at nft_data_release+0xb7/0xe0 [nf_tables], CPU#2: nft/1404 - RIP: 0010:nft_data_release+0xb7/0xe0 [nf_tables] - [..] - __nft_set_elem_destroy+0x106/0x380 [nf_tables] - nf_tables_abort_release+0x348/0x8d0 [nf_tables] - nf_tables_abort+0xcf2/0x3ac0 [nf_tables] - nfnetlink_rcv_batch+0x9c9/0x20e0 [..] - - Fixes: 628bd3e49cba ("netfilter: nf_tables: drop map element references from preparation phase") - Reported-by: Yiming Qian - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 5d244d3..55434ea 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -828,7 +828,6 @@ static void nft_map_catchall_deactivate(const struct nft_ctx *ctx, - - nft_set_elem_change_active(ctx->net, set, ext); - nft_setelem_data_deactivate(ctx->net, set, catchall->elem); -- break; - } - } - -@@ -5918,7 +5917,6 @@ static void nft_map_catchall_activate(const struct nft_ctx *ctx, - - nft_clear(ctx->net, ext); - nft_setelem_data_activate(ctx->net, set, catchall->elem); -- break; - } - } - diff --git a/1102-netfilter-nft-set-hash-fix-get-operation-on-big-endian.patch b/1102-netfilter-nft-set-hash-fix-get-operation-on-big-endian.patch deleted file mode 100644 index 032e23aa7..000000000 --- a/1102-netfilter-nft-set-hash-fix-get-operation-on-big-endian.patch +++ /dev/null @@ -1,57 +0,0 @@ -From bb3bbb9f38362d2f5f47f38b354cc935cadea8ec Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:10:08 +0200 -Subject: [PATCH] netfilter: nft_set_hash: fix get operation on big endian - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 2f635adbe264 - -commit 2f635adbe2642d398a0be3ab245accd2987be0c3 -Author: Florian Westphal -Date: Tue Jan 27 20:13:45 2026 +0100 - - netfilter: nft_set_hash: fix get operation on big endian - - tests/shell/testcases/packetpath/set_match_nomatch_hash_fast - fails on big endian with: - - Error: Could not process rule: No such file or directory - reset element ip test s { 244.147.90.126 } - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Fatal: Cannot fetch element "244.147.90.126" - - ... because the wrong bucket is searched, jhash() and jhash1_word are - not interchangeable on big endian. - - Fixes: 3b02b0adc242 ("netfilter: nft_set_hash: fix lookups with fixed size hash on big endian") - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c -index ba01ce7..739b992 100644 ---- a/net/netfilter/nft_set_hash.c -+++ b/net/netfilter/nft_set_hash.c -@@ -619,15 +619,20 @@ static struct nft_elem_priv * - nft_hash_get(const struct net *net, const struct nft_set *set, - const struct nft_set_elem *elem, unsigned int flags) - { -+ const u32 *key = (const u32 *)&elem->key.val; - struct nft_hash *priv = nft_set_priv(set); - u8 genmask = nft_genmask_cur(net); - struct nft_hash_elem *he; - u32 hash; - -- hash = jhash(elem->key.val.data, set->klen, priv->seed); -+ if (set->klen == 4) -+ hash = jhash_1word(*key, priv->seed); -+ else -+ hash = jhash(key, set->klen, priv->seed); -+ - hash = reciprocal_scale(hash, priv->buckets); - hlist_for_each_entry_rcu(he, &priv->table[hash], node) { -- if (!memcmp(nft_set_ext_key(&he->ext), elem->key.val.data, set->klen) && -+ if (!memcmp(nft_set_ext_key(&he->ext), key, set->klen) && - nft_set_elem_active(&he->ext, genmask)) - return &he->priv; - } diff --git a/1103-netfilter-nf-conntrack-h323-fix-oob-read-in-decode-choice.patch b/1103-netfilter-nf-conntrack-h323-fix-oob-read-in-decode-choice.patch deleted file mode 100644 index cdec031d7..000000000 --- a/1103-netfilter-nf-conntrack-h323-fix-oob-read-in-decode-choice.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 812cb15e9cc9b8002c24e507a9004edbccb000c3 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:15:50 +0200 -Subject: [PATCH] netfilter: nf_conntrack_h323: fix OOB read in decode_choice() - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit baed0d9ba91d - -commit baed0d9ba91d4f390da12d5039128ee897253d60 -Author: Vahagn Vardanian -Date: Wed Feb 25 14:06:18 2026 +0100 - - netfilter: nf_conntrack_h323: fix OOB read in decode_choice() - - In decode_choice(), the boundary check before get_len() uses the - variable `len`, which is still 0 from its initialization at the top of - the function: - - unsigned int type, ext, len = 0; - ... - if (ext || (son->attr & OPEN)) { - BYTE_ALIGN(bs); - if (nf_h323_error_boundary(bs, len, 0)) /* len is 0 here */ - return H323_ERROR_BOUND; - len = get_len(bs); /* OOB read */ - - When the bitstream is exactly consumed (bs->cur == bs->end), the check - nf_h323_error_boundary(bs, 0, 0) evaluates to (bs->cur + 0 > bs->end), - which is false. The subsequent get_len() call then dereferences - *bs->cur++, reading 1 byte past the end of the buffer. If that byte - has bit 7 set, get_len() reads a second byte as well. - - This can be triggered remotely by sending a crafted Q.931 SETUP message - with a User-User Information Element containing exactly 2 bytes of - PER-encoded data ({0x08, 0x00}) to port 1720 through a firewall with - the nf_conntrack_h323 helper active. The decoder fully consumes the - PER buffer before reaching this code path, resulting in a 1-2 byte - heap-buffer-overflow read confirmed by AddressSanitizer. - - Fix this by checking for 2 bytes (the maximum that get_len() may read) - instead of the uninitialized `len`. This matches the pattern used at - every other get_len() call site in the same file, where the caller - checks for 2 bytes of available data before calling get_len(). - - Fixes: ec8a8f3c31dd ("netfilter: nf_ct_h323: Extend nf_h323_error_boundary to work on bits as well") - Signed-off-by: Vahagn Vardanian - Signed-off-by: Florian Westphal - Link: https://patch.msgid.link/20260225130619.1248-2-fw@strlen.de - Signed-off-by: Paolo Abeni - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c -index ca103c9..456bf3a 100644 ---- a/net/netfilter/nf_conntrack_h323_asn1.c -+++ b/net/netfilter/nf_conntrack_h323_asn1.c -@@ -796,7 +796,7 @@ static int decode_choice(struct bitstr *bs, const struct field_t *f, - - if (ext || (son->attr & OPEN)) { - BYTE_ALIGN(bs); -- if (nf_h323_error_boundary(bs, len, 0)) -+ if (nf_h323_error_boundary(bs, 2, 0)) - return H323_ERROR_BOUND; - len = get_len(bs); - if (nf_h323_error_boundary(bs, len, 0)) diff --git a/1104-netfilter-nf-tables-unconditionally-bump-set-nelems-before-insertion.patch b/1104-netfilter-nf-tables-unconditionally-bump-set-nelems-before-insertion.patch deleted file mode 100644 index 522821adc..000000000 --- a/1104-netfilter-nf-tables-unconditionally-bump-set-nelems-before-insertion.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 573d852abb5341047873d1257065ea6ad9174da4 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:15:52 +0200 -Subject: [PATCH] netfilter: nf_tables: unconditionally bump set->nelems before - insertion - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit def602e498a4 - -commit def602e498a4f951da95c95b1b8ce8ae68aa733a -Author: Pablo Neira Ayuso -Date: Mon Mar 2 23:12:37 2026 +0100 - - netfilter: nf_tables: unconditionally bump set->nelems before insertion - - In case that the set is full, a new element gets published then removed - without waiting for the RCU grace period, while RCU reader can be - walking over it already. - - To address this issue, add the element transaction even if set is full, - but toggle the set_full flag to report -ENFILE so the abort path safely - unwinds the set to its previous state. - - As for element updates, decrement set->nelems to restore it. - - A simpler fix is to call synchronize_rcu() in the error path. - However, with a large batch adding elements to already maxed-out set, - this could cause noticeable slowdown of such batches. - - Fixes: 35d0ac9070ef ("netfilter: nf_tables: fix set->nelems counting with no NLM_F_EXCL") - Reported-by: Inseo An - Signed-off-by: Pablo Neira Ayuso - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 55434ea..f2d6ac3 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -7281,6 +7281,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, - struct nft_data_desc desc; - enum nft_registers dreg; - struct nft_trans *trans; -+ bool set_full = false; - u64 expiration; - u64 timeout; - int err, i; -@@ -7567,10 +7568,18 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, - if (err < 0) - goto err_elem_free; - -+ if (!(flags & NFT_SET_ELEM_CATCHALL)) { -+ unsigned int max = nft_set_maxsize(set), nelems; -+ -+ nelems = atomic_inc_return(&set->nelems); -+ if (nelems > max) -+ set_full = true; -+ } -+ - trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set); - if (trans == NULL) { - err = -ENOMEM; -- goto err_elem_free; -+ goto err_set_size; - } - - ext->genmask = nft_genmask_cur(ctx->net); -@@ -7622,7 +7631,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, - - ue->priv = elem_priv; - nft_trans_commit_list_add_elem(ctx->net, trans); -- goto err_elem_free; -+ goto err_set_size; - } - } - } -@@ -7635,23 +7644,16 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, - goto err_element_clash; - } - -- if (!(flags & NFT_SET_ELEM_CATCHALL)) { -- unsigned int max = nft_set_maxsize(set); -- -- if (!atomic_add_unless(&set->nelems, 1, max)) { -- err = -ENFILE; -- goto err_set_full; -- } -- } -- - nft_trans_container_elem(trans)->elems[0].priv = elem.priv; - nft_trans_commit_list_add_elem(ctx->net, trans); -- return 0; - --err_set_full: -- nft_setelem_remove(ctx->net, set, elem.priv); -+ return set_full ? -ENFILE : 0; -+ - err_element_clash: - kfree(trans); -+err_set_size: -+ if (!(flags & NFT_SET_ELEM_CATCHALL)) -+ atomic_dec(&set->nelems); - err_elem_free: - nf_tables_set_elem_destroy(ctx, set, elem.priv); - err_parse_data: diff --git a/1105-netfilter-nft-set-pipapo-fix-stack-out-of-bounds-read-in-pipapo-drop.patch b/1105-netfilter-nft-set-pipapo-fix-stack-out-of-bounds-read-in-pipapo-drop.patch deleted file mode 100644 index 408849d67..000000000 --- a/1105-netfilter-nft-set-pipapo-fix-stack-out-of-bounds-read-in-pipapo-drop.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 24f89c19d096999b6911538f085cd7d45d5086fe Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:15:54 +0200 -Subject: [PATCH] netfilter: nft_set_pipapo: fix stack out-of-bounds read in - pipapo_drop() - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit d6d8cd2db236 - -commit d6d8cd2db236a9dd13dbc2d05843b3445cc964b5 -Author: Jenny Guanni Qu -Date: Fri Mar 6 19:12:38 2026 +0000 - - netfilter: nft_set_pipapo: fix stack out-of-bounds read in pipapo_drop() - - pipapo_drop() passes rulemap[i + 1].n to pipapo_unmap() as the - to_offset argument on every iteration, including the last one where - i == m->field_count - 1. This reads one element past the end of the - stack-allocated rulemap array (declared as rulemap[NFT_PIPAPO_MAX_FIELDS] - with NFT_PIPAPO_MAX_FIELDS == 16). - - Although pipapo_unmap() returns early when is_last is true without - using the to_offset value, the argument is evaluated at the call site - before the function body executes, making this a genuine out-of-bounds - stack read confirmed by KASAN: - - BUG: KASAN: stack-out-of-bounds in pipapo_drop+0x50c/0x57c [nf_tables] - Read of size 4 at addr ffff8000810e71a4 - - This frame has 1 object: - [32, 160) 'rulemap' - - The buggy address is at offset 164 -- exactly 4 bytes past the end - of the rulemap array. - - Pass 0 instead of rulemap[i + 1].n on the last iteration to avoid - the out-of-bounds read. - - Fixes: 3c4287f62044 ("nf_tables: Add set type for arbitrary concatenation of ranges") - Signed-off-by: Jenny Guanni Qu - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c -index 308af52..f2d9442 100644 ---- a/net/netfilter/nft_set_pipapo.c -+++ b/net/netfilter/nft_set_pipapo.c -@@ -1626,6 +1626,7 @@ static void pipapo_drop(struct nft_pipapo_match *m, - int i; - - nft_pipapo_for_each_field(f, i, m) { -+ bool last = i == m->field_count - 1; - int g; - - for (g = 0; g < f->groups; g++) { -@@ -1645,7 +1646,7 @@ static void pipapo_drop(struct nft_pipapo_match *m, - } - - pipapo_unmap(f->mt, f->rules, rulemap[i].to, rulemap[i].n, -- rulemap[i + 1].n, i == m->field_count - 1); -+ last ? 0 : rulemap[i + 1].n, last); - if (pipapo_resize(f, f->rules, f->rules - rulemap[i].n)) { - /* We can ignore this, a failure to shrink tables down - * doesn't make tables invalid. diff --git a/1106-netfilter-nfnetlink-queue-fix-entry-leak-in-bridge-verdict-error-path.patch b/1106-netfilter-nfnetlink-queue-fix-entry-leak-in-bridge-verdict-error-path.patch deleted file mode 100644 index a5e09db9d..000000000 --- a/1106-netfilter-nfnetlink-queue-fix-entry-leak-in-bridge-verdict-error-path.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 6a8f494794e402fec53e71745f5afb1c34c7621a Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:15:55 +0200 -Subject: [PATCH] netfilter: nfnetlink_queue: fix entry leak in bridge verdict - error path - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit f1ba83755d81 - -commit f1ba83755d81c6fc66ac7acd723d238f974091e9 -Author: Hyunwoo Kim -Date: Sun Mar 8 02:24:06 2026 +0900 - - netfilter: nfnetlink_queue: fix entry leak in bridge verdict error path - - nfqnl_recv_verdict() calls find_dequeue_entry() to remove the queue - entry from the queue data structures, taking ownership of the entry. - For PF_BRIDGE packets, it then calls nfqa_parse_bridge() to parse VLAN - attributes. If nfqa_parse_bridge() returns an error (e.g. NFQA_VLAN - present but NFQA_VLAN_TCI missing), the function returns immediately - without freeing the dequeued entry or its sk_buff. - - This leaks the nf_queue_entry, its associated sk_buff, and all held - references (net_device refcounts, struct net refcount). Repeated - triggering exhausts kernel memory. - - Fix this by dropping the entry via nfqnl_reinject() with NF_DROP verdict - on the error path, consistent with other error handling in this file. - - Fixes: 8d45ff22f1b4 ("netfilter: bridge: nf queue verdict to use NFQA_VLAN and NFQA_L2HDR") - Reviewed-by: David Dull - Signed-off-by: Hyunwoo Kim - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c -index d2773ce..0bb1656 100644 ---- a/net/netfilter/nfnetlink_queue.c -+++ b/net/netfilter/nfnetlink_queue.c -@@ -1443,8 +1443,10 @@ static int nfqnl_recv_verdict(struct sk_buff *skb, const struct nfnl_info *info, - - if (entry->state.pf == PF_BRIDGE) { - err = nfqa_parse_bridge(entry, nfqa); -- if (err < 0) -+ if (err < 0) { -+ nfqnl_reinject(entry, NF_DROP); - return err; -+ } - } - - if (nfqa[NFQA_PAYLOAD]) { diff --git a/1107-netfilter-ctnetlink-fix-use-after-free-in-ctnetlink-dump-exp-ct.patch b/1107-netfilter-ctnetlink-fix-use-after-free-in-ctnetlink-dump-exp-ct.patch deleted file mode 100644 index 9bc5f3b6f..000000000 --- a/1107-netfilter-ctnetlink-fix-use-after-free-in-ctnetlink-dump-exp-ct.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 8d7ea526ff2d5ac74a722765b1eb02c37bea4d06 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:15:58 +0200 -Subject: [PATCH] netfilter: ctnetlink: fix use-after-free in - ctnetlink_dump_exp_ct() - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 5cb81eeda909 - -commit 5cb81eeda909dbb2def209dd10636b51549a3f8a -Author: Hyunwoo Kim -Date: Sun Mar 8 02:21:37 2026 +0900 - - netfilter: ctnetlink: fix use-after-free in ctnetlink_dump_exp_ct() - - ctnetlink_dump_exp_ct() stores a conntrack pointer in cb->data for the - netlink dump callback ctnetlink_exp_ct_dump_table(), but drops the - conntrack reference immediately after netlink_dump_start(). When the - dump spans multiple rounds, the second recvmsg() triggers the dump - callback which dereferences the now-freed conntrack via nfct_help(ct), - leading to a use-after-free on ct->ext. - - The bug is that the netlink_dump_control has no .start or .done - callbacks to manage the conntrack reference across dump rounds. Other - dump functions in the same file (e.g. ctnetlink_get_conntrack) properly - use .start/.done callbacks for this purpose. - - Fix this by adding .start and .done callbacks that hold and release the - conntrack reference for the duration of the dump, and move the - nfct_help() call after the cb->args[0] early-return check in the dump - callback to avoid dereferencing ct->ext unnecessarily. - - BUG: KASAN: slab-use-after-free in ctnetlink_exp_ct_dump_table+0x4f/0x2e0 - Read of size 8 at addr ffff88810597ebf0 by task ctnetlink_poc/133 - - CPU: 1 UID: 0 PID: 133 Comm: ctnetlink_poc Not tainted 7.0.0-rc2+ #3 PREEMPTLAZY - Call Trace: - - ctnetlink_exp_ct_dump_table+0x4f/0x2e0 - netlink_dump+0x333/0x880 - netlink_recvmsg+0x3e2/0x4b0 - ? aa_sk_perm+0x184/0x450 - sock_recvmsg+0xde/0xf0 - - Allocated by task 133: - kmem_cache_alloc_noprof+0x134/0x440 - __nf_conntrack_alloc+0xa8/0x2b0 - ctnetlink_create_conntrack+0xa1/0x900 - ctnetlink_new_conntrack+0x3cf/0x7d0 - nfnetlink_rcv_msg+0x48e/0x510 - netlink_rcv_skb+0xc9/0x1f0 - nfnetlink_rcv+0xdb/0x220 - netlink_unicast+0x3ec/0x590 - netlink_sendmsg+0x397/0x690 - __sys_sendmsg+0xf4/0x180 - - Freed by task 0: - slab_free_after_rcu_debug+0xad/0x1e0 - rcu_core+0x5c3/0x9c0 - - Fixes: e844a928431f ("netfilter: ctnetlink: allow to dump expectation per master conntrack") - Signed-off-by: Hyunwoo Kim - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c -index 633c57f..399227e 100644 ---- a/net/netfilter/nf_conntrack_netlink.c -+++ b/net/netfilter/nf_conntrack_netlink.c -@@ -3231,7 +3231,7 @@ ctnetlink_exp_ct_dump_table(struct sk_buff *skb, struct netlink_callback *cb) - { - struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); - struct nf_conn *ct = cb->data; -- struct nf_conn_help *help = nfct_help(ct); -+ struct nf_conn_help *help; - u_int8_t l3proto = nfmsg->nfgen_family; - unsigned long last_id = cb->args[1]; - struct nf_conntrack_expect *exp; -@@ -3239,6 +3239,10 @@ ctnetlink_exp_ct_dump_table(struct sk_buff *skb, struct netlink_callback *cb) - if (cb->args[0]) - return 0; - -+ help = nfct_help(ct); -+ if (!help) -+ return 0; -+ - rcu_read_lock(); - - restart: -@@ -3268,6 +3272,24 @@ ctnetlink_exp_ct_dump_table(struct sk_buff *skb, struct netlink_callback *cb) - return skb->len; - } - -+static int ctnetlink_dump_exp_ct_start(struct netlink_callback *cb) -+{ -+ struct nf_conn *ct = cb->data; -+ -+ if (!refcount_inc_not_zero(&ct->ct_general.use)) -+ return -ENOENT; -+ return 0; -+} -+ -+static int ctnetlink_dump_exp_ct_done(struct netlink_callback *cb) -+{ -+ struct nf_conn *ct = cb->data; -+ -+ if (ct) -+ nf_ct_put(ct); -+ return 0; -+} -+ - static int ctnetlink_dump_exp_ct(struct net *net, struct sock *ctnl, - struct sk_buff *skb, - const struct nlmsghdr *nlh, -@@ -3283,6 +3305,8 @@ static int ctnetlink_dump_exp_ct(struct net *net, struct sock *ctnl, - struct nf_conntrack_zone zone; - struct netlink_dump_control c = { - .dump = ctnetlink_exp_ct_dump_table, -+ .start = ctnetlink_dump_exp_ct_start, -+ .done = ctnetlink_dump_exp_ct_done, - }; - - err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER, diff --git a/1108-netfilter-conntrack-add-missing-netlink-policy-validations.patch b/1108-netfilter-conntrack-add-missing-netlink-policy-validations.patch deleted file mode 100644 index ab9297a3c..000000000 --- a/1108-netfilter-conntrack-add-missing-netlink-policy-validations.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 3579bfdd048b5391909e01eae2e7bfb5d742b97b Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:15:58 +0200 -Subject: [PATCH] netfilter: conntrack: add missing netlink policy validations - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit f900e1d77ee0 - -commit f900e1d77ee0ef87bfb5ab3fe60f0b3d8ad5ba05 -Author: Florian Westphal -Date: Tue Mar 10 00:28:29 2026 +0100 - - netfilter: conntrack: add missing netlink policy validations - - Hyunwoo Kim reports out-of-bounds access in sctp and ctnetlink. - - These attributes are used by the kernel without any validation. - Extend the netlink policies accordingly. - - Quoting the reporter: - nlattr_to_sctp() assigns the user-supplied CTA_PROTOINFO_SCTP_STATE - value directly to ct->proto.sctp.state without checking that it is - within the valid range. [..] - - and: ... with exp->dir = 100, the access at - ct->master->tuplehash[100] reads 5600 bytes past the start of a - 320-byte nf_conn object, causing a slab-out-of-bounds read confirmed by - UBSAN. - - Fixes: 076a0ca02644 ("netfilter: ctnetlink: add NAT support for expectations") - Fixes: a258860e01b8 ("netfilter: ctnetlink: add full support for SCTP to ctnetlink") - Reported-by: Hyunwoo Kim - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c -index 399227e..527bf07 100644 ---- a/net/netfilter/nf_conntrack_netlink.c -+++ b/net/netfilter/nf_conntrack_netlink.c -@@ -3518,7 +3518,7 @@ ctnetlink_change_expect(struct nf_conntrack_expect *x, - - #if IS_ENABLED(CONFIG_NF_NAT) - static const struct nla_policy exp_nat_nla_policy[CTA_EXPECT_NAT_MAX+1] = { -- [CTA_EXPECT_NAT_DIR] = { .type = NLA_U32 }, -+ [CTA_EXPECT_NAT_DIR] = NLA_POLICY_MAX(NLA_BE32, IP_CT_DIR_REPLY), - [CTA_EXPECT_NAT_TUPLE] = { .type = NLA_NESTED }, - }; - #endif -diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c -index 4cc97f9..fabb2c1 100644 ---- a/net/netfilter/nf_conntrack_proto_sctp.c -+++ b/net/netfilter/nf_conntrack_proto_sctp.c -@@ -587,7 +587,8 @@ static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla, - } - - static const struct nla_policy sctp_nla_policy[CTA_PROTOINFO_SCTP_MAX+1] = { -- [CTA_PROTOINFO_SCTP_STATE] = { .type = NLA_U8 }, -+ [CTA_PROTOINFO_SCTP_STATE] = NLA_POLICY_MAX(NLA_U8, -+ SCTP_CONNTRACK_HEARTBEAT_SENT), - [CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] = { .type = NLA_U32 }, - [CTA_PROTOINFO_SCTP_VTAG_REPLY] = { .type = NLA_U32 }, - }; diff --git a/1109-netfilter-nf-conntrack-sip-fix-content-length-u32-truncation-in-sip-help-tcp.patch b/1109-netfilter-nf-conntrack-sip-fix-content-length-u32-truncation-in-sip-help-tcp.patch deleted file mode 100644 index 9e630f1ef..000000000 --- a/1109-netfilter-nf-conntrack-sip-fix-content-length-u32-truncation-in-sip-help-tcp.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 2f1682c1275edb5ac6139158d930d43be0717378 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:15:59 +0200 -Subject: [PATCH] netfilter: nf_conntrack_sip: fix Content-Length u32 - truncation in sip_help_tcp() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit fbce58e719a1 - -commit fbce58e719a17aa215c724473fd5baaa4a8dc57c -Author: Lukas Johannes Möller -Date: Tue Mar 10 21:49:01 2026 +0000 - - netfilter: nf_conntrack_sip: fix Content-Length u32 truncation in sip_help_tcp() - - sip_help_tcp() parses the SIP Content-Length header with - simple_strtoul(), which returns unsigned long, but stores the result in - unsigned int clen. On 64-bit systems, values exceeding UINT_MAX are - silently truncated before computing the SIP message boundary. - - For example, Content-Length 4294967328 (2^32 + 32) is truncated to 32, - causing the parser to miscalculate where the current message ends. The - loop then treats trailing data in the TCP segment as a second SIP - message and processes it through the SDP parser. - - Fix this by changing clen to unsigned long to match the return type of - simple_strtoul(), and reject Content-Length values that exceed the - remaining TCP payload length. - - Fixes: f5b321bd37fb ("netfilter: nf_conntrack_sip: add TCP support") - Signed-off-by: Lukas Johannes Möller - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c -index ca748f8..4ab5ef7 100644 ---- a/net/netfilter/nf_conntrack_sip.c -+++ b/net/netfilter/nf_conntrack_sip.c -@@ -1534,11 +1534,12 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, - { - struct tcphdr *th, _tcph; - unsigned int dataoff, datalen; -- unsigned int matchoff, matchlen, clen; -+ unsigned int matchoff, matchlen; - unsigned int msglen, origlen; - const char *dptr, *end; - s16 diff, tdiff = 0; - int ret = NF_ACCEPT; -+ unsigned long clen; - bool term; - - if (ctinfo != IP_CT_ESTABLISHED && -@@ -1573,6 +1574,9 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, - if (dptr + matchoff == end) - break; - -+ if (clen > datalen) -+ break; -+ - term = false; - for (; end + strlen("\r\n\r\n") <= dptr + datalen; end++) { - if (end[0] == '\r' && end[1] == '\n' && diff --git a/1110-netfilter-nf-conntrack-h323-fix-oob-read-in-decode-int-cons-case.patch b/1110-netfilter-nf-conntrack-h323-fix-oob-read-in-decode-int-cons-case.patch deleted file mode 100644 index 202d51f83..000000000 --- a/1110-netfilter-nf-conntrack-h323-fix-oob-read-in-decode-int-cons-case.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 6ad52cd472dace258bf7e2970ece287cfa2668b1 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:02 +0200 -Subject: [PATCH] netfilter: nf_conntrack_h323: fix OOB read in decode_int() - CONS case -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 1e3a3593162c - -commit 1e3a3593162c96e8a8de48b1e14f60c3b57fca8a -Author: Jenny Guanni Qu -Date: Thu Mar 12 02:29:32 2026 +0000 - - netfilter: nf_conntrack_h323: fix OOB read in decode_int() CONS case - - In decode_int(), the CONS case calls get_bits(bs, 2) to read a length - value, then calls get_uint(bs, len) without checking that len bytes - remain in the buffer. The existing boundary check only validates the - 2 bits for get_bits(), not the subsequent 1-4 bytes that get_uint() - reads. This allows a malformed H.323/RAS packet to cause a 1-4 byte - slab-out-of-bounds read. - - Add a boundary check for len bytes after get_bits() and before - get_uint(). - - Fixes: 5e35941d9901 ("[NETFILTER]: Add H.323 conntrack/NAT helper") - Reported-by: Klaudia Kloc - Reported-by: Dawid Moczadło - Signed-off-by: Jenny Guanni Qu - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c -index 456bf3a..7b1497e 100644 ---- a/net/netfilter/nf_conntrack_h323_asn1.c -+++ b/net/netfilter/nf_conntrack_h323_asn1.c -@@ -331,6 +331,8 @@ static int decode_int(struct bitstr *bs, const struct field_t *f, - if (nf_h323_error_boundary(bs, 0, 2)) - return H323_ERROR_BOUND; - len = get_bits(bs, 2) + 1; -+ if (nf_h323_error_boundary(bs, len, 0)) -+ return H323_ERROR_BOUND; - BYTE_ALIGN(bs); - if (base && (f->attr & DECODE)) { /* timeToLive */ - unsigned int v = get_uint(bs, len) + f->lb; diff --git a/1111-nf-tables-nft-dynset-fix-possible-stateful-expression-memleak-in-error-path.patch b/1111-nf-tables-nft-dynset-fix-possible-stateful-expression-memleak-in-error-path.patch deleted file mode 100644 index afb62f6dd..000000000 --- a/1111-nf-tables-nft-dynset-fix-possible-stateful-expression-memleak-in-error-path.patch +++ /dev/null @@ -1,105 +0,0 @@ -From d5cb2ee377e40a8ab981e46c0f83ec60239785ba Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:03 +0200 -Subject: [PATCH] nf_tables: nft_dynset: fix possible stateful expression - memleak in error path -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 0548a13b5a14 - -commit 0548a13b5a145b16e4da0628b5936baf35f51b43 -Author: Pablo Neira Ayuso -Date: Thu Mar 12 12:38:59 2026 +0100 - - nf_tables: nft_dynset: fix possible stateful expression memleak in error path - - If cloning the second stateful expression in the element via GFP_ATOMIC - fails, then the first stateful expression remains in place without being - released. - -   unreferenced object (percpu) 0x607b97e9cab8 (size 16): -     comm "softirq", pid 0, jiffies 4294931867 -     hex dump (first 16 bytes on cpu 3): -       00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -     backtrace (crc 0): -       pcpu_alloc_noprof+0x453/0xd80 -       nft_counter_clone+0x9c/0x190 [nf_tables] -       nft_expr_clone+0x8f/0x1b0 [nf_tables] -       nft_dynset_new+0x2cb/0x5f0 [nf_tables] -       nft_rhash_update+0x236/0x11c0 [nf_tables] -       nft_dynset_eval+0x11f/0x670 [nf_tables] -       nft_do_chain+0x253/0x1700 [nf_tables] -       nft_do_chain_ipv4+0x18d/0x270 [nf_tables] -       nf_hook_slow+0xaa/0x1e0 -       ip_local_deliver+0x209/0x330 - - Fixes: 563125a73ac3 ("netfilter: nftables: generalize set extension to support for several expressions") - Reported-by: Gurpreet Shergill - Signed-off-by: Pablo Neira Ayuso - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h -index 81b52cd..5fe20cc 100644 ---- a/include/net/netfilter/nf_tables.h -+++ b/include/net/netfilter/nf_tables.h -@@ -871,6 +871,8 @@ struct nft_elem_priv *nft_set_elem_init(const struct nft_set *set, - u64 timeout, u64 expiration, gfp_t gfp); - int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set, - struct nft_expr *expr_array[]); -+void nft_set_elem_expr_destroy(const struct nft_ctx *ctx, -+ struct nft_set_elem_expr *elem_expr); - void nft_set_elem_destroy(const struct nft_set *set, - const struct nft_elem_priv *elem_priv, - bool destroy_expr); -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index f2d6ac3..81164ad 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -6853,8 +6853,8 @@ static void __nft_set_elem_expr_destroy(const struct nft_ctx *ctx, - } - } - --static void nft_set_elem_expr_destroy(const struct nft_ctx *ctx, -- struct nft_set_elem_expr *elem_expr) -+void nft_set_elem_expr_destroy(const struct nft_ctx *ctx, -+ struct nft_set_elem_expr *elem_expr) - { - struct nft_expr *expr; - u32 size; -diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c -index 7807d81..9123277 100644 ---- a/net/netfilter/nft_dynset.c -+++ b/net/netfilter/nft_dynset.c -@@ -30,18 +30,26 @@ static int nft_dynset_expr_setup(const struct nft_dynset *priv, - const struct nft_set_ext *ext) - { - struct nft_set_elem_expr *elem_expr = nft_set_ext_expr(ext); -+ struct nft_ctx ctx = { -+ .net = read_pnet(&priv->set->net), -+ .family = priv->set->table->family, -+ }; - struct nft_expr *expr; - int i; - - for (i = 0; i < priv->num_exprs; i++) { - expr = nft_setelem_expr_at(elem_expr, elem_expr->size); - if (nft_expr_clone(expr, priv->expr_array[i], GFP_ATOMIC) < 0) -- return -1; -+ goto err_out; - - elem_expr->size += priv->expr_array[i]->ops->size; - } - - return 0; -+err_out: -+ nft_set_elem_expr_destroy(&ctx, elem_expr); -+ -+ return -1; - } - - struct nft_elem_priv *nft_dynset_new(struct nft_set *set, diff --git a/1112-netfilter-nft-set-pipapo-avx2-don-t-return-non-matching-entry-on-expiry.patch b/1112-netfilter-nft-set-pipapo-avx2-don-t-return-non-matching-entry-on-expiry.patch deleted file mode 100644 index 3746a52b2..000000000 --- a/1112-netfilter-nft-set-pipapo-avx2-don-t-return-non-matching-entry-on-expiry.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 84e748a8ba9c8453579b6335a098f4efdcd8fd6d Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:13 +0200 -Subject: [PATCH] netfilter: nft_set_pipapo_avx2: don't return non-matching - entry on expiry - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit d3c0037ffe12 - -commit d3c0037ffe1273fa1961e779ff6906234d6cf53c -Author: Florian Westphal -Date: Wed Mar 25 14:10:55 2026 +0100 - - netfilter: nft_set_pipapo_avx2: don't return non-matching entry on expiry - - New test case fails unexpectedly when avx2 matching functions are used. - - The test first loads a ranomly generated pipapo set - with 'ipv4 . port' key, i.e. nft -f foo. - - This works. Then, it reloads the set after a flush: - (echo flush set t s; cat foo) | nft -f - - - This is expected to work, because its the same set after all and it was - already loaded once. - - But with avx2, this fails: nft reports a clashing element. - - The reported clash is of following form: - - We successfully re-inserted - a . b - c . d - - Then we try to insert a . d - - avx2 finds the already existing a . d, which (due to 'flush set') is marked - as invalid in the new generation. It skips the element and moves to next. - - Due to incorrect masking, the skip-step finds the next matching - element *only considering the first field*, - - i.e. we return the already reinserted "a . b", even though the - last field is different and the entry should not have been matched. - - No such error is reported for the generic c implementation (no avx2) or when - the last field has to use the 'nft_pipapo_avx2_lookup_slow' fallback. - - Bisection points to - 7711f4bb4b36 ("netfilter: nft_set_pipapo: fix range overlap detection") - but that fix merely uncovers this bug. - - Before this commit, the wrong element is returned, but erronously - reported as a full, identical duplicate. - - The root-cause is too early return in the avx2 match functions. - When we process the last field, we should continue to process data - until the entire input size has been consumed to make sure no stale - bits remain in the map. - - Link: https://lore.kernel.org/netfilter-devel/20260321152506.037f68c0@elisabeth/ - Signed-off-by: Florian Westphal - Reviewed-by: Stefano Brivio - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nft_set_pipapo_avx2.c b/net/netfilter/nft_set_pipapo_avx2.c -index bf7a0f6..bb0917e 100644 ---- a/net/netfilter/nft_set_pipapo_avx2.c -+++ b/net/netfilter/nft_set_pipapo_avx2.c -@@ -242,7 +242,7 @@ static int nft_pipapo_avx2_lookup_4b_2(unsigned long *map, unsigned long *fill, - - b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); - if (last) -- return b; -+ ret = b; - - if (unlikely(ret == -1)) - ret = b / XSAVE_YMM_SIZE; -@@ -319,7 +319,7 @@ static int nft_pipapo_avx2_lookup_4b_4(unsigned long *map, unsigned long *fill, - - b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); - if (last) -- return b; -+ ret = b; - - if (unlikely(ret == -1)) - ret = b / XSAVE_YMM_SIZE; -@@ -414,7 +414,7 @@ static int nft_pipapo_avx2_lookup_4b_8(unsigned long *map, unsigned long *fill, - - b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); - if (last) -- return b; -+ ret = b; - - if (unlikely(ret == -1)) - ret = b / XSAVE_YMM_SIZE; -@@ -505,7 +505,7 @@ static int nft_pipapo_avx2_lookup_4b_12(unsigned long *map, unsigned long *fill, - - b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); - if (last) -- return b; -+ ret = b; - - if (unlikely(ret == -1)) - ret = b / XSAVE_YMM_SIZE; -@@ -641,7 +641,7 @@ static int nft_pipapo_avx2_lookup_4b_32(unsigned long *map, unsigned long *fill, - - b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); - if (last) -- return b; -+ ret = b; - - if (unlikely(ret == -1)) - ret = b / XSAVE_YMM_SIZE; -@@ -699,7 +699,7 @@ static int nft_pipapo_avx2_lookup_8b_1(unsigned long *map, unsigned long *fill, - - b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); - if (last) -- return b; -+ ret = b; - - if (unlikely(ret == -1)) - ret = b / XSAVE_YMM_SIZE; -@@ -764,7 +764,7 @@ static int nft_pipapo_avx2_lookup_8b_2(unsigned long *map, unsigned long *fill, - - b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); - if (last) -- return b; -+ ret = b; - - if (unlikely(ret == -1)) - ret = b / XSAVE_YMM_SIZE; -@@ -839,7 +839,7 @@ static int nft_pipapo_avx2_lookup_8b_4(unsigned long *map, unsigned long *fill, - - b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); - if (last) -- return b; -+ ret = b; - - if (unlikely(ret == -1)) - ret = b / XSAVE_YMM_SIZE; -@@ -925,7 +925,7 @@ static int nft_pipapo_avx2_lookup_8b_6(unsigned long *map, unsigned long *fill, - - b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); - if (last) -- return b; -+ ret = b; - - if (unlikely(ret == -1)) - ret = b / XSAVE_YMM_SIZE; -@@ -1019,7 +1019,7 @@ static int nft_pipapo_avx2_lookup_8b_16(unsigned long *map, unsigned long *fill, - - b = nft_pipapo_avx2_refill(i_ul, &map[i_ul], fill, f->mt, last); - if (last) -- return b; -+ ret = b; - - if (unlikely(ret == -1)) - ret = b / XSAVE_YMM_SIZE; diff --git a/1113-netfilter-nfnetlink-log-fix-uninitialized-padding-leak-in-nfula-payload.patch b/1113-netfilter-nfnetlink-log-fix-uninitialized-padding-leak-in-nfula-payload.patch deleted file mode 100644 index 7c6fa2d7f..000000000 --- a/1113-netfilter-nfnetlink-log-fix-uninitialized-padding-leak-in-nfula-payload.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 95bac469e4bcdb05093eec68ee002e8d5fd79bc2 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:15 +0200 -Subject: [PATCH] netfilter: nfnetlink_log: fix uninitialized padding leak in - NFULA_PAYLOAD - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 52025ebaa29f - -commit 52025ebaa29f4eb4ed8bf92ce83a68f24ab7fdf7 -Author: Weiming Shi -Date: Wed Mar 25 14:10:58 2026 +0100 - - netfilter: nfnetlink_log: fix uninitialized padding leak in NFULA_PAYLOAD - - __build_packet_message() manually constructs the NFULA_PAYLOAD netlink - attribute using skb_put() and skb_copy_bits(), bypassing the standard - nla_reserve()/nla_put() helpers. While nla_total_size(data_len) bytes - are allocated (including NLA alignment padding), only data_len bytes - of actual packet data are copied. The trailing nla_padlen(data_len) - bytes (1-3 when data_len is not 4-byte aligned) are never initialized, - leaking stale heap contents to userspace via the NFLOG netlink socket. - - Replace the manual attribute construction with nla_reserve(), which - handles the tailroom check, header setup, and padding zeroing via - __nla_reserve(). The subsequent skb_copy_bits() fills in the payload - data on top of the properly initialized attribute. - - Fixes: df6fb868d611 ("[NETFILTER]: nfnetlink: convert to generic netlink attribute functions") - Reported-by: Xiang Mei - Signed-off-by: Weiming Shi - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c -index bfcb9cd..27dd352 100644 ---- a/net/netfilter/nfnetlink_log.c -+++ b/net/netfilter/nfnetlink_log.c -@@ -647,15 +647,11 @@ __build_packet_message(struct nfnl_log_net *log, - - if (data_len) { - struct nlattr *nla; -- int size = nla_attr_size(data_len); - -- if (skb_tailroom(inst->skb) < nla_total_size(data_len)) -+ nla = nla_reserve(inst->skb, NFULA_PAYLOAD, data_len); -+ if (!nla) - goto nla_put_failure; - -- nla = skb_put(inst->skb, nla_total_size(data_len)); -- nla->nla_type = NFULA_PAYLOAD; -- nla->nla_len = size; -- - if (skb_copy_bits(skb, 0, nla_data(nla), data_len)) - BUG(); - } diff --git a/1114-netfilter-nf-conntrack-expect-honor-expectation-helper-field.patch b/1114-netfilter-nf-conntrack-expect-honor-expectation-helper-field.patch deleted file mode 100644 index b8e70918b..000000000 --- a/1114-netfilter-nf-conntrack-expect-honor-expectation-helper-field.patch +++ /dev/null @@ -1,206 +0,0 @@ -From 258cc75af0f0db2881d8c1940733dfd2d57dc95e Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:19 +0200 -Subject: [PATCH] netfilter: nf_conntrack_expect: honor expectation helper - field - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 9c42bc9db90a - -commit 9c42bc9db90a154bc61ae337a070465f3393485a -Author: Pablo Neira Ayuso -Date: Wed Mar 25 14:11:02 2026 +0100 - - netfilter: nf_conntrack_expect: honor expectation helper field - - The expectation helper field is mostly unused. As a result, the - netfilter codebase relies on accessing the helper through exp->master. - - Always set on the expectation helper field so it can be used to reach - the helper. - - nf_ct_expect_init() is called from packet path where the skb owns - the ct object, therefore accessing exp->master for the newly created - expectation is safe. This saves a lot of updates in all callsites - to pass the ct object as parameter to nf_ct_expect_init(). - - This is a preparation patches for follow up fixes. - - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h -index 165e7a0..1b01400 100644 ---- a/include/net/netfilter/nf_conntrack_expect.h -+++ b/include/net/netfilter/nf_conntrack_expect.h -@@ -40,7 +40,7 @@ struct nf_conntrack_expect { - struct nf_conntrack_expect *this); - - /* Helper to assign to new connection */ -- struct nf_conntrack_helper *helper; -+ struct nf_conntrack_helper __rcu *helper; - - /* The conntrack of the master connection */ - struct nf_conn *master; -diff --git a/net/netfilter/nf_conntrack_broadcast.c b/net/netfilter/nf_conntrack_broadcast.c -index a7552a4..1964c59 100644 ---- a/net/netfilter/nf_conntrack_broadcast.c -+++ b/net/netfilter/nf_conntrack_broadcast.c -@@ -70,7 +70,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, - exp->expectfn = NULL; - exp->flags = NF_CT_EXPECT_PERMANENT; - exp->class = NF_CT_EXPECT_CLASS_DEFAULT; -- exp->helper = NULL; -+ rcu_assign_pointer(exp->helper, helper); - - nf_ct_expect_related(exp, 0); - nf_ct_expect_put(exp); -diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c -index f9e65f0..de5e2ae 100644 ---- a/net/netfilter/nf_conntrack_expect.c -+++ b/net/netfilter/nf_conntrack_expect.c -@@ -314,12 +314,19 @@ struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me) - } - EXPORT_SYMBOL_GPL(nf_ct_expect_alloc); - -+/* This function can only be used from packet path, where accessing -+ * master's helper is safe, because the packet holds a reference on -+ * the conntrack object. Never use it from control plane. -+ */ - void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class, - u_int8_t family, - const union nf_inet_addr *saddr, - const union nf_inet_addr *daddr, - u_int8_t proto, const __be16 *src, const __be16 *dst) - { -+ struct nf_conntrack_helper *helper = NULL; -+ struct nf_conn *ct = exp->master; -+ struct nf_conn_help *help; - int len; - - if (family == AF_INET) -@@ -330,7 +337,12 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class, - exp->flags = 0; - exp->class = class; - exp->expectfn = NULL; -- exp->helper = NULL; -+ -+ help = nfct_help(ct); -+ if (help) -+ helper = rcu_dereference(help->helper); -+ -+ rcu_assign_pointer(exp->helper, helper); - exp->tuple.src.l3num = family; - exp->tuple.dst.protonum = proto; - -diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c -index 14f7387..fbf69d4 100644 ---- a/net/netfilter/nf_conntrack_h323_main.c -+++ b/net/netfilter/nf_conntrack_h323_main.c -@@ -642,7 +642,7 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct, - &ct->tuplehash[!dir].tuple.src.u3, - &ct->tuplehash[!dir].tuple.dst.u3, - IPPROTO_TCP, NULL, &port); -- exp->helper = &nf_conntrack_helper_h245; -+ rcu_assign_pointer(exp->helper, &nf_conntrack_helper_h245); - - nathook = rcu_dereference(nfct_h323_nat_hook); - if (memcmp(&ct->tuplehash[dir].tuple.src.u3, -@@ -766,7 +766,7 @@ static int expect_callforwarding(struct sk_buff *skb, - nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), - &ct->tuplehash[!dir].tuple.src.u3, &addr, - IPPROTO_TCP, NULL, &port); -- exp->helper = nf_conntrack_helper_q931; -+ rcu_assign_pointer(exp->helper, nf_conntrack_helper_q931); - - nathook = rcu_dereference(nfct_h323_nat_hook); - if (memcmp(&ct->tuplehash[dir].tuple.src.u3, -@@ -1233,7 +1233,7 @@ static int expect_q931(struct sk_buff *skb, struct nf_conn *ct, - &ct->tuplehash[!dir].tuple.src.u3 : NULL, - &ct->tuplehash[!dir].tuple.dst.u3, - IPPROTO_TCP, NULL, &port); -- exp->helper = nf_conntrack_helper_q931; -+ rcu_assign_pointer(exp->helper, nf_conntrack_helper_q931); - exp->flags = NF_CT_EXPECT_PERMANENT; /* Accept multiple calls */ - - nathook = rcu_dereference(nfct_h323_nat_hook); -@@ -1305,7 +1305,7 @@ static int process_gcf(struct sk_buff *skb, struct nf_conn *ct, - nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), - &ct->tuplehash[!dir].tuple.src.u3, &addr, - IPPROTO_UDP, NULL, &port); -- exp->helper = nf_conntrack_helper_ras; -+ rcu_assign_pointer(exp->helper, nf_conntrack_helper_ras); - - if (nf_ct_expect_related(exp, 0) == 0) { - pr_debug("nf_ct_ras: expect RAS "); -@@ -1522,7 +1522,7 @@ static int process_acf(struct sk_buff *skb, struct nf_conn *ct, - &ct->tuplehash[!dir].tuple.src.u3, &addr, - IPPROTO_TCP, NULL, &port); - exp->flags = NF_CT_EXPECT_PERMANENT; -- exp->helper = nf_conntrack_helper_q931; -+ rcu_assign_pointer(exp->helper, nf_conntrack_helper_q931); - - if (nf_ct_expect_related(exp, 0) == 0) { - pr_debug("nf_ct_ras: expect Q.931 "); -@@ -1576,7 +1576,7 @@ static int process_lcf(struct sk_buff *skb, struct nf_conn *ct, - &ct->tuplehash[!dir].tuple.src.u3, &addr, - IPPROTO_TCP, NULL, &port); - exp->flags = NF_CT_EXPECT_PERMANENT; -- exp->helper = nf_conntrack_helper_q931; -+ rcu_assign_pointer(exp->helper, nf_conntrack_helper_q931); - - if (nf_ct_expect_related(exp, 0) == 0) { - pr_debug("nf_ct_ras: expect Q.931 "); -diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c -index 9d7d36a..a21c976 100644 ---- a/net/netfilter/nf_conntrack_helper.c -+++ b/net/netfilter/nf_conntrack_helper.c -@@ -399,7 +399,7 @@ static bool expect_iter_me(struct nf_conntrack_expect *exp, void *data) - const struct nf_conntrack_helper *me = data; - const struct nf_conntrack_helper *this; - -- if (exp->helper == me) -+ if (rcu_access_pointer(exp->helper) == me) - return true; - - this = rcu_dereference_protected(help->helper, -@@ -421,6 +421,11 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) - - nf_ct_expect_iterate_destroy(expect_iter_me, me); - nf_ct_iterate_destroy(unhelp, me); -+ -+ /* nf_ct_iterate_destroy() does an unconditional synchronize_rcu() as -+ * last step, this ensures rcu readers of exp->helper are done. -+ * No need for another synchronize_rcu() here. -+ */ - } - EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); - -diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c -index 527bf07..1da2757 100644 ---- a/net/netfilter/nf_conntrack_netlink.c -+++ b/net/netfilter/nf_conntrack_netlink.c -@@ -3602,7 +3602,7 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, - - exp->class = class; - exp->master = ct; -- exp->helper = helper; -+ rcu_assign_pointer(exp->helper, helper); - exp->tuple = *tuple; - exp->mask.src.u3 = mask->src.u3; - exp->mask.src.u.all = mask->src.u.all; -diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c -index 4ab5ef7..106b2f4 100644 ---- a/net/netfilter/nf_conntrack_sip.c -+++ b/net/netfilter/nf_conntrack_sip.c -@@ -1297,7 +1297,7 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff, - nf_ct_expect_init(exp, SIP_EXPECT_SIGNALLING, nf_ct_l3num(ct), - saddr, &daddr, proto, NULL, &port); - exp->timeout.expires = sip_timeout * HZ; -- exp->helper = helper; -+ rcu_assign_pointer(exp->helper, helper); - exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE; - - hooks = rcu_dereference(nf_nat_sip_hooks); diff --git a/1115-netfilter-nf-conntrack-expect-use-expect-helper.patch b/1115-netfilter-nf-conntrack-expect-use-expect-helper.patch deleted file mode 100644 index d317eb767..000000000 --- a/1115-netfilter-nf-conntrack-expect-use-expect-helper.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 7214a2db7b72aa16525b5583488ae15b790d20bc Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:20 +0200 -Subject: [PATCH] netfilter: nf_conntrack_expect: use expect->helper - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit f01794106042 - -commit f01794106042ee27e54af6fdf5b319a2fe3df94d -Author: Pablo Neira Ayuso -Date: Wed Mar 25 14:11:03 2026 +0100 - - netfilter: nf_conntrack_expect: use expect->helper - - Use expect->helper in ctnetlink and /proc to dump the helper name. - Using nfct_help() without holding a reference to the master conntrack - is unsafe. - - Use exp->master->helper in ctnetlink path if userspace does not provide - an explicit helper when creating an expectation to retain the existing - behaviour. The ctnetlink expectation path holds the reference on the - master conntrack and nf_conntrack_expect lock and the nfnetlink glue - path refers to the master ct that is attached to the skb. - - Reported-by: Hyunwoo Kim - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c -index de5e2ae..1cbe5f1 100644 ---- a/net/netfilter/nf_conntrack_expect.c -+++ b/net/netfilter/nf_conntrack_expect.c -@@ -674,7 +674,7 @@ static int exp_seq_show(struct seq_file *s, void *v) - if (expect->flags & NF_CT_EXPECT_USERSPACE) - seq_printf(s, "%sUSERSPACE", delim); - -- helper = rcu_dereference(nfct_help(expect->master)->helper); -+ helper = rcu_dereference(expect->helper); - if (helper) { - seq_printf(s, "%s%s", expect->flags ? " " : "", helper->name); - if (helper->expect_policy[expect->class].name[0]) -diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c -index a21c976..a715304 100644 ---- a/net/netfilter/nf_conntrack_helper.c -+++ b/net/netfilter/nf_conntrack_helper.c -@@ -395,14 +395,10 @@ EXPORT_SYMBOL_GPL(nf_conntrack_helper_register); - - static bool expect_iter_me(struct nf_conntrack_expect *exp, void *data) - { -- struct nf_conn_help *help = nfct_help(exp->master); - const struct nf_conntrack_helper *me = data; - const struct nf_conntrack_helper *this; - -- if (rcu_access_pointer(exp->helper) == me) -- return true; -- -- this = rcu_dereference_protected(help->helper, -+ this = rcu_dereference_protected(exp->helper, - lockdep_is_held(&nf_conntrack_expect_lock)); - return this == me; - } -diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c -index 1da2757..479acad 100644 ---- a/net/netfilter/nf_conntrack_netlink.c -+++ b/net/netfilter/nf_conntrack_netlink.c -@@ -3031,7 +3031,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, - { - struct nf_conn *master = exp->master; - long timeout = ((long)exp->timeout.expires - (long)jiffies) / HZ; -- struct nf_conn_help *help; -+ struct nf_conntrack_helper *helper; - #if IS_ENABLED(CONFIG_NF_NAT) - struct nlattr *nest_parms; - struct nf_conntrack_tuple nat_tuple = {}; -@@ -3076,15 +3076,12 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, - nla_put_be32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags)) || - nla_put_be32(skb, CTA_EXPECT_CLASS, htonl(exp->class))) - goto nla_put_failure; -- help = nfct_help(master); -- if (help) { -- struct nf_conntrack_helper *helper; - -- helper = rcu_dereference(help->helper); -- if (helper && -- nla_put_string(skb, CTA_EXPECT_HELP_NAME, helper->name)) -- goto nla_put_failure; -- } -+ helper = rcu_dereference(exp->helper); -+ if (helper && -+ nla_put_string(skb, CTA_EXPECT_HELP_NAME, helper->name)) -+ goto nla_put_failure; -+ - expfn = nf_ct_helper_expectfn_find_by_symbol(exp->expectfn); - if (expfn != NULL && - nla_put_string(skb, CTA_EXPECT_FN, expfn->name)) -@@ -3419,12 +3416,9 @@ static int ctnetlink_get_expect(struct sk_buff *skb, - static bool expect_iter_name(struct nf_conntrack_expect *exp, void *data) - { - struct nf_conntrack_helper *helper; -- const struct nf_conn_help *m_help; - const char *name = data; - -- m_help = nfct_help(exp->master); -- -- helper = rcu_dereference(m_help->helper); -+ helper = rcu_dereference(exp->helper); - if (!helper) - return false; - -@@ -3563,9 +3557,9 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, - struct nf_conntrack_tuple *tuple, - struct nf_conntrack_tuple *mask) - { -- u_int32_t class = 0; - struct nf_conntrack_expect *exp; - struct nf_conn_help *help; -+ u32 class = 0; - int err; - - help = nfct_help(ct); -@@ -3602,6 +3596,8 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, - - exp->class = class; - exp->master = ct; -+ if (!helper) -+ helper = rcu_dereference(help->helper); - rcu_assign_pointer(exp->helper, helper); - exp->tuple = *tuple; - exp->mask.src.u3 = mask->src.u3; -diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c -index 106b2f4..20e57cf 100644 ---- a/net/netfilter/nf_conntrack_sip.c -+++ b/net/netfilter/nf_conntrack_sip.c -@@ -924,7 +924,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff, - exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); - - if (!exp || exp->master == ct || -- nfct_help(exp->master)->helper != nfct_help(ct)->helper || -+ exp->helper != nfct_help(ct)->helper || - exp->class != class) - break; - #if IS_ENABLED(CONFIG_NF_NAT) diff --git a/1116-netfilter-nf-conntrack-expect-store-netns-and-zone-in-expectation.patch b/1116-netfilter-nf-conntrack-expect-store-netns-and-zone-in-expectation.patch deleted file mode 100644 index 9484617e7..000000000 --- a/1116-netfilter-nf-conntrack-expect-store-netns-and-zone-in-expectation.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 1ef310863ab448530889c2f720436ef846da997a Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:23 +0200 -Subject: [PATCH] netfilter: nf_conntrack_expect: store netns and zone in - expectation - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 02a3231b6d82 - -commit 02a3231b6d82efe750da6554ebf280e4a6f78756 -Author: Pablo Neira Ayuso -Date: Wed Mar 25 22:39:55 2026 +0100 - - netfilter: nf_conntrack_expect: store netns and zone in expectation - - __nf_ct_expect_find() and nf_ct_expect_find_get() are called under - rcu_read_lock() but they dereference the master conntrack via - exp->master. - - Since the expectation does not hold a reference on the master conntrack, - this could be dying conntrack or different recycled conntrack than the - real master due to SLAB_TYPESAFE_RCU. - - Store the netns, the master_tuple and the zone in struct - nf_conntrack_expect as a safety measure. - - This patch is required by the follow up fix not to dump expectations - that do not belong to this netns. - - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h -index 1b01400..e9a8350 100644 ---- a/include/net/netfilter/nf_conntrack_expect.h -+++ b/include/net/netfilter/nf_conntrack_expect.h -@@ -22,10 +22,16 @@ struct nf_conntrack_expect { - /* Hash member */ - struct hlist_node hnode; - -+ /* Network namespace */ -+ possible_net_t net; -+ - /* We expect this tuple, with the following mask */ - struct nf_conntrack_tuple tuple; - struct nf_conntrack_tuple_mask mask; - -+#ifdef CONFIG_NF_CONNTRACK_ZONES -+ struct nf_conntrack_zone zone; -+#endif - /* Usage count. */ - refcount_t use; - -@@ -62,7 +68,17 @@ struct nf_conntrack_expect { - - static inline struct net *nf_ct_exp_net(struct nf_conntrack_expect *exp) - { -- return nf_ct_net(exp->master); -+ return read_pnet(&exp->net); -+} -+ -+static inline bool nf_ct_exp_zone_equal_any(const struct nf_conntrack_expect *a, -+ const struct nf_conntrack_zone *b) -+{ -+#ifdef CONFIG_NF_CONNTRACK_ZONES -+ return a->zone.id == b->id; -+#else -+ return true; -+#endif - } - - #define NF_CT_EXP_POLICY_NAME_LEN 16 -diff --git a/net/netfilter/nf_conntrack_broadcast.c b/net/netfilter/nf_conntrack_broadcast.c -index 1964c59..4f39bf7 100644 ---- a/net/netfilter/nf_conntrack_broadcast.c -+++ b/net/netfilter/nf_conntrack_broadcast.c -@@ -21,6 +21,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, - unsigned int timeout) - { - const struct nf_conntrack_helper *helper; -+ struct net *net = read_pnet(&ct->ct_net); - struct nf_conntrack_expect *exp; - struct iphdr *iph = ip_hdr(skb); - struct rtable *rt = skb_rtable(skb); -@@ -71,7 +72,10 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, - exp->flags = NF_CT_EXPECT_PERMANENT; - exp->class = NF_CT_EXPECT_CLASS_DEFAULT; - rcu_assign_pointer(exp->helper, helper); -- -+ write_pnet(&exp->net, net); -+#ifdef CONFIG_NF_CONNTRACK_ZONES -+ exp->zone = ct->zone; -+#endif - nf_ct_expect_related(exp, 0); - nf_ct_expect_put(exp); - -diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c -index 1cbe5f1..db28801 100644 ---- a/net/netfilter/nf_conntrack_expect.c -+++ b/net/netfilter/nf_conntrack_expect.c -@@ -113,8 +113,8 @@ nf_ct_exp_equal(const struct nf_conntrack_tuple *tuple, - const struct net *net) - { - return nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask) && -- net_eq(net, nf_ct_net(i->master)) && -- nf_ct_zone_equal_any(i->master, zone); -+ net_eq(net, read_pnet(&i->net)) && -+ nf_ct_exp_zone_equal_any(i, zone); - } - - bool nf_ct_remove_expect(struct nf_conntrack_expect *exp) -@@ -326,6 +326,7 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class, - { - struct nf_conntrack_helper *helper = NULL; - struct nf_conn *ct = exp->master; -+ struct net *net = read_pnet(&ct->ct_net); - struct nf_conn_help *help; - int len; - -@@ -343,6 +344,10 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class, - helper = rcu_dereference(help->helper); - - rcu_assign_pointer(exp->helper, helper); -+ write_pnet(&exp->net, net); -+#ifdef CONFIG_NF_CONNTRACK_ZONES -+ exp->zone = ct->zone; -+#endif - exp->tuple.src.l3num = family; - exp->tuple.dst.protonum = proto; - -diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c -index 479acad..844236c 100644 ---- a/net/netfilter/nf_conntrack_netlink.c -+++ b/net/netfilter/nf_conntrack_netlink.c -@@ -3557,6 +3557,7 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, - struct nf_conntrack_tuple *tuple, - struct nf_conntrack_tuple *mask) - { -+ struct net *net = read_pnet(&ct->ct_net); - struct nf_conntrack_expect *exp; - struct nf_conn_help *help; - u32 class = 0; -@@ -3596,6 +3597,10 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, - - exp->class = class; - exp->master = ct; -+ write_pnet(&exp->net, net); -+#ifdef CONFIG_NF_CONNTRACK_ZONES -+ exp->zone = ct->zone; -+#endif - if (!helper) - helper = rcu_dereference(help->helper); - rcu_assign_pointer(exp->helper, helper); diff --git a/1117-netfilter-ip6t-rt-reject-oversized-addrnr-in-rt-mt6-check.patch b/1117-netfilter-ip6t-rt-reject-oversized-addrnr-in-rt-mt6-check.patch deleted file mode 100644 index 5c4f67da5..000000000 --- a/1117-netfilter-ip6t-rt-reject-oversized-addrnr-in-rt-mt6-check.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 7769732787489525396da7af990f9f8fe0d3edd3 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:16 +0200 -Subject: [PATCH] netfilter: ip6t_rt: reject oversized addrnr in rt_mt6_check() - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 9d3f027327c2 - -commit 9d3f027327c2fa265f7f85ead41294792c3296ed -Author: Ren Wei -Date: Wed Mar 25 14:11:00 2026 +0100 - - netfilter: ip6t_rt: reject oversized addrnr in rt_mt6_check() - - Reject rt match rules whose addrnr exceeds IP6T_RT_HOPS. - - rt_mt6() expects addrnr to stay within the bounds of rtinfo->addrs[]. - Validate addrnr during rule installation so malformed rules are rejected - before the match logic can use an out-of-range value. - - Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") - Reported-by: Yifan Wu - Reported-by: Juefei Pu - Co-developed-by: Yuan Tan - Signed-off-by: Yuan Tan - Suggested-by: Xin Liu - Tested-by: Yuhang Zheng - Signed-off-by: Ren Wei - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c -index 4ad8b20..5561bd9 100644 ---- a/net/ipv6/netfilter/ip6t_rt.c -+++ b/net/ipv6/netfilter/ip6t_rt.c -@@ -157,6 +157,10 @@ static int rt_mt6_check(const struct xt_mtchk_param *par) - pr_debug("unknown flags %X\n", rtinfo->invflags); - return -EINVAL; - } -+ if (rtinfo->addrnr > IP6T_RT_HOPS) { -+ pr_debug("too many addresses specified\n"); -+ return -EINVAL; -+ } - if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) && - (!(rtinfo->flags & IP6T_RT_TYP) || - (rtinfo->rt_type != 0) || diff --git a/1118-netfilter-ctnetlink-use-netlink-policy-range-checks.patch b/1118-netfilter-ctnetlink-use-netlink-policy-range-checks.patch deleted file mode 100644 index 201821cc1..000000000 --- a/1118-netfilter-ctnetlink-use-netlink-policy-range-checks.patch +++ /dev/null @@ -1,125 +0,0 @@ -From bb977545d63209b172be316ac61e3787f769a085 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:27 +0200 -Subject: [PATCH] netfilter: ctnetlink: use netlink policy range checks - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 8f15b5071b45 - -commit 8f15b5071b4548b0aafc03b366eb45c9c6566704 -Author: David Carlier -Date: Wed Mar 25 14:11:08 2026 +0100 - - netfilter: ctnetlink: use netlink policy range checks - - Replace manual range and mask validations with netlink policy - annotations in ctnetlink code paths, so that the netlink core rejects - invalid values early and can generate extack errors. - - - CTA_PROTOINFO_TCP_STATE: reject values > TCP_CONNTRACK_SYN_SENT2 at - policy level, removing the manual >= TCP_CONNTRACK_MAX check. - - CTA_PROTOINFO_TCP_WSCALE_ORIGINAL/REPLY: reject values > TCP_MAX_WSCALE - (14). The normal TCP option parsing path already clamps to this value, - but the ctnetlink path accepted 0-255, causing undefined behavior when - used as a u32 shift count. - - CTA_FILTER_ORIG_FLAGS/REPLY_FLAGS: use NLA_POLICY_MASK with - CTA_FILTER_F_ALL, removing the manual mask checks. - - CTA_EXPECT_FLAGS: use NLA_POLICY_MASK with NF_CT_EXPECT_MASK, adding - a new mask define grouping all valid expect flags. - - Extracted from a broader nf-next patch by Florian Westphal, scoped to - ctnetlink for the fixes tree. - - Fixes: c8e2078cfe41 ("[NETFILTER]: ctnetlink: add support for internal tcp connection tracking flags handling") - Signed-off-by: David Carlier - Co-developed-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/include/uapi/linux/netfilter/nf_conntrack_common.h b/include/uapi/linux/netfilter/nf_conntrack_common.h -index 2607102..56b6b60 100644 ---- a/include/uapi/linux/netfilter/nf_conntrack_common.h -+++ b/include/uapi/linux/netfilter/nf_conntrack_common.h -@@ -159,5 +159,9 @@ enum ip_conntrack_expect_events { - #define NF_CT_EXPECT_INACTIVE 0x2 - #define NF_CT_EXPECT_USERSPACE 0x4 - -+#ifdef __KERNEL__ -+#define NF_CT_EXPECT_MASK (NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE | \ -+ NF_CT_EXPECT_USERSPACE) -+#endif - - #endif /* _UAPI_NF_CONNTRACK_COMMON_H */ -diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c -index 844236c..edc6045 100644 ---- a/net/netfilter/nf_conntrack_netlink.c -+++ b/net/netfilter/nf_conntrack_netlink.c -@@ -909,8 +909,8 @@ struct ctnetlink_filter { - }; - - static const struct nla_policy cta_filter_nla_policy[CTA_FILTER_MAX + 1] = { -- [CTA_FILTER_ORIG_FLAGS] = { .type = NLA_U32 }, -- [CTA_FILTER_REPLY_FLAGS] = { .type = NLA_U32 }, -+ [CTA_FILTER_ORIG_FLAGS] = NLA_POLICY_MASK(NLA_U32, CTA_FILTER_F_ALL), -+ [CTA_FILTER_REPLY_FLAGS] = NLA_POLICY_MASK(NLA_U32, CTA_FILTER_F_ALL), - }; - - static int ctnetlink_parse_filter(const struct nlattr *attr, -@@ -924,17 +924,11 @@ static int ctnetlink_parse_filter(const struct nlattr *attr, - if (ret) - return ret; - -- if (tb[CTA_FILTER_ORIG_FLAGS]) { -+ if (tb[CTA_FILTER_ORIG_FLAGS]) - filter->orig_flags = nla_get_u32(tb[CTA_FILTER_ORIG_FLAGS]); -- if (filter->orig_flags & ~CTA_FILTER_F_ALL) -- return -EOPNOTSUPP; -- } - -- if (tb[CTA_FILTER_REPLY_FLAGS]) { -+ if (tb[CTA_FILTER_REPLY_FLAGS]) - filter->reply_flags = nla_get_u32(tb[CTA_FILTER_REPLY_FLAGS]); -- if (filter->reply_flags & ~CTA_FILTER_F_ALL) -- return -EOPNOTSUPP; -- } - - return 0; - } -@@ -2653,7 +2647,7 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = { - [CTA_EXPECT_HELP_NAME] = { .type = NLA_NUL_STRING, - .len = NF_CT_HELPER_NAME_LEN - 1 }, - [CTA_EXPECT_ZONE] = { .type = NLA_U16 }, -- [CTA_EXPECT_FLAGS] = { .type = NLA_U32 }, -+ [CTA_EXPECT_FLAGS] = NLA_POLICY_MASK(NLA_BE32, NF_CT_EXPECT_MASK), - [CTA_EXPECT_CLASS] = { .type = NLA_U32 }, - [CTA_EXPECT_NAT] = { .type = NLA_NESTED }, - [CTA_EXPECT_FN] = { .type = NLA_NUL_STRING }, -diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c -index 0c1d086..b67426c 100644 ---- a/net/netfilter/nf_conntrack_proto_tcp.c -+++ b/net/netfilter/nf_conntrack_proto_tcp.c -@@ -1385,9 +1385,9 @@ static int tcp_to_nlattr(struct sk_buff *skb, struct nlattr *nla, - } - - static const struct nla_policy tcp_nla_policy[CTA_PROTOINFO_TCP_MAX+1] = { -- [CTA_PROTOINFO_TCP_STATE] = { .type = NLA_U8 }, -- [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] = { .type = NLA_U8 }, -- [CTA_PROTOINFO_TCP_WSCALE_REPLY] = { .type = NLA_U8 }, -+ [CTA_PROTOINFO_TCP_STATE] = NLA_POLICY_MAX(NLA_U8, TCP_CONNTRACK_SYN_SENT2), -+ [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] = NLA_POLICY_MAX(NLA_U8, TCP_MAX_WSCALE), -+ [CTA_PROTOINFO_TCP_WSCALE_REPLY] = NLA_POLICY_MAX(NLA_U8, TCP_MAX_WSCALE), - [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL] = { .len = sizeof(struct nf_ct_tcp_flags) }, - [CTA_PROTOINFO_TCP_FLAGS_REPLY] = { .len = sizeof(struct nf_ct_tcp_flags) }, - }; -@@ -1414,10 +1414,6 @@ static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct) - if (err < 0) - return err; - -- if (tb[CTA_PROTOINFO_TCP_STATE] && -- nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]) >= TCP_CONNTRACK_MAX) -- return -EINVAL; -- - spin_lock_bh(&ct->lock); - if (tb[CTA_PROTOINFO_TCP_STATE]) - ct->proto.tcp.state = nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]); diff --git a/1119-netfilter-nfnetlink-log-account-for-netlink-header-size.patch b/1119-netfilter-nfnetlink-log-account-for-netlink-header-size.patch deleted file mode 100644 index 22d0feabf..000000000 --- a/1119-netfilter-nfnetlink-log-account-for-netlink-header-size.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 216247489e80cd8001356ed24e13323803cce985 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:30 +0200 -Subject: [PATCH] netfilter: nfnetlink_log: account for netlink header size - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 6d52a4a0520a - -commit 6d52a4a0520a6696bdde51caa11f2d6821cd0c01 -Author: Florian Westphal -Date: Thu Mar 26 16:17:24 2026 +0100 - - netfilter: nfnetlink_log: account for netlink header size - - This is a followup to an old bug fix: NLMSG_DONE needs to account - for the netlink header size, not just the attribute size. - - This can result in a WARN splat + drop of the netlink message, - but other than this there are no ill effects. - - Fixes: 9dfa1dfe4d5e ("netfilter: nf_log: account for size of NLMSG_DONE attribute") - Reported-by: Yiming Qian - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c -index 27dd352..dcd2493 100644 ---- a/net/netfilter/nfnetlink_log.c -+++ b/net/netfilter/nfnetlink_log.c -@@ -726,7 +726,7 @@ nfulnl_log_packet(struct net *net, - + nla_total_size(plen) /* prefix */ - + nla_total_size(sizeof(struct nfulnl_msg_packet_hw)) - + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp)) -- + nla_total_size(sizeof(struct nfgenmsg)); /* NLMSG_DONE */ -+ + nlmsg_total_size(sizeof(struct nfgenmsg)); /* NLMSG_DONE */ - - if (in && skb_mac_header_was_set(skb)) { - size += nla_total_size(skb->dev->hard_header_len) diff --git a/1120-netfilter-x-tables-ensure-names-are-nul-terminated.patch b/1120-netfilter-x-tables-ensure-names-are-nul-terminated.patch deleted file mode 100644 index 96f17fd49..000000000 --- a/1120-netfilter-x-tables-ensure-names-are-nul-terminated.patch +++ /dev/null @@ -1,65 +0,0 @@ -From fb3e41e38a172b76e67ec5c97f4db2d3a9407c40 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:31 +0200 -Subject: [PATCH] netfilter: x_tables: ensure names are nul-terminated - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit a958a4f90ddd - -commit a958a4f90ddd7de0800b33ca9d7b886b7d40f74e -Author: Florian Westphal -Date: Tue Mar 31 23:13:36 2026 +0200 - - netfilter: x_tables: ensure names are nul-terminated - - Reject names that lack a \0 character before feeding them - to functions that expect c-strings. - - Fixes tag is the most recent commit that needs this change. - - Fixes: c38c4597e4bf ("netfilter: implement xt_cgroup cgroup2 path match") - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/xt_cgroup.c b/net/netfilter/xt_cgroup.c -index c0f5e9a..bfc9871 100644 ---- a/net/netfilter/xt_cgroup.c -+++ b/net/netfilter/xt_cgroup.c -@@ -53,6 +53,9 @@ static int cgroup_mt_check_v1(const struct xt_mtchk_param *par) - - info->priv = NULL; - if (info->has_path) { -+ if (strnlen(info->path, sizeof(info->path)) >= sizeof(info->path)) -+ return -ENAMETOOLONG; -+ - cgrp = cgroup_get_from_path(info->path); - if (IS_ERR(cgrp)) { - pr_info_ratelimited("invalid path, errno=%ld\n", -@@ -85,6 +88,9 @@ static int cgroup_mt_check_v2(const struct xt_mtchk_param *par) - - info->priv = NULL; - if (info->has_path) { -+ if (strnlen(info->path, sizeof(info->path)) >= sizeof(info->path)) -+ return -ENAMETOOLONG; -+ - cgrp = cgroup_get_from_path(info->path); - if (IS_ERR(cgrp)) { - pr_info_ratelimited("invalid path, errno=%ld\n", -diff --git a/net/netfilter/xt_rateest.c b/net/netfilter/xt_rateest.c -index 72324bd..b1d736c 100644 ---- a/net/netfilter/xt_rateest.c -+++ b/net/netfilter/xt_rateest.c -@@ -91,6 +91,11 @@ static int xt_rateest_mt_checkentry(const struct xt_mtchk_param *par) - goto err1; - } - -+ if (strnlen(info->name1, sizeof(info->name1)) >= sizeof(info->name1)) -+ return -ENAMETOOLONG; -+ if (strnlen(info->name2, sizeof(info->name2)) >= sizeof(info->name2)) -+ return -ENAMETOOLONG; -+ - ret = -ENOENT; - est1 = xt_rateest_lookup(par->net, info->name1); - if (!est1) diff --git a/1121-netfilter-ipset-use-nla-strcmp-for-ipset-attr-name-attr.patch b/1121-netfilter-ipset-use-nla-strcmp-for-ipset-attr-name-attr.patch deleted file mode 100644 index 4d0cac9b9..000000000 --- a/1121-netfilter-ipset-use-nla-strcmp-for-ipset-attr-name-attr.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 7563a383e063cf6be846f150a25d85098adad32b Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:33 +0200 -Subject: [PATCH] netfilter: ipset: use nla_strcmp for IPSET_ATTR_NAME attr - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit b7e8590987aa - -commit b7e8590987aa94c9dc51518fad0e58cb887b1db5 -Author: Florian Westphal -Date: Mon Mar 30 14:16:34 2026 +0200 - - netfilter: ipset: use nla_strcmp for IPSET_ATTR_NAME attr - - IPSET_ATTR_NAME and IPSET_ATTR_NAMEREF are of NLA_STRING type, they - cannot be treated like a c-string. - - They either have to be switched to NLA_NUL_STRING, or the compare - operations need to use the nla functions. - - Fixes: f830837f0eed ("netfilter: ipset: list:set set type support") - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h -index e9f4f84..b983315 100644 ---- a/include/linux/netfilter/ipset/ip_set.h -+++ b/include/linux/netfilter/ipset/ip_set.h -@@ -309,7 +309,7 @@ enum { - - /* register and unregister set references */ - extern ip_set_id_t ip_set_get_byname(struct net *net, -- const char *name, struct ip_set **set); -+ const struct nlattr *name, struct ip_set **set); - extern void ip_set_put_byindex(struct net *net, ip_set_id_t index); - extern void ip_set_name_byindex(struct net *net, ip_set_id_t index, char *name); - extern ip_set_id_t ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index); -diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c -index cc20e6d..a4e1d79 100644 ---- a/net/netfilter/ipset/ip_set_core.c -+++ b/net/netfilter/ipset/ip_set_core.c -@@ -821,7 +821,7 @@ EXPORT_SYMBOL_GPL(ip_set_del); - * - */ - ip_set_id_t --ip_set_get_byname(struct net *net, const char *name, struct ip_set **set) -+ip_set_get_byname(struct net *net, const struct nlattr *name, struct ip_set **set) - { - ip_set_id_t i, index = IPSET_INVALID_ID; - struct ip_set *s; -@@ -830,7 +830,7 @@ ip_set_get_byname(struct net *net, const char *name, struct ip_set **set) - rcu_read_lock(); - for (i = 0; i < inst->ip_set_max; i++) { - s = rcu_dereference(inst->ip_set_list)[i]; -- if (s && STRNCMP(s->name, name)) { -+ if (s && nla_strcmp(name, s->name) == 0) { - __ip_set_get(s); - index = i; - *set = s; -diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c -index 13c7a08..34bb84d 100644 ---- a/net/netfilter/ipset/ip_set_list_set.c -+++ b/net/netfilter/ipset/ip_set_list_set.c -@@ -367,7 +367,7 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[], - ret = ip_set_get_extensions(set, tb, &ext); - if (ret) - return ret; -- e.id = ip_set_get_byname(map->net, nla_data(tb[IPSET_ATTR_NAME]), &s); -+ e.id = ip_set_get_byname(map->net, tb[IPSET_ATTR_NAME], &s); - if (e.id == IPSET_INVALID_ID) - return -IPSET_ERR_NAME; - /* "Loop detection" */ -@@ -389,7 +389,7 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[], - - if (tb[IPSET_ATTR_NAMEREF]) { - e.refid = ip_set_get_byname(map->net, -- nla_data(tb[IPSET_ATTR_NAMEREF]), -+ tb[IPSET_ATTR_NAMEREF], - &s); - if (e.refid == IPSET_INVALID_ID) { - ret = -IPSET_ERR_NAMEREF; diff --git a/1122-netfilter-ctnetlink-zero-expect-nat-fields-when-cta-expect-nat-absent.patch b/1122-netfilter-ctnetlink-zero-expect-nat-fields-when-cta-expect-nat-absent.patch deleted file mode 100644 index bda94e949..000000000 --- a/1122-netfilter-ctnetlink-zero-expect-nat-fields-when-cta-expect-nat-absent.patch +++ /dev/null @@ -1,58 +0,0 @@ -From fc4bd898b84a9af433a40544389691829990d4b2 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:35 +0200 -Subject: [PATCH] netfilter: ctnetlink: zero expect NAT fields when - CTA_EXPECT_NAT absent - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 35177c687713 - -commit 35177c6877134a21315f37d57a5577846225623e -Author: Qi Tang -Date: Tue Mar 31 14:17:12 2026 +0800 - - netfilter: ctnetlink: zero expect NAT fields when CTA_EXPECT_NAT absent - - ctnetlink_alloc_expect() allocates expectations from a non-zeroing - slab cache via nf_ct_expect_alloc(). When CTA_EXPECT_NAT is not - present in the netlink message, saved_addr and saved_proto are - never initialized. Stale data from a previous slab occupant can - then be dumped to userspace by ctnetlink_exp_dump_expect(), which - checks these fields to decide whether to emit CTA_EXPECT_NAT. - - The safe sibling nf_ct_expect_init(), used by the packet path, - explicitly zeroes these fields. - - Zero saved_addr, saved_proto and dir in the else branch, guarded - by IS_ENABLED(CONFIG_NF_NAT) since these fields only exist when - NAT is enabled. - - Confirmed by priming the expect slab with NAT-bearing expectations, - freeing them, creating a new expectation without CTA_EXPECT_NAT, - and observing that the ctnetlink dump emits a spurious - CTA_EXPECT_NAT containing stale data from the prior allocation. - - Fixes: 076a0ca02644 ("netfilter: ctnetlink: add NAT support for expectations") - Reported-by: kernel test robot - Signed-off-by: Qi Tang - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c -index edc6045..208e26a 100644 ---- a/net/netfilter/nf_conntrack_netlink.c -+++ b/net/netfilter/nf_conntrack_netlink.c -@@ -3607,6 +3607,12 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, - exp, nf_ct_l3num(ct)); - if (err < 0) - goto err_out; -+#if IS_ENABLED(CONFIG_NF_NAT) -+ } else { -+ memset(&exp->saved_addr, 0, sizeof(exp->saved_addr)); -+ memset(&exp->saved_proto, 0, sizeof(exp->saved_proto)); -+ exp->dir = 0; -+#endif - } - return exp; - err_out: diff --git a/1123-netfilter-ctnetlink-ignore-explicit-helper-on-new-expectations.patch b/1123-netfilter-ctnetlink-ignore-explicit-helper-on-new-expectations.patch deleted file mode 100644 index 2390edb05..000000000 --- a/1123-netfilter-ctnetlink-ignore-explicit-helper-on-new-expectations.patch +++ /dev/null @@ -1,169 +0,0 @@ -From dbc7553b9ac766a071e3fdd0467041890bf514da Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:37 +0200 -Subject: [PATCH] netfilter: ctnetlink: ignore explicit helper on new - expectations - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 917b61fa2042 - -commit 917b61fa2042f11e2af4c428e43f08199586633a -Author: Pablo Neira Ayuso -Date: Mon Mar 30 11:26:22 2026 +0200 - - netfilter: ctnetlink: ignore explicit helper on new expectations - - Use the existing master conntrack helper, anything else is not really - supported and it just makes validation more complicated, so just ignore - what helper userspace suggests for this expectation. - - This was uncovered when validating CTA_EXPECT_CLASS via different helper - provided by userspace than the existing master conntrack helper: - - BUG: KASAN: slab-out-of-bounds in nf_ct_expect_related_report+0x2479/0x27c0 - Read of size 4 at addr ffff8880043fe408 by task poc/102 - Call Trace: - nf_ct_expect_related_report+0x2479/0x27c0 - ctnetlink_create_expect+0x22b/0x3b0 - ctnetlink_new_expect+0x4bd/0x5c0 - nfnetlink_rcv_msg+0x67a/0x950 - netlink_rcv_skb+0x120/0x350 - - Allowing to read kernel memory bytes off the expectation boundary. - - CTA_EXPECT_HELP_NAME is still used to offer the helper name to userspace - via netlink dump. - - Fixes: bd0779370588 ("netfilter: nfnetlink_queue: allow to attach expectations to conntracks") - Reported-by: Qi Tang - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c -index 208e26a..dcef3ef 100644 ---- a/net/netfilter/nf_conntrack_netlink.c -+++ b/net/netfilter/nf_conntrack_netlink.c -@@ -2655,7 +2655,6 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = { - - static struct nf_conntrack_expect * - ctnetlink_alloc_expect(const struct nlattr *const cda[], struct nf_conn *ct, -- struct nf_conntrack_helper *helper, - struct nf_conntrack_tuple *tuple, - struct nf_conntrack_tuple *mask); - -@@ -2884,7 +2883,6 @@ ctnetlink_glue_attach_expect(const struct nlattr *attr, struct nf_conn *ct, - { - struct nlattr *cda[CTA_EXPECT_MAX+1]; - struct nf_conntrack_tuple tuple, mask; -- struct nf_conntrack_helper *helper = NULL; - struct nf_conntrack_expect *exp; - int err; - -@@ -2898,17 +2896,8 @@ ctnetlink_glue_attach_expect(const struct nlattr *attr, struct nf_conn *ct, - if (err < 0) - return err; - -- if (cda[CTA_EXPECT_HELP_NAME]) { -- const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]); -- -- helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct), -- nf_ct_protonum(ct)); -- if (helper == NULL) -- return -EOPNOTSUPP; -- } -- - exp = ctnetlink_alloc_expect((const struct nlattr * const *)cda, ct, -- helper, &tuple, &mask); -+ &tuple, &mask); - if (IS_ERR(exp)) - return PTR_ERR(exp); - -@@ -3547,11 +3536,11 @@ ctnetlink_parse_expect_nat(const struct nlattr *attr, - - static struct nf_conntrack_expect * - ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, -- struct nf_conntrack_helper *helper, - struct nf_conntrack_tuple *tuple, - struct nf_conntrack_tuple *mask) - { - struct net *net = read_pnet(&ct->ct_net); -+ struct nf_conntrack_helper *helper; - struct nf_conntrack_expect *exp; - struct nf_conn_help *help; - u32 class = 0; -@@ -3561,7 +3550,11 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, - if (!help) - return ERR_PTR(-EOPNOTSUPP); - -- if (cda[CTA_EXPECT_CLASS] && helper) { -+ helper = rcu_dereference(help->helper); -+ if (!helper) -+ return ERR_PTR(-EOPNOTSUPP); -+ -+ if (cda[CTA_EXPECT_CLASS]) { - class = ntohl(nla_get_be32(cda[CTA_EXPECT_CLASS])); - if (class > helper->expect_class_max) - return ERR_PTR(-EINVAL); -@@ -3595,8 +3588,6 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, - #ifdef CONFIG_NF_CONNTRACK_ZONES - exp->zone = ct->zone; - #endif -- if (!helper) -- helper = rcu_dereference(help->helper); - rcu_assign_pointer(exp->helper, helper); - exp->tuple = *tuple; - exp->mask.src.u3 = mask->src.u3; -@@ -3628,7 +3619,6 @@ ctnetlink_create_expect(struct net *net, - { - struct nf_conntrack_tuple tuple, mask, master_tuple; - struct nf_conntrack_tuple_hash *h = NULL; -- struct nf_conntrack_helper *helper = NULL; - struct nf_conntrack_expect *exp; - struct nf_conn *ct; - int err; -@@ -3654,33 +3644,7 @@ ctnetlink_create_expect(struct net *net, - ct = nf_ct_tuplehash_to_ctrack(h); - - rcu_read_lock(); -- if (cda[CTA_EXPECT_HELP_NAME]) { -- const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]); -- -- helper = __nf_conntrack_helper_find(helpname, u3, -- nf_ct_protonum(ct)); -- if (helper == NULL) { -- rcu_read_unlock(); --#ifdef CONFIG_MODULES -- if (request_module("nfct-helper-%s", helpname) < 0) { -- err = -EOPNOTSUPP; -- goto err_ct; -- } -- rcu_read_lock(); -- helper = __nf_conntrack_helper_find(helpname, u3, -- nf_ct_protonum(ct)); -- if (helper) { -- err = -EAGAIN; -- goto err_rcu; -- } -- rcu_read_unlock(); --#endif -- err = -EOPNOTSUPP; -- goto err_ct; -- } -- } -- -- exp = ctnetlink_alloc_expect(cda, ct, helper, &tuple, &mask); -+ exp = ctnetlink_alloc_expect(cda, ct, &tuple, &mask); - if (IS_ERR(exp)) { - err = PTR_ERR(exp); - goto err_rcu; -@@ -3690,8 +3654,8 @@ ctnetlink_create_expect(struct net *net, - nf_ct_expect_put(exp); - err_rcu: - rcu_read_unlock(); --err_ct: - nf_ct_put(ct); -+ - return err; - } - diff --git a/1124-netfilter-x-tables-restrict-xt-check-match-xt-check-target-extensions-for-nfprot.patch b/1124-netfilter-x-tables-restrict-xt-check-match-xt-check-target-extensions-for-nfprot.patch deleted file mode 100644 index 9b8d5bce0..000000000 --- a/1124-netfilter-x-tables-restrict-xt-check-match-xt-check-target-extensions-for-nfprot.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 55107f6cfe5236b5522a7b83bdc908ea36acf54c Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:40 +0200 -Subject: [PATCH] netfilter: x_tables: restrict xt_check_match/xt_check_target - extensions for NFPROTO_ARP - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 3d5d488f1177 - -commit 3d5d488f11776738deab9da336038add95d342d1 -Author: Pablo Neira Ayuso -Date: Tue Mar 31 16:41:25 2026 +0200 - - netfilter: x_tables: restrict xt_check_match/xt_check_target extensions for NFPROTO_ARP - - Weiming Shi says: - - xt_match and xt_target structs registered with NFPROTO_UNSPEC can be - loaded by any protocol family through nft_compat. When such a - match/target sets .hooks to restrict which hooks it may run on, the - bitmask uses NF_INET_* constants. This is only correct for families - whose hook layout matches NF_INET_*: IPv4, IPv6, INET, and bridge - all share the same five hooks (PRE_ROUTING ... POST_ROUTING). - - ARP only has three hooks (IN=0, OUT=1, FORWARD=2) with different - semantics. Because NF_ARP_OUT == 1 == NF_INET_LOCAL_IN, the .hooks - validation silently passes for the wrong reasons, allowing matches to - run on ARP chains where the hook assumptions (e.g. state->in being - set on input hooks) do not hold. This leads to NULL pointer - dereferences; xt_devgroup is one concrete example: - - Oops: general protection fault, probably for non-canonical address 0xdffffc0000000044: 0000 [#1] SMP KASAN NOPTI - KASAN: null-ptr-deref in range [0x0000000000000220-0x0000000000000227] - RIP: 0010:devgroup_mt+0xff/0x350 - Call Trace: - - nft_match_eval (net/netfilter/nft_compat.c:407) - nft_do_chain (net/netfilter/nf_tables_core.c:285) - nft_do_chain_arp (net/netfilter/nft_chain_filter.c:61) - nf_hook_slow (net/netfilter/core.c:623) - arp_xmit (net/ipv4/arp.c:666) - - Kernel panic - not syncing: Fatal exception in interrupt - - Fix it by restricting arptables to NFPROTO_ARP extensions only. - Note that arptables-legacy only supports: - - - arpt_CLASSIFY - - arpt_mangle - - arpt_MARK - - that provide explicit NFPROTO_ARP match/target declarations. - - Fixes: 9291747f118d ("netfilter: xtables: add device group match") - Reported-by: Xiang Mei - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c -index 7098406..10530a0 100644 ---- a/net/netfilter/x_tables.c -+++ b/net/netfilter/x_tables.c -@@ -501,6 +501,17 @@ int xt_check_match(struct xt_mtchk_param *par, - par->match->table, par->table); - return -EINVAL; - } -+ -+ /* NFPROTO_UNSPEC implies NF_INET_* hooks which do not overlap with -+ * NF_ARP_IN,OUT,FORWARD, allow explicit extensions with NFPROTO_ARP -+ * support. -+ */ -+ if (par->family == NFPROTO_ARP && -+ par->match->family != NFPROTO_ARP) { -+ pr_info_ratelimited("%s_tables: %s match: not valid for this family\n", -+ xt_prefix[par->family], par->match->name); -+ return -EINVAL; -+ } - if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) { - char used[64], allow[64]; - -@@ -1016,6 +1027,18 @@ int xt_check_target(struct xt_tgchk_param *par, - par->target->table, par->table); - return -EINVAL; - } -+ -+ /* NFPROTO_UNSPEC implies NF_INET_* hooks which do not overlap with -+ * NF_ARP_IN,OUT,FORWARD, allow explicit extensions with NFPROTO_ARP -+ * support. -+ */ -+ if (par->family == NFPROTO_ARP && -+ par->target->family != NFPROTO_ARP) { -+ pr_info_ratelimited("%s_tables: %s target: not valid for this family\n", -+ xt_prefix[par->family], par->target->name); -+ return -EINVAL; -+ } -+ - if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) { - char used[64], allow[64]; - diff --git a/1125-netfilter-nf-tables-reject-immediate-nf-queue-verdict.patch b/1125-netfilter-nf-tables-reject-immediate-nf-queue-verdict.patch deleted file mode 100644 index 638498b02..000000000 --- a/1125-netfilter-nf-tables-reject-immediate-nf-queue-verdict.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 94a7ba900e7ea7da14a796edc10401a700d3b894 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:43 +0200 -Subject: [PATCH] netfilter: nf_tables: reject immediate NF_QUEUE verdict - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit da107398cbd4 - -commit da107398cbd4bbdb6bffecb2ce86d5c9384f4cec -Author: Pablo Neira Ayuso -Date: Tue Mar 31 23:08:02 2026 +0200 - - netfilter: nf_tables: reject immediate NF_QUEUE verdict - - nft_queue is always used from userspace nftables to deliver the NF_QUEUE - verdict. Immediately emitting an NF_QUEUE verdict is never used by the - userspace nft tools, so reject immediate NF_QUEUE verdicts. - - The arp family does not provide queue support, but such an immediate - verdict is still reachable. Globally reject NF_QUEUE immediate verdicts - to address this issue. - - Fixes: f342de4e2f33 ("netfilter: nf_tables: reject QUEUE/DROP verdict parameters") - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 81164ad..7cc4163 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -11804,8 +11804,6 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, - switch (data->verdict.code) { - case NF_ACCEPT: - case NF_DROP: -- case NF_QUEUE: -- break; - case NFT_CONTINUE: - case NFT_BREAK: - case NFT_RETURN: -@@ -11840,6 +11838,11 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, - - data->verdict.chain = chain; - break; -+ case NF_QUEUE: -+ /* The nft_queue expression is used for this purpose, an -+ * immediate NF_QUEUE verdict should not ever be seen here. -+ */ -+ fallthrough; - default: - return -EINVAL; - } diff --git a/1126-netfilter-nfnetlink-log-initialize-nfgenmsg-in-nlmsg-done-terminator.patch b/1126-netfilter-nfnetlink-log-initialize-nfgenmsg-in-nlmsg-done-terminator.patch deleted file mode 100644 index d99667614..000000000 --- a/1126-netfilter-nfnetlink-log-initialize-nfgenmsg-in-nlmsg-done-terminator.patch +++ /dev/null @@ -1,52 +0,0 @@ -From a9469302e0f5583c2d4a0796bf8e723f2a90e01c Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:20:51 +0200 -Subject: [PATCH] netfilter: nfnetlink_log: initialize nfgenmsg in NLMSG_DONE - terminator - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 1f3083aec883 - -commit 1f3083aec8836213da441270cdb1ab612dd82cf4 -Author: Xiang Mei -Date: Wed Apr 1 14:20:57 2026 -0700 - - netfilter: nfnetlink_log: initialize nfgenmsg in NLMSG_DONE terminator - - When batching multiple NFLOG messages (inst->qlen > 1), __nfulnl_send() - appends an NLMSG_DONE terminator with sizeof(struct nfgenmsg) payload via - nlmsg_put(), but never initializes the nfgenmsg bytes. The nlmsg_put() - helper only zeroes alignment padding after the payload, not the payload - itself, so four bytes of stale kernel heap data are leaked to userspace - in the NLMSG_DONE message body. - - Use nfnl_msg_put() to build the NLMSG_DONE terminator, which initializes - the nfgenmsg payload via nfnl_fill_hdr(), consistent with how - __build_packet_message() already constructs NFULNL_MSG_PACKET headers. - - Fixes: 29c5d4afba51 ("[NETFILTER]: nfnetlink_log: fix sending of multipart messages") - Reported-by: Weiming Shi - Signed-off-by: Xiang Mei - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c -index dcd2493..b1f3eda 100644 ---- a/net/netfilter/nfnetlink_log.c -+++ b/net/netfilter/nfnetlink_log.c -@@ -361,10 +361,10 @@ static void - __nfulnl_send(struct nfulnl_instance *inst) - { - if (inst->qlen > 1) { -- struct nlmsghdr *nlh = nlmsg_put(inst->skb, 0, 0, -- NLMSG_DONE, -- sizeof(struct nfgenmsg), -- 0); -+ struct nlmsghdr *nlh = nfnl_msg_put(inst->skb, 0, 0, -+ NLMSG_DONE, 0, -+ AF_UNSPEC, NFNETLINK_V0, -+ htons(inst->group_num)); - if (WARN_ONCE(!nlh, "bad nlskb size: %u, tailroom %d\n", - inst->skb->len, skb_tailroom(inst->skb))) { - kfree_skb(inst->skb); diff --git a/1127-netfilter-xt-multiport-validate-range-encoding-in-checkentry.patch b/1127-netfilter-xt-multiport-validate-range-encoding-in-checkentry.patch deleted file mode 100644 index b5482d0f7..000000000 --- a/1127-netfilter-xt-multiport-validate-range-encoding-in-checkentry.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 8fa17e23a20d7981a2193301408f1f339ea2d057 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:20:52 +0200 -Subject: [PATCH] netfilter: xt_multiport: validate range encoding in - checkentry - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit ff64c5bfef12 - -commit ff64c5bfef12461df8450e0f50bb693b5269c720 -Author: Ren Wei -Date: Fri Apr 3 23:52:52 2026 +0800 - - netfilter: xt_multiport: validate range encoding in checkentry - - ports_match_v1() treats any non-zero pflags entry as the start of a - port range and unconditionally consumes the next ports[] element as - the range end. - - The checkentry path currently validates protocol, flags and count, but - it does not validate the range encoding itself. As a result, malformed - rules can mark the last slot as a range start or place two range starts - back to back, leaving ports_match_v1() to step past the last valid - ports[] element while interpreting the rule. - - Reject malformed multiport v1 rules in checkentry by validating that - each range start has a following element and that the following element - is not itself marked as another range start. - - Fixes: a89ecb6a2ef7 ("[NETFILTER]: x_tables: unify IPv4/IPv6 multiport match") - Reported-by: Yifan Wu - Reported-by: Juefei Pu - Co-developed-by: Yuan Tan - Signed-off-by: Yuan Tan - Suggested-by: Xin Liu - Tested-by: Yuhang Zheng - Signed-off-by: Ren Wei - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/xt_multiport.c b/net/netfilter/xt_multiport.c -index 44a00f5..a1691ff 100644 ---- a/net/netfilter/xt_multiport.c -+++ b/net/netfilter/xt_multiport.c -@@ -105,6 +105,28 @@ multiport_mt(const struct sk_buff *skb, struct xt_action_param *par) - return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1])); - } - -+static bool -+multiport_valid_ranges(const struct xt_multiport_v1 *multiinfo) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < multiinfo->count; i++) { -+ if (!multiinfo->pflags[i]) -+ continue; -+ -+ if (++i >= multiinfo->count) -+ return false; -+ -+ if (multiinfo->pflags[i]) -+ return false; -+ -+ if (multiinfo->ports[i - 1] > multiinfo->ports[i]) -+ return false; -+ } -+ -+ return true; -+} -+ - static inline bool - check(u_int16_t proto, - u_int8_t ip_invflags, -@@ -127,8 +149,10 @@ static int multiport_mt_check(const struct xt_mtchk_param *par) - const struct ipt_ip *ip = par->entryinfo; - const struct xt_multiport_v1 *multiinfo = par->matchinfo; - -- return check(ip->proto, ip->invflags, multiinfo->flags, -- multiinfo->count) ? 0 : -EINVAL; -+ if (!check(ip->proto, ip->invflags, multiinfo->flags, multiinfo->count)) -+ return -EINVAL; -+ -+ return multiport_valid_ranges(multiinfo) ? 0 : -EINVAL; - } - - static int multiport_mt6_check(const struct xt_mtchk_param *par) -@@ -136,8 +160,10 @@ static int multiport_mt6_check(const struct xt_mtchk_param *par) - const struct ip6t_ip6 *ip = par->entryinfo; - const struct xt_multiport_v1 *multiinfo = par->matchinfo; - -- return check(ip->proto, ip->invflags, multiinfo->flags, -- multiinfo->count) ? 0 : -EINVAL; -+ if (!check(ip->proto, ip->invflags, multiinfo->flags, multiinfo->count)) -+ return -EINVAL; -+ -+ return multiport_valid_ranges(multiinfo) ? 0 : -EINVAL; - } - - static struct xt_match multiport_mt_reg[] __read_mostly = { diff --git a/1128-netfilter-nft-ct-fix-use-after-free-in-timeout-object-destroy.patch b/1128-netfilter-nft-ct-fix-use-after-free-in-timeout-object-destroy.patch deleted file mode 100644 index 6c6244795..000000000 --- a/1128-netfilter-nft-ct-fix-use-after-free-in-timeout-object-destroy.patch +++ /dev/null @@ -1,80 +0,0 @@ -From b79e7ff0af28845109dc3fcd964751f0391ceebf Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:20:53 +0200 -Subject: [PATCH] netfilter: nft_ct: fix use-after-free in timeout object - destroy - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit f8dca15a1b19 - -commit f8dca15a1b190787bbd03285304b569631160eda -Author: Tuan Do -Date: Fri Apr 3 00:33:17 2026 -0700 - - netfilter: nft_ct: fix use-after-free in timeout object destroy - - nft_ct_timeout_obj_destroy() frees the timeout object with kfree() - immediately after nf_ct_untimeout(), without waiting for an RCU grace - period. Concurrent packet processing on other CPUs may still hold - RCU-protected references to the timeout object obtained via - rcu_dereference() in nf_ct_timeout_data(). - - Add an rcu_head to struct nf_ct_timeout and use kfree_rcu() to defer - freeing until after an RCU grace period, matching the approach already - used in nfnetlink_cttimeout.c. - - KASAN report: - BUG: KASAN: slab-use-after-free in nf_conntrack_tcp_packet+0x1381/0x29d0 - Read of size 4 at addr ffff8881035fe19c by task exploit/80 - - Call Trace: - nf_conntrack_tcp_packet+0x1381/0x29d0 - nf_conntrack_in+0x612/0x8b0 - nf_hook_slow+0x70/0x100 - __ip_local_out+0x1b2/0x210 - tcp_sendmsg_locked+0x722/0x1580 - __sys_sendto+0x2d8/0x320 - - Allocated by task 75: - nft_ct_timeout_obj_init+0xf6/0x290 - nft_obj_init+0x107/0x1b0 - nf_tables_newobj+0x680/0x9c0 - nfnetlink_rcv_batch+0xc29/0xe00 - - Freed by task 26: - nft_obj_destroy+0x3f/0xa0 - nf_tables_trans_destroy_work+0x51c/0x5c0 - process_one_work+0x2c4/0x5a0 - - Fixes: 7e0b2b57f01d ("netfilter: nft_ct: add ct timeout support") - Cc: stable@vger.kernel.org - Signed-off-by: Tuan Do - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/include/net/netfilter/nf_conntrack_timeout.h b/include/net/netfilter/nf_conntrack_timeout.h -index 9fdaba9..3a66d4a 100644 ---- a/include/net/netfilter/nf_conntrack_timeout.h -+++ b/include/net/netfilter/nf_conntrack_timeout.h -@@ -14,6 +14,7 @@ - struct nf_ct_timeout { - __u16 l3num; - const struct nf_conntrack_l4proto *l4proto; -+ struct rcu_head rcu; - char data[]; - }; - -diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c -index 6f2ae7c..d0090d0 100644 ---- a/net/netfilter/nft_ct.c -+++ b/net/netfilter/nft_ct.c -@@ -1018,7 +1018,7 @@ static void nft_ct_timeout_obj_destroy(const struct nft_ctx *ctx, - - nf_ct_untimeout(ctx->net, timeout); - nf_ct_netns_put(ctx->net, ctx->family); -- kfree(priv->timeout); -+ kfree_rcu(priv->timeout, rcu); - } - - static int nft_ct_timeout_obj_dump(struct sk_buff *skb, diff --git a/1129-netfilter-nft-osf-restrict-it-to-ipv4.patch b/1129-netfilter-nft-osf-restrict-it-to-ipv4.patch deleted file mode 100644 index ca8e75e17..000000000 --- a/1129-netfilter-nft-osf-restrict-it-to-ipv4.patch +++ /dev/null @@ -1,47 +0,0 @@ -From dc881297140fa0d80136180c1e2e1d66c5adac44 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:15 +0200 -Subject: [PATCH] netfilter: nft_osf: restrict it to ipv4 - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit b336fdbb7103 - -commit b336fdbb7103fb1484e1dcb6741151d4b5a41e35 -Author: Pablo Neira Ayuso -Date: Tue Apr 14 13:06:38 2026 +0200 - - netfilter: nft_osf: restrict it to ipv4 - - This expression only supports for ipv4, restrict it. - - Fixes: b96af92d6eaf ("netfilter: nf_tables: implement Passive OS fingerprint module in nft_osf") - Acked-by: Florian Westphal - Reviewed-by: Fernando Fernandez Mancera - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c -index 1c0b493..bdc2f6c 100644 ---- a/net/netfilter/nft_osf.c -+++ b/net/netfilter/nft_osf.c -@@ -28,6 +28,11 @@ static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs, - struct nf_osf_data data; - struct tcphdr _tcph; - -+ if (nft_pf(pkt) != NFPROTO_IPV4) { -+ regs->verdict.code = NFT_BREAK; -+ return; -+ } -+ - if (pkt->tprot != IPPROTO_TCP) { - regs->verdict.code = NFT_BREAK; - return; -@@ -114,7 +119,6 @@ static int nft_osf_validate(const struct nft_ctx *ctx, - - switch (ctx->family) { - case NFPROTO_IPV4: -- case NFPROTO_IPV6: - case NFPROTO_INET: - hooks = (1 << NF_INET_LOCAL_IN) | - (1 << NF_INET_PRE_ROUTING) | diff --git a/1130-nfnetlink-osf-validate-individual-option-lengths-in-fingerprints.patch b/1130-nfnetlink-osf-validate-individual-option-lengths-in-fingerprints.patch deleted file mode 100644 index fd08fa22b..000000000 --- a/1130-nfnetlink-osf-validate-individual-option-lengths-in-fingerprints.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 05577640875b9759b4511a3cbe9cbcd2f92e27f3 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:11 +0200 -Subject: [PATCH] nfnetlink_osf: validate individual option lengths in - fingerprints - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit dbdfaae96096 - -commit dbdfaae9609629a9569362e3b8f33d0a20fd783c -Author: Weiming Shi -Date: Thu Mar 19 15:32:44 2026 +0800 - - nfnetlink_osf: validate individual option lengths in fingerprints - - nfnl_osf_add_callback() validates opt_num bounds and string - NUL-termination but does not check individual option length fields. - A zero-length option causes nf_osf_match_one() to enter the option - matching loop even when foptsize sums to zero, which matches packets - with no TCP options where ctx->optp is NULL: - - Oops: general protection fault - KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] - RIP: 0010:nf_osf_match_one (net/netfilter/nfnetlink_osf.c:98) - Call Trace: - nf_osf_match (net/netfilter/nfnetlink_osf.c:227) - xt_osf_match_packet (net/netfilter/xt_osf.c:32) - ipt_do_table (net/ipv4/netfilter/ip_tables.c:293) - nf_hook_slow (net/netfilter/core.c:623) - ip_local_deliver (net/ipv4/ip_input.c:262) - ip_rcv (net/ipv4/ip_input.c:573) - - Additionally, an MSS option (kind=2) with length < 4 causes - out-of-bounds reads when nf_osf_match_one() unconditionally accesses - optp[2] and optp[3] for MSS value extraction. While RFC 9293 - section 3.2 specifies that the MSS option is always exactly 4 - bytes (Kind=2, Length=4), the check uses "< 4" rather than - "!= 4" because lengths greater than 4 do not cause memory - safety issues -- the buffer is guaranteed to be at least - foptsize bytes by the ctx->optsize == foptsize check. - - Reject fingerprints where any option has zero length, or where an MSS - option has length less than 4, at add time rather than trusting these - values in the packet matching hot path. - - Fixes: 11eeef41d5f6 ("netfilter: passive OS fingerprint xtables match") - Reported-by: Xiang Mei - Signed-off-by: Weiming Shi - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c -index c0fc431..9fc9544 100644 ---- a/net/netfilter/nfnetlink_osf.c -+++ b/net/netfilter/nfnetlink_osf.c -@@ -302,7 +302,9 @@ static int nfnl_osf_add_callback(struct sk_buff *skb, - { - struct nf_osf_user_finger *f; - struct nf_osf_finger *kf = NULL, *sf; -+ unsigned int tot_opt_len = 0; - int err = 0; -+ int i; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; -@@ -318,6 +320,17 @@ static int nfnl_osf_add_callback(struct sk_buff *skb, - if (f->opt_num > ARRAY_SIZE(f->opt)) - return -EINVAL; - -+ for (i = 0; i < f->opt_num; i++) { -+ if (!f->opt[i].length || f->opt[i].length > MAX_IPOPTLEN) -+ return -EINVAL; -+ if (f->opt[i].kind == OSFOPT_MSS && f->opt[i].length < 4) -+ return -EINVAL; -+ -+ tot_opt_len += f->opt[i].length; -+ if (tot_opt_len > MAX_IPOPTLEN) -+ return -EINVAL; -+ } -+ - if (!memchr(f->genre, 0, MAXGENRELEN) || - !memchr(f->subtype, 0, MAXGENRELEN) || - !memchr(f->version, 0, MAXGENRELEN)) diff --git a/1131-netfilter-nfnetlink-osf-fix-divide-by-zero-in-osf-wss-modulo.patch b/1131-netfilter-nfnetlink-osf-fix-divide-by-zero-in-osf-wss-modulo.patch deleted file mode 100644 index b7108c94f..000000000 --- a/1131-netfilter-nfnetlink-osf-fix-divide-by-zero-in-osf-wss-modulo.patch +++ /dev/null @@ -1,68 +0,0 @@ -From aea9be3048d15f93e770970a6206c38bdaa11cb2 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:16 +0200 -Subject: [PATCH] netfilter: nfnetlink_osf: fix divide-by-zero in - OSF_WSS_MODULO - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 2195574dc6d9 - -commit 2195574dc6d9017d32ac346987e12659f931d932 -Author: Xiang Mei -Date: Tue Apr 14 15:14:01 2026 -0700 - - netfilter: nfnetlink_osf: fix divide-by-zero in OSF_WSS_MODULO - - nf_osf_match_one() computes ctx->window % f->wss.val in the - OSF_WSS_MODULO branch with no guard for f->wss.val == 0. A - CAP_NET_ADMIN user can add such a fingerprint via nfnetlink; a - subsequent matching TCP SYN divides by zero and panics the kernel. - - Reject the bogus fingerprint in nfnl_osf_add_callback() above the - per-option for-loop. f->wss is per-fingerprint, not per-option, so - the check must run regardless of f->opt_num (including 0). Also - reject wss.wc >= OSF_WSS_MAX; nf_osf_match_one() already treats that - as "should not happen". - - Crash: - Oops: divide error: 0000 [#1] SMP KASAN NOPTI - RIP: 0010:nf_osf_match_one (net/netfilter/nfnetlink_osf.c:98) - Call Trace: - - nf_osf_match (net/netfilter/nfnetlink_osf.c:220) - xt_osf_match_packet (net/netfilter/xt_osf.c:32) - ipt_do_table (net/ipv4/netfilter/ip_tables.c:348) - nf_hook_slow (net/netfilter/core.c:622) - ip_local_deliver (net/ipv4/ip_input.c:265) - ip_rcv (include/linux/skbuff.h:1162) - __netif_receive_skb_one_core (net/core/dev.c:6181) - process_backlog (net/core/dev.c:6642) - __napi_poll (net/core/dev.c:7710) - net_rx_action (net/core/dev.c:7945) - handle_softirqs (kernel/softirq.c:622) - - Fixes: 11eeef41d5f6 ("netfilter: passive OS fingerprint xtables match") - Reported-by: Weiming Shi - Suggested-by: Florian Westphal - Suggested-by: Pablo Neira Ayuso - Signed-off-by: Xiang Mei - Reviewed-by: Fernando Fernandez Mancera - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c -index 9fc9544..2305c7d 100644 ---- a/net/netfilter/nfnetlink_osf.c -+++ b/net/netfilter/nfnetlink_osf.c -@@ -320,6 +320,10 @@ static int nfnl_osf_add_callback(struct sk_buff *skb, - if (f->opt_num > ARRAY_SIZE(f->opt)) - return -EINVAL; - -+ if (f->wss.wc >= OSF_WSS_MAX || -+ (f->wss.wc == OSF_WSS_MODULO && f->wss.val == 0)) -+ return -EINVAL; -+ - for (i = 0; i < f->opt_num; i++) { - if (!f->opt[i].length || f->opt[i].length > MAX_IPOPTLEN) - return -EINVAL; diff --git a/1132-netfilter-conntrack-remove-sprintf-usage.patch b/1132-netfilter-conntrack-remove-sprintf-usage.patch deleted file mode 100644 index bb924b32b..000000000 --- a/1132-netfilter-conntrack-remove-sprintf-usage.patch +++ /dev/null @@ -1,181 +0,0 @@ -From 1fa34c650b5f6cf04b877fa6cb5337ee834c826d Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:16 +0200 -Subject: [PATCH] netfilter: conntrack: remove sprintf usage - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 6e7066bdb481 - -commit 6e7066bdb481a87fe88c4fa563e348c03b2d373d -Author: Florian Westphal -Date: Tue Apr 14 19:13:46 2026 +0200 - - netfilter: conntrack: remove sprintf usage - - Replace it with scnprintf, the buffer sizes are expected to be large enough - to hold the result, no need for snprintf+overflow check. - - Increase buffer size in mangle_content_len() while at it. - - BUG: KASAN: stack-out-of-bounds in vsnprintf+0xea5/0x1270 - Write of size 1 at addr [..] - vsnprintf+0xea5/0x1270 - sprintf+0xb1/0xe0 - mangle_content_len+0x1ac/0x280 - nf_nat_sdp_session+0x1cc/0x240 - process_sdp+0x8f8/0xb80 - process_invite_request+0x108/0x2b0 - process_sip_msg+0x5da/0xf50 - sip_help_tcp+0x45e/0x780 - nf_confirm+0x34d/0x990 - [..] - - Fixes: 9fafcd7b2032 ("[NETFILTER]: nf_conntrack/nf_nat: add SIP helper port") - Reported-by: Yiming Qian - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_nat_amanda.c b/net/netfilter/nf_nat_amanda.c -index 98deef6..8f10549 100644 ---- a/net/netfilter/nf_nat_amanda.c -+++ b/net/netfilter/nf_nat_amanda.c -@@ -50,7 +50,7 @@ static unsigned int help(struct sk_buff *skb, - return NF_DROP; - } - -- sprintf(buffer, "%u", port); -+ snprintf(buffer, sizeof(buffer), "%u", port); - if (!nf_nat_mangle_udp_packet(skb, exp->master, ctinfo, - protoff, matchoff, matchlen, - buffer, strlen(buffer))) { -diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c -index cf4aeb2..c845b6d 100644 ---- a/net/netfilter/nf_nat_sip.c -+++ b/net/netfilter/nf_nat_sip.c -@@ -68,25 +68,27 @@ static unsigned int mangle_packet(struct sk_buff *skb, unsigned int protoff, - } - - static int sip_sprintf_addr(const struct nf_conn *ct, char *buffer, -+ size_t size, - const union nf_inet_addr *addr, bool delim) - { - if (nf_ct_l3num(ct) == NFPROTO_IPV4) -- return sprintf(buffer, "%pI4", &addr->ip); -+ return scnprintf(buffer, size, "%pI4", &addr->ip); - else { - if (delim) -- return sprintf(buffer, "[%pI6c]", &addr->ip6); -+ return scnprintf(buffer, size, "[%pI6c]", &addr->ip6); - else -- return sprintf(buffer, "%pI6c", &addr->ip6); -+ return scnprintf(buffer, size, "%pI6c", &addr->ip6); - } - } - - static int sip_sprintf_addr_port(const struct nf_conn *ct, char *buffer, -+ size_t size, - const union nf_inet_addr *addr, u16 port) - { - if (nf_ct_l3num(ct) == NFPROTO_IPV4) -- return sprintf(buffer, "%pI4:%u", &addr->ip, port); -+ return scnprintf(buffer, size, "%pI4:%u", &addr->ip, port); - else -- return sprintf(buffer, "[%pI6c]:%u", &addr->ip6, port); -+ return scnprintf(buffer, size, "[%pI6c]:%u", &addr->ip6, port); - } - - static int map_addr(struct sk_buff *skb, unsigned int protoff, -@@ -119,7 +121,7 @@ static int map_addr(struct sk_buff *skb, unsigned int protoff, - if (nf_inet_addr_cmp(&newaddr, addr) && newport == port) - return 1; - -- buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, ntohs(newport)); -+ buflen = sip_sprintf_addr_port(ct, buffer, sizeof(buffer), &newaddr, ntohs(newport)); - return mangle_packet(skb, protoff, dataoff, dptr, datalen, - matchoff, matchlen, buffer, buflen); - } -@@ -212,7 +214,7 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff, - &addr, true) > 0 && - nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.src.u3) && - !nf_inet_addr_cmp(&addr, &ct->tuplehash[!dir].tuple.dst.u3)) { -- buflen = sip_sprintf_addr(ct, buffer, -+ buflen = sip_sprintf_addr(ct, buffer, sizeof(buffer), - &ct->tuplehash[!dir].tuple.dst.u3, - true); - if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, -@@ -229,7 +231,7 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff, - &addr, false) > 0 && - nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.dst.u3) && - !nf_inet_addr_cmp(&addr, &ct->tuplehash[!dir].tuple.src.u3)) { -- buflen = sip_sprintf_addr(ct, buffer, -+ buflen = sip_sprintf_addr(ct, buffer, sizeof(buffer), - &ct->tuplehash[!dir].tuple.src.u3, - false); - if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, -@@ -247,7 +249,7 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff, - htons(n) == ct->tuplehash[dir].tuple.dst.u.udp.port && - htons(n) != ct->tuplehash[!dir].tuple.src.u.udp.port) { - __be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port; -- buflen = sprintf(buffer, "%u", ntohs(p)); -+ buflen = scnprintf(buffer, sizeof(buffer), "%u", ntohs(p)); - if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, - poff, plen, buffer, buflen)) { - nf_ct_helper_log(skb, ct, "cannot mangle rport"); -@@ -418,7 +420,8 @@ static unsigned int nf_nat_sip_expect(struct sk_buff *skb, unsigned int protoff, - - if (!nf_inet_addr_cmp(&exp->tuple.dst.u3, &exp->saved_addr) || - exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) { -- buflen = sip_sprintf_addr_port(ct, buffer, &newaddr, port); -+ buflen = sip_sprintf_addr_port(ct, buffer, sizeof(buffer), -+ &newaddr, port); - if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, - matchoff, matchlen, buffer, buflen)) { - nf_ct_helper_log(skb, ct, "cannot mangle packet"); -@@ -438,8 +441,8 @@ static int mangle_content_len(struct sk_buff *skb, unsigned int protoff, - { - enum ip_conntrack_info ctinfo; - struct nf_conn *ct = nf_ct_get(skb, &ctinfo); -+ char buffer[sizeof("4294967295")]; - unsigned int matchoff, matchlen; -- char buffer[sizeof("65536")]; - int buflen, c_len; - - /* Get actual SDP length */ -@@ -454,7 +457,7 @@ static int mangle_content_len(struct sk_buff *skb, unsigned int protoff, - &matchoff, &matchlen) <= 0) - return 0; - -- buflen = sprintf(buffer, "%u", c_len); -+ buflen = scnprintf(buffer, sizeof(buffer), "%u", c_len); - return mangle_packet(skb, protoff, dataoff, dptr, datalen, - matchoff, matchlen, buffer, buflen); - } -@@ -491,7 +494,7 @@ static unsigned int nf_nat_sdp_addr(struct sk_buff *skb, unsigned int protoff, - char buffer[INET6_ADDRSTRLEN]; - unsigned int buflen; - -- buflen = sip_sprintf_addr(ct, buffer, addr, false); -+ buflen = sip_sprintf_addr(ct, buffer, sizeof(buffer), addr, false); - if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, - sdpoff, type, term, buffer, buflen)) - return 0; -@@ -509,7 +512,7 @@ static unsigned int nf_nat_sdp_port(struct sk_buff *skb, unsigned int protoff, - char buffer[sizeof("nnnnn")]; - unsigned int buflen; - -- buflen = sprintf(buffer, "%u", port); -+ buflen = scnprintf(buffer, sizeof(buffer), "%u", port); - if (!mangle_packet(skb, protoff, dataoff, dptr, datalen, - matchoff, matchlen, buffer, buflen)) - return 0; -@@ -529,7 +532,7 @@ static unsigned int nf_nat_sdp_session(struct sk_buff *skb, unsigned int protoff - unsigned int buflen; - - /* Mangle session description owner and contact addresses */ -- buflen = sip_sprintf_addr(ct, buffer, addr, false); -+ buflen = sip_sprintf_addr(ct, buffer, sizeof(buffer), addr, false); - if (mangle_sdp_packet(skb, protoff, dataoff, dptr, datalen, sdpoff, - SDP_HDR_OWNER, SDP_HDR_MEDIA, buffer, buflen)) - return 0; diff --git a/1133-netfilter-nat-use-kfree-rcu-to-release-ops.patch b/1133-netfilter-nat-use-kfree-rcu-to-release-ops.patch deleted file mode 100644 index bd4559cd4..000000000 --- a/1133-netfilter-nat-use-kfree-rcu-to-release-ops.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 827d950e20067e03f0bdc4dda3c48d1162e1077c Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:17 +0200 -Subject: [PATCH] netfilter: nat: use kfree_rcu to release ops - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 6eda0d771f94 - -commit 6eda0d771f94267f73f57c94630aa47e90957915 -Author: Pablo Neira Ayuso -Date: Wed Apr 15 17:29:45 2026 +0200 - - netfilter: nat: use kfree_rcu to release ops - - Florian Westphal says: - - "Historically this is not an issue, even for normal base hooks: the data - path doesn't use the original nf_hook_ops that are used to register the - callbacks. - - However, in v5.14 I added the ability to dump the active netfilter - hooks from userspace. - - This code will peek back into the nf_hook_ops that are available - at the tail of the pointer-array blob used by the datapath. - - The nat hooks are special, because they are called indirectly from - the central nat dispatcher hook. They are currently invisible to - the nfnl hook dump subsystem though. - - But once that changes the nat ops structures have to be deferred too." - - Update nf_nat_register_fn() to deal with partial exposition of the hooks - from error path which can be also an issue for nfnetlink_hook. - - Fixes: e2cf17d3774c ("netfilter: add new hook nfnl subsystem") - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c -index a5db7c6..625a1ca 100644 ---- a/net/ipv4/netfilter/iptable_nat.c -+++ b/net/ipv4/netfilter/iptable_nat.c -@@ -79,7 +79,7 @@ static int ipt_nat_register_lookups(struct net *net) - while (i) - nf_nat_ipv4_unregister_fn(net, &ops[--i]); - -- kfree(ops); -+ kfree_rcu(ops, rcu); - return ret; - } - } -@@ -100,7 +100,7 @@ static void ipt_nat_unregister_lookups(struct net *net) - for (i = 0; i < ARRAY_SIZE(nf_nat_ipv4_ops); i++) - nf_nat_ipv4_unregister_fn(net, &ops[i]); - -- kfree(ops); -+ kfree_rcu(ops, rcu); - } - - static int iptable_nat_table_init(struct net *net) -diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c -index e119d4f..5be7232 100644 ---- a/net/ipv6/netfilter/ip6table_nat.c -+++ b/net/ipv6/netfilter/ip6table_nat.c -@@ -81,7 +81,7 @@ static int ip6t_nat_register_lookups(struct net *net) - while (i) - nf_nat_ipv6_unregister_fn(net, &ops[--i]); - -- kfree(ops); -+ kfree_rcu(ops, rcu); - return ret; - } - } -@@ -102,7 +102,7 @@ static void ip6t_nat_unregister_lookups(struct net *net) - for (i = 0; i < ARRAY_SIZE(nf_nat_ipv6_ops); i++) - nf_nat_ipv6_unregister_fn(net, &ops[i]); - -- kfree(ops); -+ kfree_rcu(ops, rcu); - } - - static int ip6table_nat_table_init(struct net *net) -diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c -index 746acd1..d380e1a 100644 ---- a/net/netfilter/nf_nat_core.c -+++ b/net/netfilter/nf_nat_core.c -@@ -1236,9 +1236,11 @@ int nf_nat_register_fn(struct net *net, u8 pf, const struct nf_hook_ops *ops, - ret = nf_register_net_hooks(net, nat_ops, ops_count); - if (ret < 0) { - mutex_unlock(&nf_nat_proto_mutex); -- for (i = 0; i < ops_count; i++) -- kfree(nat_ops[i].priv); -- kfree(nat_ops); -+ for (i = 0; i < ops_count; i++) { -+ priv = nat_ops[i].priv; -+ kfree_rcu(priv, rcu_head); -+ } -+ kfree_rcu(nat_ops, rcu); - return ret; - } - -@@ -1302,7 +1304,7 @@ void nf_nat_unregister_fn(struct net *net, u8 pf, const struct nf_hook_ops *ops, - } - - nat_proto_net->nat_hook_ops = NULL; -- kfree(nat_ops); -+ kfree_rcu(nat_ops, rcu); - } - unlock: - mutex_unlock(&nf_nat_proto_mutex); diff --git a/1134-netfilter-nfnetlink-osf-fix-out-of-bounds-read-on-option-matching.patch b/1134-netfilter-nfnetlink-osf-fix-out-of-bounds-read-on-option-matching.patch deleted file mode 100644 index 4da577d23..000000000 --- a/1134-netfilter-nfnetlink-osf-fix-out-of-bounds-read-on-option-matching.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 08043ad607850a39c83dec4e06a59532552a0c96 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:18 +0200 -Subject: [PATCH] netfilter: nfnetlink_osf: fix out-of-bounds read on option - matching - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit f5ca450087c3 - -commit f5ca450087c3baf3651055e7a6de92600f827af3 -Author: Fernando Fernandez Mancera -Date: Fri Apr 17 18:20:56 2026 +0200 - - netfilter: nfnetlink_osf: fix out-of-bounds read on option matching - - In nf_osf_match(), the nf_osf_hdr_ctx structure is initialized once - and passed by reference to nf_osf_match_one() for each fingerprint - checked. During TCP option parsing, nf_osf_match_one() advances the - shared ctx->optp pointer. - - If a fingerprint perfectly matches, the function returns early without - restoring ctx->optp to its initial state. If the user has configured - NF_OSF_LOGLEVEL_ALL, the loop continues to the next fingerprint. - However, because ctx->optp was not restored, the next call to - nf_osf_match_one() starts parsing from the end of the options buffer. - This causes subsequent matches to read garbage data and fail - immediately, making it impossible to log more than one match or logging - incorrect matches. - - Instead of using a shared ctx->optp pointer, pass the context as a - constant pointer and use a local pointer (optp) for TCP option - traversal. This makes nf_osf_match_one() strictly stateless from the - caller's perspective, ensuring every fingerprint check starts at the - correct option offset. - - Fixes: 1a6a0951fc00 ("netfilter: nfnetlink_osf: add missing fmatch check") - Suggested-by: Florian Westphal - Signed-off-by: Fernando Fernandez Mancera - Reviewed-by: Pablo Neira Ayuso - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c -index 2305c7d..832a973 100644 ---- a/net/netfilter/nfnetlink_osf.c -+++ b/net/netfilter/nfnetlink_osf.c -@@ -64,9 +64,9 @@ struct nf_osf_hdr_ctx { - static bool nf_osf_match_one(const struct sk_buff *skb, - const struct nf_osf_user_finger *f, - int ttl_check, -- struct nf_osf_hdr_ctx *ctx) -+ const struct nf_osf_hdr_ctx *ctx) - { -- const __u8 *optpinit = ctx->optp; -+ const __u8 *optp = ctx->optp; - unsigned int check_WSS = 0; - int fmatch = FMATCH_WRONG; - int foptsize, optnum; -@@ -95,17 +95,17 @@ static bool nf_osf_match_one(const struct sk_buff *skb, - check_WSS = f->wss.wc; - - for (optnum = 0; optnum < f->opt_num; ++optnum) { -- if (f->opt[optnum].kind == *ctx->optp) { -+ if (f->opt[optnum].kind == *optp) { - __u32 len = f->opt[optnum].length; -- const __u8 *optend = ctx->optp + len; -+ const __u8 *optend = optp + len; - - fmatch = FMATCH_OK; - -- switch (*ctx->optp) { -+ switch (*optp) { - case OSFOPT_MSS: -- mss = ctx->optp[3]; -+ mss = optp[3]; - mss <<= 8; -- mss |= ctx->optp[2]; -+ mss |= optp[2]; - - mss = ntohs((__force __be16)mss); - break; -@@ -113,7 +113,7 @@ static bool nf_osf_match_one(const struct sk_buff *skb, - break; - } - -- ctx->optp = optend; -+ optp = optend; - } else - fmatch = FMATCH_OPT_WRONG; - -@@ -156,9 +156,6 @@ static bool nf_osf_match_one(const struct sk_buff *skb, - } - } - -- if (fmatch != FMATCH_OK) -- ctx->optp = optpinit; -- - return fmatch == FMATCH_OK; - } - diff --git a/1135-netfilter-nfnetlink-osf-fix-potential-null-dereference-in-ttl-check.patch b/1135-netfilter-nfnetlink-osf-fix-potential-null-dereference-in-ttl-check.patch deleted file mode 100644 index 2f36ffaba..000000000 --- a/1135-netfilter-nfnetlink-osf-fix-potential-null-dereference-in-ttl-check.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 7fce69f7fa9f3555eec125a06c235b5664b059c8 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:18 +0200 -Subject: [PATCH] netfilter: nfnetlink_osf: fix potential NULL dereference in - ttl check - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 711987ba281f - -commit 711987ba281fd806322a7cd244e98e2a81903114 -Author: Fernando Fernandez Mancera -Date: Fri Apr 17 18:20:57 2026 +0200 - - netfilter: nfnetlink_osf: fix potential NULL dereference in ttl check - - The nf_osf_ttl() function accessed skb->dev to perform a local interface - address lookup without verifying that the device pointer was valid. - - Additionally, the implementation utilized an in_dev_for_each_ifa_rcu - loop to match the packet source address against local interface - addresses. It assumed that packets from the same subnet should not see a - decrement on the initial TTL. A packet might appear it is from the same - subnet but it actually isn't especially in modern environments with - containers and virtual switching. - - Remove the device dereference and interface loop. Replace the logic with - a switch statement that evaluates the TTL according to the ttl_check. - - Fixes: 11eeef41d5f6 ("netfilter: passive OS fingerprint xtables match") - Reported-by: Kito Xu (veritas501) - Closes: https://lore.kernel.org/netfilter-devel/20260414074556.2512750-1-hxzene@gmail.com/ - Signed-off-by: Fernando Fernandez Mancera - Reviewed-by: Pablo Neira Ayuso - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c -index 832a973..c89efb9 100644 ---- a/net/netfilter/nfnetlink_osf.c -+++ b/net/netfilter/nfnetlink_osf.c -@@ -31,26 +31,18 @@ EXPORT_SYMBOL_GPL(nf_osf_fingers); - static inline int nf_osf_ttl(const struct sk_buff *skb, - int ttl_check, unsigned char f_ttl) - { -- struct in_device *in_dev = __in_dev_get_rcu(skb->dev); - const struct iphdr *ip = ip_hdr(skb); -- const struct in_ifaddr *ifa; -- int ret = 0; - -- if (ttl_check == NF_OSF_TTL_TRUE) -+ switch (ttl_check) { -+ case NF_OSF_TTL_TRUE: - return ip->ttl == f_ttl; -- if (ttl_check == NF_OSF_TTL_NOCHECK) -- return 1; -- else if (ip->ttl <= f_ttl) -+ break; -+ case NF_OSF_TTL_NOCHECK: - return 1; -- -- in_dev_for_each_ifa_rcu(ifa, in_dev) { -- if (inet_ifa_match(ip->saddr, ifa)) { -- ret = (ip->ttl == f_ttl); -- break; -- } -+ case NF_OSF_TTL_LESS: -+ default: -+ return ip->ttl <= f_ttl; - } -- -- return ret; - } - - struct nf_osf_hdr_ctx { diff --git a/1136-netfilter-nf-tables-use-list-del-rcu-for-netlink-hooks.patch b/1136-netfilter-nf-tables-use-list-del-rcu-for-netlink-hooks.patch deleted file mode 100644 index 827da0c09..000000000 --- a/1136-netfilter-nf-tables-use-list-del-rcu-for-netlink-hooks.patch +++ /dev/null @@ -1,137 +0,0 @@ -From bedd721414832ff460290adf488d09deff50db05 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:19 +0200 -Subject: [PATCH] netfilter: nf_tables: use list_del_rcu for netlink hooks - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit f3224ee463f8 - -commit f3224ee463f8f6f6ced7dcdf6081add4f8128527 -Author: Florian Westphal -Date: Thu Apr 16 15:14:51 2026 +0200 - - netfilter: nf_tables: use list_del_rcu for netlink hooks - - nft_netdev_unregister_hooks and __nft_unregister_flowtable_net_hooks need - to use list_del_rcu(), this list can be walked by concurrent dumpers. - - Add a new helper and use it consistently. - - Fixes: f9a43007d3f7 ("netfilter: nf_tables: double hook unregistration in netns path") - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 7cc4163..f67b9b0 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -373,6 +373,12 @@ static void nft_netdev_hook_free_rcu(struct nft_hook *hook) - call_rcu(&hook->rcu, __nft_netdev_hook_free_rcu); - } - -+static void nft_netdev_hook_unlink_free_rcu(struct nft_hook *hook) -+{ -+ list_del_rcu(&hook->list); -+ nft_netdev_hook_free_rcu(hook); -+} -+ - static void nft_netdev_unregister_hooks(struct net *net, - struct list_head *hook_list, - bool release_netdev) -@@ -383,10 +389,8 @@ static void nft_netdev_unregister_hooks(struct net *net, - list_for_each_entry_safe(hook, next, hook_list, list) { - list_for_each_entry(ops, &hook->ops_list, list) - nf_unregister_net_hook(net, ops); -- if (release_netdev) { -- list_del(&hook->list); -- nft_netdev_hook_free_rcu(hook); -- } -+ if (release_netdev) -+ nft_netdev_hook_unlink_free_rcu(hook); - } - } - -@@ -2314,10 +2318,8 @@ void nf_tables_chain_destroy(struct nft_chain *chain) - - if (nft_base_chain_netdev(table->family, basechain->ops.hooknum)) { - list_for_each_entry_safe(hook, next, -- &basechain->hook_list, list) { -- list_del_rcu(&hook->list); -- nft_netdev_hook_free_rcu(hook); -- } -+ &basechain->hook_list, list) -+ nft_netdev_hook_unlink_free_rcu(hook); - } - module_put(basechain->type->owner); - if (rcu_access_pointer(basechain->stats)) { -@@ -3017,6 +3019,7 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy, - list_for_each_entry(ops, &h->ops_list, list) - nf_unregister_net_hook(ctx->net, ops); - } -+ /* hook.list is on stack, no need for list_del_rcu() */ - list_del(&h->list); - nft_netdev_hook_free_rcu(h); - } -@@ -9049,10 +9052,8 @@ static void __nft_unregister_flowtable_net_hooks(struct net *net, - list_for_each_entry_safe(hook, next, hook_list, list) { - list_for_each_entry(ops, &hook->ops_list, list) - nft_unregister_flowtable_ops(net, flowtable, ops); -- if (release_netdev) { -- list_del(&hook->list); -- nft_netdev_hook_free_rcu(hook); -- } -+ if (release_netdev) -+ nft_netdev_hook_unlink_free_rcu(hook); - } - } - -@@ -9123,8 +9124,7 @@ static int nft_register_flowtable_net_hooks(struct net *net, - - nft_unregister_flowtable_ops(net, flowtable, ops); - } -- list_del_rcu(&hook->list); -- nft_netdev_hook_free_rcu(hook); -+ nft_netdev_hook_unlink_free_rcu(hook); - } - - return err; -@@ -9134,10 +9134,8 @@ static void nft_hooks_destroy(struct list_head *hook_list) - { - struct nft_hook *hook, *next; - -- list_for_each_entry_safe(hook, next, hook_list, list) { -- list_del_rcu(&hook->list); -- nft_netdev_hook_free_rcu(hook); -- } -+ list_for_each_entry_safe(hook, next, hook_list, list) -+ nft_netdev_hook_unlink_free_rcu(hook); - } - - static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh, -@@ -9225,8 +9223,7 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh, - nft_unregister_flowtable_ops(ctx->net, - flowtable, ops); - } -- list_del_rcu(&hook->list); -- nft_netdev_hook_free_rcu(hook); -+ nft_netdev_hook_unlink_free_rcu(hook); - } - - return err; -@@ -9730,13 +9727,8 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx, - - static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable) - { -- struct nft_hook *hook, *next; -- - flowtable->data.type->free(&flowtable->data); -- list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) { -- list_del_rcu(&hook->list); -- nft_netdev_hook_free_rcu(hook); -- } -+ nft_hooks_destroy(&flowtable->hook_list); - kfree(flowtable->name); - module_put(flowtable->data.type->owner); - kfree(flowtable); diff --git a/1137-rculist-add-list-splice-rcu-for-private-lists.patch b/1137-rculist-add-list-splice-rcu-for-private-lists.patch deleted file mode 100644 index 2071b3222..000000000 --- a/1137-rculist-add-list-splice-rcu-for-private-lists.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 4f79f8ec95a853c69e776a91f3258f8309713123 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:20 +0200 -Subject: [PATCH] rculist: add list_splice_rcu() for private lists - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit f902877b6355 - -commit f902877b635551513729bdf9a8d1422c4aab7741 -Author: Pablo Neira Ayuso -Date: Wed Apr 15 17:56:02 2026 +0200 - - rculist: add list_splice_rcu() for private lists - - This patch adds a helper function, list_splice_rcu(), to safely splice - a private (non-RCU-protected) list into an RCU-protected list. - - The function ensures that only the pointer visible to RCU readers - (prev->next) is updated using rcu_assign_pointer(), while the rest of - the list manipulations are performed with regular assignments, as the - source list is private and not visible to concurrent RCU readers. - - This is useful for moving elements from a private list into a global - RCU-protected list, ensuring safe publication for RCU readers. - Subsystems with some sort of batching mechanism from userspace can - benefit from this new function. - - The function __list_splice_rcu() has been added for clarity and to - follow the same pattern as in the existing list_splice*() interfaces, - where there is a check to ensure that the list to splice is not - empty. Note that __list_splice_rcu() has no documentation for this - reason. - - Reviewed-by: Paul E. McKenney - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/include/linux/rculist.h b/include/linux/rculist.h -index 1b11926..591272f 100644 ---- a/include/linux/rculist.h -+++ b/include/linux/rculist.h -@@ -251,6 +251,35 @@ static inline void list_replace_rcu(struct list_head *old, - old->prev = LIST_POISON2; - } - -+static inline void __list_splice_rcu(struct list_head *list, -+ struct list_head *prev, -+ struct list_head *next) -+{ -+ struct list_head *first = list->next; -+ struct list_head *last = list->prev; -+ -+ last->next = next; -+ first->prev = prev; -+ next->prev = last; -+ rcu_assign_pointer(list_next_rcu(prev), first); -+} -+ -+/** -+ * list_splice_rcu - splice a non-RCU list into an RCU-protected list, -+ * designed for stacks. -+ * @list: the non RCU-protected list to splice -+ * @head: the place in the existing RCU-protected list to splice -+ * -+ * The list pointed to by @head can be RCU-read traversed concurrently with -+ * this function. -+ */ -+static inline void list_splice_rcu(struct list_head *list, -+ struct list_head *head) -+{ -+ if (!list_empty(list)) -+ __list_splice_rcu(list, head, head->next); -+} -+ - /** - * __list_splice_init_rcu - join an RCU-protected list into an existing list. - * @list: the RCU-protected list to splice diff --git a/1138-netfilter-nf-tables-join-hook-list-via-splice-list-rcu-in-commit-phase.patch b/1138-netfilter-nf-tables-join-hook-list-via-splice-list-rcu-in-commit-phase.patch deleted file mode 100644 index efea172cf..000000000 --- a/1138-netfilter-nf-tables-join-hook-list-via-splice-list-rcu-in-commit-phase.patch +++ /dev/null @@ -1,51 +0,0 @@ -From f5e3847dafb8aae3a40977b9a266e8c31cf0e018 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:21 +0200 -Subject: [PATCH] netfilter: nf_tables: join hook list via splice_list_rcu() in - commit phase - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit a6134e62dba2 - -commit a6134e62dba2ea4f760b29d5226907f447c92400 -Author: Pablo Neira Ayuso -Date: Wed Apr 15 17:56:14 2026 +0200 - - netfilter: nf_tables: join hook list via splice_list_rcu() in commit phase - - Publish new hooks in the list into the basechain/flowtable using - splice_list_rcu() to ensure netlink dump list traversal via rcu is safe - while concurrent ruleset update is going on. - - Fixes: 78d9f48f7f44 ("netfilter: nf_tables: add devices to existing flowtable") - Fixes: b9703ed44ffb ("netfilter: nf_tables: support for adding new devices to an existing netdev chain") - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index f67b9b0..32155f1 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -11048,8 +11048,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) - nft_chain_commit_update(nft_trans_container_chain(trans)); - nf_tables_chain_notify(&ctx, NFT_MSG_NEWCHAIN, - &nft_trans_chain_hooks(trans)); -- list_splice(&nft_trans_chain_hooks(trans), -- &nft_trans_basechain(trans)->hook_list); -+ list_splice_rcu(&nft_trans_chain_hooks(trans), -+ &nft_trans_basechain(trans)->hook_list); - /* trans destroyed after rcu grace period */ - } else { - nft_chain_commit_drop_policy(nft_trans_container_chain(trans)); -@@ -11178,8 +11178,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) - nft_trans_flowtable(trans), - &nft_trans_flowtable_hooks(trans), - NFT_MSG_NEWFLOWTABLE); -- list_splice(&nft_trans_flowtable_hooks(trans), -- &nft_trans_flowtable(trans)->hook_list); -+ list_splice_rcu(&nft_trans_flowtable_hooks(trans), -+ &nft_trans_flowtable(trans)->hook_list); - } else { - nft_clear(net, nft_trans_flowtable(trans)); - nf_tables_flowtable_notify(&ctx, diff --git a/1139-netfilter-nf-tables-add-hook-transactions-for-device-deletions.patch b/1139-netfilter-nf-tables-add-hook-transactions-for-device-deletions.patch deleted file mode 100644 index 257a171e2..000000000 --- a/1139-netfilter-nf-tables-add-hook-transactions-for-device-deletions.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 28986d167301cbf492736a86d0bd9138186d4bc4 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:21 +0200 -Subject: [PATCH] netfilter: nf_tables: add hook transactions for device - deletions - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 10f79dbd7719 - -commit 10f79dbd7719d1da9f5884d13060322d8729f091 -Author: Pablo Neira Ayuso -Date: Wed Apr 15 22:58:23 2026 +0200 - - netfilter: nf_tables: add hook transactions for device deletions - - Restore the flag that indicates that the hook is going away, ie. - NFT_HOOK_REMOVE, but add a new transaction object to track deletion - of hooks without altering the basechain/flowtable hook_list during - the preparation phase. - - The existing approach that moves the hook from the basechain/flowtable - hook_list to transaction hook_list breaks netlink dump path readers - of this RCU-protected list. - - It should be possible use an array for nft_trans_hook to store the - deleted hooks to compact the representation but I am not expecting - many hook object, specially now that wildcard support for devices - is in place. - - Note that the nft_trans_chain_hooks() list contains a list of struct - nft_trans_hook objects for DELCHAIN and DELFLOWTABLE commands, while - this list stores struct nft_hook objects for NEWCHAIN and NEWFLOWTABLE. - Note that new commands can be updated to use nft_trans_hook for - consistency. - - This patch also adapts the event notification path to deal with the list - of hook transactions. - - Fixes: 7d937b107108 ("netfilter: nf_tables: support for deleting devices in an existing netdev chain") - Fixes: b6d9014a3335 ("netfilter: nf_tables: delete flowtable hooks via transaction list") - Reported-by: Xiang Mei - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h -index 5fe20cc..a704616 100644 ---- a/include/net/netfilter/nf_tables.h -+++ b/include/net/netfilter/nf_tables.h -@@ -1213,12 +1213,15 @@ struct nft_stats { - struct u64_stats_sync syncp; - }; - -+#define NFT_HOOK_REMOVE (1 << 0) -+ - struct nft_hook { - struct list_head list; - struct list_head ops_list; - struct rcu_head rcu; - char ifname[IFNAMSIZ]; - u8 ifnamelen; -+ u8 flags; - }; - - struct nf_hook_ops *nft_hook_find_ops(const struct nft_hook *hook, -@@ -1673,6 +1676,16 @@ struct nft_trans { - u8 put_net:1; - }; - -+/** -+ * struct nft_trans_hook - nf_tables hook update in transaction -+ * @list: used internally -+ * @hook: struct nft_hook with the device hook -+ */ -+struct nft_trans_hook { -+ struct list_head list; -+ struct nft_hook *hook; -+}; -+ - /** - * struct nft_trans_binding - nf_tables object with binding support in transaction - * @nft_trans: base structure, MUST be first member diff --git a/1140-netfilter-xt-policy-fix-strict-mode-inbound-policy-matching.patch b/1140-netfilter-xt-policy-fix-strict-mode-inbound-policy-matching.patch deleted file mode 100644 index 10eeaf90b..000000000 --- a/1140-netfilter-xt-policy-fix-strict-mode-inbound-policy-matching.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 8356d8b52032a2e39e5e3ac6f8d4c8c69247064f Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:52 +0200 -Subject: [PATCH] netfilter: xt_policy: fix strict mode inbound policy matching - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 4b2b4d7d4e20 - -commit 4b2b4d7d4e203c92db8966b163edfacb1f0e1e29 -Author: Jiexun Wang -Date: Fri Apr 17 20:25:06 2026 +0800 - - netfilter: xt_policy: fix strict mode inbound policy matching - - match_policy_in() walks sec_path entries from the last transform to the - first one, but strict policy matching needs to consume info->pol[] in - the same forward order as the rule layout. - - Derive the strict-match policy position from the number of transforms - already consumed so that multi-element inbound rules are matched - consistently. - - Fixes: c4b885139203 ("[NETFILTER]: x_tables: replace IPv4/IPv6 policy match by address family independant version") - Reported-by: Yuan Tan - Reported-by: Yifan Wu - Reported-by: Juefei Pu - Reported-by: Xin Liu - Signed-off-by: Jiexun Wang - Signed-off-by: Ren Wei - Acked-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c -index cb6e827..b5fa655 100644 ---- a/net/netfilter/xt_policy.c -+++ b/net/netfilter/xt_policy.c -@@ -63,7 +63,7 @@ match_policy_in(const struct sk_buff *skb, const struct xt_policy_info *info, - return 0; - - for (i = sp->len - 1; i >= 0; i--) { -- pos = strict ? i - sp->len + 1 : 0; -+ pos = strict ? sp->len - i - 1 : 0; - if (pos >= info->len) - return 0; - e = &info->pol[pos]; diff --git a/1141-netfilter-nf-conntrack-sip-don-t-use-simple-strtoul.patch b/1141-netfilter-nf-conntrack-sip-don-t-use-simple-strtoul.patch deleted file mode 100644 index 373b4d184..000000000 --- a/1141-netfilter-nf-conntrack-sip-don-t-use-simple-strtoul.patch +++ /dev/null @@ -1,351 +0,0 @@ -From cfeec2dad64d5c91326707d6a443086a260f5c22 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:53 +0200 -Subject: [PATCH] netfilter: nf_conntrack_sip: don't use simple_strtoul -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 8cf6809cddcb - -commit 8cf6809cddcbe301aedfc6b51bcd4944d45795f6 -Author: Florian Westphal -Date: Thu Apr 23 02:19:11 2026 +0200 - - netfilter: nf_conntrack_sip: don't use simple_strtoul - - Replace unsafe port parsing in epaddr_len(), ct_sip_parse_header_uri(), - and ct_sip_parse_request() with a new sip_parse_port() helper that - validates each digit against the buffer limit, eliminating the use of - simple_strtoul() which assumes NUL-terminated strings. - - The previous code dereferenced pointers without bounds checks after - sip_parse_addr() and relied on simple_strtoul() on non-NUL-terminated - skb data. A port that reaches the buffer limit without a trailing - character is also rejected as malformed. - - Also get rid of all simple_strtoul() usage in conntrack, prefer a - stricter version instead. There are intentional changes: - - - Bail out if number is > UINT_MAX and indicate a failure, same for - too long sequences. - While we do accept 05535 as port 5535, we will not accept e.g. - 'sip:10.0.0.1:005060'. While its syntactically valid under RFC 3261, - we should restrict this to not waste cycles when presented with - malformed packets with 64k '0' characters. - - - Force base 10 in ct_sip_parse_numerical_param(). This is used to fetch - 'expire=' and 'rports='; both are expected to use base-10. - - - In nf_nat_sip.c, only accept the parsed value if its within the 1k-64k - range. - - - epaddr_len now returns 0 if the port is invalid, as it already does - for invalid ip addresses. This is intentional. nf_conntrack_sip - performs lots of guesswork to find the right parts of the message - to parse. Being stricter could break existing setups. - Connection tracking helpers are designed to allow traffic to - pass, not to block it. - - Based on an earlier patch from Jenny Guanni Qu . - - Fixes: 05e3ced297fe ("[NETFILTER]: nf_conntrack_sip: introduce SIP-URI parsing helper") - Reported-by: Klaudia Kloc - Reported-by: Dawid Moczadło - Reported-by: Jenny Guanni Qu . - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c -index 20e57cf..b31f31e 100644 ---- a/net/netfilter/nf_conntrack_sip.c -+++ b/net/netfilter/nf_conntrack_sip.c -@@ -181,6 +181,57 @@ static int sip_parse_addr(const struct nf_conn *ct, const char *cp, - return 1; - } - -+/* Parse optional port number after IP address. -+ * Returns false on malformed input, true otherwise. -+ * If port is non-NULL, stores parsed port in network byte order. -+ * If no port is present, sets *port to default SIP port. -+ */ -+static bool sip_parse_port(const char *dptr, const char **endp, -+ const char *limit, __be16 *port) -+{ -+ unsigned int p = 0; -+ int len = 0; -+ -+ if (dptr >= limit) -+ return false; -+ -+ if (*dptr != ':') { -+ if (port) -+ *port = htons(SIP_PORT); -+ if (endp) -+ *endp = dptr; -+ return true; -+ } -+ -+ dptr++; /* skip ':' */ -+ -+ while (dptr < limit && isdigit(*dptr)) { -+ p = p * 10 + (*dptr - '0'); -+ dptr++; -+ len++; -+ if (len > 5) /* max "65535" */ -+ return false; -+ } -+ -+ if (len == 0) -+ return false; -+ -+ /* reached limit while parsing port */ -+ if (dptr >= limit) -+ return false; -+ -+ if (p < 1024 || p > 65535) -+ return false; -+ -+ if (port) -+ *port = htons(p); -+ -+ if (endp) -+ *endp = dptr; -+ -+ return true; -+} -+ - /* skip ip address. returns its length. */ - static int epaddr_len(const struct nf_conn *ct, const char *dptr, - const char *limit, int *shift) -@@ -193,11 +244,8 @@ static int epaddr_len(const struct nf_conn *ct, const char *dptr, - return 0; - } - -- /* Port number */ -- if (*dptr == ':') { -- dptr++; -- dptr += digits_len(ct, dptr, limit, shift); -- } -+ if (!sip_parse_port(dptr, &dptr, limit, NULL)) -+ return 0; - return dptr - aux; - } - -@@ -228,6 +276,51 @@ static int skp_epaddr_len(const struct nf_conn *ct, const char *dptr, - return epaddr_len(ct, dptr, limit, shift); - } - -+/* simple_strtoul stops after first non-number character. -+ * But as we're not dealing with c-strings, we can't rely on -+ * hitting \r,\n,\0 etc. before moving past end of buffer. -+ * -+ * This is a variant of simple_strtoul, but doesn't require -+ * a c-string. -+ * -+ * If value exceeds UINT_MAX, 0 is returned. -+ */ -+static unsigned int sip_strtouint(const char *cp, unsigned int len, char **endp) -+{ -+ const unsigned int max = sizeof("4294967295"); -+ unsigned int olen = len; -+ const char *s = cp; -+ u64 result = 0; -+ -+ if (len > max) -+ len = max; -+ -+ while (olen > 0 && isdigit(*s)) { -+ unsigned int value; -+ -+ if (len == 0) -+ goto err; -+ -+ value = *s - '0'; -+ result = result * 10 + value; -+ -+ if (result > UINT_MAX) -+ goto err; -+ s++; -+ len--; -+ olen--; -+ } -+ -+ if (endp) -+ *endp = (char *)s; -+ -+ return result; -+err: -+ if (endp) -+ *endp = (char *)cp; -+ return 0; -+} -+ - /* Parse a SIP request line of the form: - * - * Request-Line = Method SP Request-URI SP SIP-Version CRLF -@@ -241,7 +334,6 @@ int ct_sip_parse_request(const struct nf_conn *ct, - { - const char *start = dptr, *limit = dptr + datalen, *end; - unsigned int mlen; -- unsigned int p; - int shift = 0; - - /* Skip method and following whitespace */ -@@ -267,14 +359,8 @@ int ct_sip_parse_request(const struct nf_conn *ct, - - if (!sip_parse_addr(ct, dptr, &end, addr, limit, true)) - return -1; -- if (end < limit && *end == ':') { -- end++; -- p = simple_strtoul(end, (char **)&end, 10); -- if (p < 1024 || p > 65535) -- return -1; -- *port = htons(p); -- } else -- *port = htons(SIP_PORT); -+ if (!sip_parse_port(end, &end, limit, port)) -+ return -1; - - if (end == dptr) - return 0; -@@ -509,7 +595,6 @@ int ct_sip_parse_header_uri(const struct nf_conn *ct, const char *dptr, - union nf_inet_addr *addr, __be16 *port) - { - const char *c, *limit = dptr + datalen; -- unsigned int p; - int ret; - - ret = ct_sip_walk_headers(ct, dptr, dataoff ? *dataoff : 0, datalen, -@@ -520,14 +605,8 @@ int ct_sip_parse_header_uri(const struct nf_conn *ct, const char *dptr, - - if (!sip_parse_addr(ct, dptr + *matchoff, &c, addr, limit, true)) - return -1; -- if (*c == ':') { -- c++; -- p = simple_strtoul(c, (char **)&c, 10); -- if (p < 1024 || p > 65535) -- return -1; -- *port = htons(p); -- } else -- *port = htons(SIP_PORT); -+ if (!sip_parse_port(c, &c, limit, port)) -+ return -1; - - if (dataoff) - *dataoff = c - dptr; -@@ -609,7 +688,7 @@ int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr, - return 0; - - start += strlen(name); -- *val = simple_strtoul(start, &end, 0); -+ *val = sip_strtouint(start, limit - start, (char **)&end); - if (start == end) - return -1; - if (matchoff && matchlen) { -@@ -1061,6 +1140,8 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff, - - mediaoff = sdpoff; - for (i = 0; i < ARRAY_SIZE(sdp_media_types); ) { -+ char *end; -+ - if (ct_sip_get_sdp_header(ct, *dptr, mediaoff, *datalen, - SDP_HDR_MEDIA, SDP_HDR_UNSPEC, - &mediaoff, &medialen) <= 0) -@@ -1076,8 +1157,8 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff, - mediaoff += t->len; - medialen -= t->len; - -- port = simple_strtoul(*dptr + mediaoff, NULL, 10); -- if (port == 0) -+ port = sip_strtouint(*dptr + mediaoff, *datalen - mediaoff, (char **)&end); -+ if (port == 0 || *dptr + mediaoff == end) - continue; - if (port < 1024 || port > 65535) { - nf_ct_helper_log(skb, ct, "wrong port %u", port); -@@ -1249,7 +1330,7 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff, - */ - if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_EXPIRES, - &matchoff, &matchlen) > 0) -- expires = simple_strtoul(*dptr + matchoff, NULL, 10); -+ expires = sip_strtouint(*dptr + matchoff, *datalen - matchoff, NULL); - - ret = ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, - SIP_HDR_CONTACT, NULL, -@@ -1353,7 +1434,7 @@ static int process_register_response(struct sk_buff *skb, unsigned int protoff, - - if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_EXPIRES, - &matchoff, &matchlen) > 0) -- expires = simple_strtoul(*dptr + matchoff, NULL, 10); -+ expires = sip_strtouint(*dptr + matchoff, *datalen - matchoff, NULL); - - while (1) { - unsigned int c_expires = expires; -@@ -1413,10 +1494,12 @@ static int process_sip_response(struct sk_buff *skb, unsigned int protoff, - struct nf_conn *ct = nf_ct_get(skb, &ctinfo); - unsigned int matchoff, matchlen, matchend; - unsigned int code, cseq, i; -+ char *end; - - if (*datalen < strlen("SIP/2.0 200")) - return NF_ACCEPT; -- code = simple_strtoul(*dptr + strlen("SIP/2.0 "), NULL, 10); -+ code = sip_strtouint(*dptr + strlen("SIP/2.0 "), -+ *datalen - strlen("SIP/2.0 "), NULL); - if (!code) { - nf_ct_helper_log(skb, ct, "cannot get code"); - return NF_DROP; -@@ -1427,8 +1510,8 @@ static int process_sip_response(struct sk_buff *skb, unsigned int protoff, - nf_ct_helper_log(skb, ct, "cannot parse cseq"); - return NF_DROP; - } -- cseq = simple_strtoul(*dptr + matchoff, NULL, 10); -- if (!cseq && *(*dptr + matchoff) != '0') { -+ cseq = sip_strtouint(*dptr + matchoff, *datalen - matchoff, (char **)&end); -+ if (*dptr + matchoff == end) { - nf_ct_helper_log(skb, ct, "cannot get cseq"); - return NF_DROP; - } -@@ -1477,6 +1560,7 @@ static int process_sip_request(struct sk_buff *skb, unsigned int protoff, - - for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) { - const struct sip_handler *handler; -+ char *end; - - handler = &sip_handlers[i]; - if (handler->request == NULL) -@@ -1493,8 +1577,8 @@ static int process_sip_request(struct sk_buff *skb, unsigned int protoff, - nf_ct_helper_log(skb, ct, "cannot parse cseq"); - return NF_DROP; - } -- cseq = simple_strtoul(*dptr + matchoff, NULL, 10); -- if (!cseq && *(*dptr + matchoff) != '0') { -+ cseq = sip_strtouint(*dptr + matchoff, *datalen - matchoff, (char **)&end); -+ if (*dptr + matchoff == end) { - nf_ct_helper_log(skb, ct, "cannot get cseq"); - return NF_DROP; - } -@@ -1570,7 +1654,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, - &matchoff, &matchlen) <= 0) - break; - -- clen = simple_strtoul(dptr + matchoff, (char **)&end, 10); -+ clen = sip_strtouint(dptr + matchoff, datalen - matchoff, (char **)&end); - if (dptr + matchoff == end) - break; - -diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c -index c845b6d..9fbfc6b 100644 ---- a/net/netfilter/nf_nat_sip.c -+++ b/net/netfilter/nf_nat_sip.c -@@ -246,6 +246,7 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff, - if (ct_sip_parse_numerical_param(ct, *dptr, matchend, *datalen, - "rport=", &poff, &plen, - &n) > 0 && -+ n >= 1024 && n <= 65535 && - htons(n) == ct->tuplehash[dir].tuple.dst.u.udp.port && - htons(n) != ct->tuplehash[!dir].tuple.src.u.udp.port) { - __be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port; diff --git a/1142-netfilter-replace-skb-try-make-writable-by-skb-ensure-writable.patch b/1142-netfilter-replace-skb-try-make-writable-by-skb-ensure-writable.patch deleted file mode 100644 index 9b914f774..000000000 --- a/1142-netfilter-replace-skb-try-make-writable-by-skb-ensure-writable.patch +++ /dev/null @@ -1,81 +0,0 @@ -From a3f61eef6943577933d43f3546d57ae78f5b44f3 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:55 +0200 -Subject: [PATCH] netfilter: replace skb_try_make_writable() by - skb_ensure_writable() - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 1049970d7583 - -commit 1049970d7583194eedc30e45a3c898b2cb1c30ba -Author: Pablo Neira Ayuso -Date: Mon Apr 27 14:34:45 2026 +0200 - - netfilter: replace skb_try_make_writable() by skb_ensure_writable() - - skb_try_make_writable() only works on clones and uncloned packets might - have their network header in paged fragments. - - nft_fwd needs to work for the ingress and egress hooks, but the egress - hook where skb->data points to the mac header, use skb_network_offset() - to include the mac header. The flowtable is fine since it already uses - the transport offset. - - Fixes: d32de98ea70f ("netfilter: nft_fwd_netdev: allow to forward packets via neighbour layer") - Fixes: 7d2086871762 ("netfilter: nf_flow_table: move ipv4 offload hook code to nf_flow_table") - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_flow_table_ip.c b/net/netfilter/nf_flow_table_ip.c -index 8cd4cf7..43266ab 100644 ---- a/net/netfilter/nf_flow_table_ip.c -+++ b/net/netfilter/nf_flow_table_ip.c -@@ -394,7 +394,7 @@ static int nf_flow_offload_forward(struct nf_flowtable_ctx *ctx, - return 0; - } - -- if (skb_try_make_writable(skb, thoff + ctx->hdrsize)) -+ if (skb_ensure_writable(skb, thoff + ctx->hdrsize)) - return -1; - - flow_offload_refresh(flow_table, flow, false); -@@ -673,7 +673,7 @@ static int nf_flow_offload_ipv6_forward(struct nf_flowtable_ctx *ctx, - return 0; - } - -- if (skb_try_make_writable(skb, thoff + ctx->hdrsize)) -+ if (skb_ensure_writable(skb, thoff + ctx->hdrsize)) - return -1; - - flow_offload_refresh(flow_table, flow, false); -diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c -index 152a9fb..c49da00 100644 ---- a/net/netfilter/nft_fwd_netdev.c -+++ b/net/netfilter/nft_fwd_netdev.c -@@ -100,6 +100,7 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr, - int oif = regs->data[priv->sreg_dev]; - unsigned int verdict = NF_STOLEN; - struct sk_buff *skb = pkt->skb; -+ int nhoff = skb_network_offset(skb); - struct net_device *dev; - int neigh_table; - -@@ -111,7 +112,7 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr, - verdict = NFT_BREAK; - goto out; - } -- if (skb_try_make_writable(skb, sizeof(*iph))) { -+ if (skb_ensure_writable(skb, nhoff + sizeof(*iph))) { - verdict = NF_DROP; - goto out; - } -@@ -127,7 +128,7 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr, - verdict = NFT_BREAK; - goto out; - } -- if (skb_try_make_writable(skb, sizeof(*ip6h))) { -+ if (skb_ensure_writable(skb, nhoff + sizeof(*ip6h))) { - verdict = NF_DROP; - goto out; - } diff --git a/1143-netfilter-nft-fwd-netdev-add-device-and-headroom-validate-with-neigh-forwarding.patch b/1143-netfilter-nft-fwd-netdev-add-device-and-headroom-validate-with-neigh-forwarding.patch deleted file mode 100644 index db958bf9c..000000000 --- a/1143-netfilter-nft-fwd-netdev-add-device-and-headroom-validate-with-neigh-forwarding.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 2073f1cc95a6d0cfea7e966c7307730ba7dca41c Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:57 +0200 -Subject: [PATCH] netfilter: nft_fwd_netdev: add device and headroom validate - with neigh forwarding - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 0a0b35f0bf10 - -commit 0a0b35f0bf10b4c2be607465f5c9c12c8681305b -Author: Pablo Neira Ayuso -Date: Mon Apr 27 14:34:48 2026 +0200 - - netfilter: nft_fwd_netdev: add device and headroom validate with neigh forwarding - - The ttl field has been decremented already and evaluation of this rule - would proceed, just drop this packet instead if there is no destination - device to forwards this packet. This is exactly what nf_dup already does - in this case. - - Moreover, check for headroom and call skb_expand_head() like in the IP - output path to ensure there is sufficient headroom when forwarding this - via neigh_xmit(). - - Fixes: d32de98ea70f ("netfilter: nft_fwd_netdev: allow to forward packets via neighbour layer") - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c -index c49da00..08246ef 100644 ---- a/net/netfilter/nft_fwd_netdev.c -+++ b/net/netfilter/nft_fwd_netdev.c -@@ -102,6 +102,7 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr, - struct sk_buff *skb = pkt->skb; - int nhoff = skb_network_offset(skb); - struct net_device *dev; -+ unsigned int hh_len; - int neigh_table; - - switch (priv->nfproto) { -@@ -143,8 +144,19 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr, - } - - dev = dev_get_by_index_rcu(nft_net(pkt), oif); -- if (dev == NULL) -- return; -+ if (dev == NULL) { -+ verdict = NF_DROP; -+ goto out; -+ } -+ -+ hh_len = LL_RESERVED_SPACE(dev); -+ if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { -+ skb = skb_expand_head(skb, hh_len); -+ if (!skb) { -+ verdict = NF_STOLEN; -+ goto out; -+ } -+ } - - skb->dev = dev; - skb_clear_tstamp(skb); diff --git a/1144-netfilter-nft-fwd-netdev-use-recursion-counter-in-neigh-egress-path.patch b/1144-netfilter-nft-fwd-netdev-use-recursion-counter-in-neigh-egress-path.patch deleted file mode 100644 index 6ec1e533a..000000000 --- a/1144-netfilter-nft-fwd-netdev-use-recursion-counter-in-neigh-egress-path.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 5c6290d3ed9c20d216c2e6fe34d529a1417264e5 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:58 +0200 -Subject: [PATCH] netfilter: nft_fwd_netdev: use recursion counter in neigh - egress path - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 1d47b55b36d2 - -commit 1d47b55b36d2ec73fe6901212c8b28a593c3b27c -Author: Weiming Shi -Date: Mon Apr 27 14:34:50 2026 +0200 - - netfilter: nft_fwd_netdev: use recursion counter in neigh egress path - - nft_fwd_neigh can be used in egress chains (NF_NETDEV_EGRESS). When the - forwarding rule targets the same device or two devices forward to each - other, neigh_xmit() triggers dev_queue_xmit() which re-enters - nf_hook_egress(), causing infinite recursion and stack overflow. - - Move the nf_get_nf_dup_skb_recursion() accessor and NF_RECURSION_LIMIT - to the shared header nf_dup_netdev.h as a static inline, so that - nft_fwd_netdev can use the recursion counter directly without exported - function call overhead. Guard neigh_xmit() with the same recursion - limit already used in nf_do_netdev_egress(). - - [ Updated to cache the nf_get_nf_dup_skb_recursion pointer. --pablo ] - - Fixes: f87b9464d152 ("netfilter: nft_fwd_netdev: Support egress hook") - Reported-by: Xiang Mei - Signed-off-by: Weiming Shi - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/include/net/netfilter/nf_dup_netdev.h b/include/net/netfilter/nf_dup_netdev.h -index b175d27..609bcf4 100644 ---- a/include/net/netfilter/nf_dup_netdev.h -+++ b/include/net/netfilter/nf_dup_netdev.h -@@ -3,10 +3,23 @@ - #define _NF_DUP_NETDEV_H_ - - #include -+#include -+#include - - void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif); - void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif); - -+#define NF_RECURSION_LIMIT 2 -+ -+static inline u8 *nf_get_nf_dup_skb_recursion(void) -+{ -+#ifndef CONFIG_PREEMPT_RT -+ return this_cpu_ptr(&softnet_data.xmit.nf_dup_skb_recursion); -+#else -+ return ¤t->net_xmit.nf_dup_skb_recursion; -+#endif -+} -+ - struct nft_offload_ctx; - struct nft_flow_rule; - -diff --git a/net/netfilter/nf_dup_netdev.c b/net/netfilter/nf_dup_netdev.c -index a8e2425..516bcf4 100644 ---- a/net/netfilter/nf_dup_netdev.c -+++ b/net/netfilter/nf_dup_netdev.c -@@ -17,6 +17,22 @@ - - static DEFINE_PER_CPU(u8, nf_dup_skb_recursion); - -+#define NF_RECURSION_LIMIT 2 -+ -+#ifndef CONFIG_PREEMPT_RT -+static u8 *nf_get_nf_dup_skb_recursion(void) -+{ -+ return this_cpu_ptr(&softnet_data.xmit.nf_dup_skb_recursion); -+} -+#else -+ -+static u8 *nf_get_nf_dup_skb_recursion(void) -+{ -+ return ¤t->net_xmit.nf_dup_skb_recursion; -+} -+ -+#endif -+ - static void nf_do_netdev_egress(struct sk_buff *skb, struct net_device *dev, - enum nf_dev_hooks hook) - { -diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c -index 08246ef..a9743a1 100644 ---- a/net/netfilter/nft_fwd_netdev.c -+++ b/net/netfilter/nft_fwd_netdev.c -@@ -95,6 +95,7 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr, - struct nft_regs *regs, - const struct nft_pktinfo *pkt) - { -+ u8 *nf_dup_skb_recursion = nf_get_nf_dup_skb_recursion(); - struct nft_fwd_neigh *priv = nft_expr_priv(expr); - void *addr = ®s->data[priv->sreg_addr]; - int oif = regs->data[priv->sreg_dev]; -@@ -143,6 +144,11 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr, - goto out; - } - -+ if (*nf_dup_skb_recursion > NF_RECURSION_LIMIT) { -+ verdict = NF_DROP; -+ goto out; -+ } -+ - dev = dev_get_by_index_rcu(nft_net(pkt), oif); - if (dev == NULL) { - verdict = NF_DROP; -@@ -160,7 +166,9 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr, - - skb->dev = dev; - skb_clear_tstamp(skb); -+ (*nf_dup_skb_recursion)++; - neigh_xmit(neigh_table, dev, addr, skb); -+ (*nf_dup_skb_recursion)--; - out: - regs->verdict.code = verdict; - } diff --git a/1145-netfilter-xtables-restrict-several-matches-to-inet-family.patch b/1145-netfilter-xtables-restrict-several-matches-to-inet-family.patch deleted file mode 100644 index ebf03d389..000000000 --- a/1145-netfilter-xtables-restrict-several-matches-to-inet-family.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 2dd0f2f9dede63706b7b211f6ae7c0b0db170e7b Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:16 +0200 -Subject: [PATCH] netfilter: xtables: restrict several matches to inet family - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit b6fe26f86a16 - -commit b6fe26f86a1649f84e057f3f15605b08eda15497 -Author: Pablo Neira Ayuso -Date: Wed Apr 15 12:21:00 2026 +0200 - - netfilter: xtables: restrict several matches to inet family - - This is a partial revert of: - - commit ab4f21e6fb1c ("netfilter: xtables: use NFPROTO_UNSPEC in more extensions") - - to allow ipv4 and ipv6 only. - - - xt_mac - - xt_owner - - xt_physdev - - These extensions are not used by ebtables in userspace. - - Moreover, xt_realm is only for ipv4, since dst->tclassid is ipv4 - specific. - - Fixes: ab4f21e6fb1c ("netfilter: xtables: use NFPROTO_UNSPEC in more extensions") - Reported-by: "Kito Xu (veritas501)" - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c -index 81649da..bd23547 100644 ---- a/net/netfilter/xt_mac.c -+++ b/net/netfilter/xt_mac.c -@@ -38,25 +38,37 @@ static bool mac_mt(const struct sk_buff *skb, struct xt_action_param *par) - return ret; - } - --static struct xt_match mac_mt_reg __read_mostly = { -- .name = "mac", -- .revision = 0, -- .family = NFPROTO_UNSPEC, -- .match = mac_mt, -- .matchsize = sizeof(struct xt_mac_info), -- .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) | -- (1 << NF_INET_FORWARD), -- .me = THIS_MODULE, -+static struct xt_match mac_mt_reg[] __read_mostly = { -+ { -+ .name = "mac", -+ .family = NFPROTO_IPV4, -+ .match = mac_mt, -+ .matchsize = sizeof(struct xt_mac_info), -+ .hooks = (1 << NF_INET_PRE_ROUTING) | -+ (1 << NF_INET_LOCAL_IN) | -+ (1 << NF_INET_FORWARD), -+ .me = THIS_MODULE, -+ }, -+ { -+ .name = "mac", -+ .family = NFPROTO_IPV6, -+ .match = mac_mt, -+ .matchsize = sizeof(struct xt_mac_info), -+ .hooks = (1 << NF_INET_PRE_ROUTING) | -+ (1 << NF_INET_LOCAL_IN) | -+ (1 << NF_INET_FORWARD), -+ .me = THIS_MODULE, -+ }, - }; - - static int __init mac_mt_init(void) - { -- return xt_register_match(&mac_mt_reg); -+ return xt_register_matches(mac_mt_reg, ARRAY_SIZE(mac_mt_reg)); - } - - static void __exit mac_mt_exit(void) - { -- xt_unregister_match(&mac_mt_reg); -+ xt_unregister_matches(mac_mt_reg, ARRAY_SIZE(mac_mt_reg)); - } - - module_init(mac_mt_init); -diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c -index 5033288..7be2fe2 100644 ---- a/net/netfilter/xt_owner.c -+++ b/net/netfilter/xt_owner.c -@@ -127,26 +127,39 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) - return true; - } - --static struct xt_match owner_mt_reg __read_mostly = { -- .name = "owner", -- .revision = 1, -- .family = NFPROTO_UNSPEC, -- .checkentry = owner_check, -- .match = owner_mt, -- .matchsize = sizeof(struct xt_owner_match_info), -- .hooks = (1 << NF_INET_LOCAL_OUT) | -- (1 << NF_INET_POST_ROUTING), -- .me = THIS_MODULE, -+static struct xt_match owner_mt_reg[] __read_mostly = { -+ { -+ .name = "owner", -+ .revision = 1, -+ .family = NFPROTO_IPV4, -+ .checkentry = owner_check, -+ .match = owner_mt, -+ .matchsize = sizeof(struct xt_owner_match_info), -+ .hooks = (1 << NF_INET_LOCAL_OUT) | -+ (1 << NF_INET_POST_ROUTING), -+ .me = THIS_MODULE, -+ }, -+ { -+ .name = "owner", -+ .revision = 1, -+ .family = NFPROTO_IPV6, -+ .checkentry = owner_check, -+ .match = owner_mt, -+ .matchsize = sizeof(struct xt_owner_match_info), -+ .hooks = (1 << NF_INET_LOCAL_OUT) | -+ (1 << NF_INET_POST_ROUTING), -+ .me = THIS_MODULE, -+ } - }; - - static int __init owner_mt_init(void) - { -- return xt_register_match(&owner_mt_reg); -+ return xt_register_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg)); - } - - static void __exit owner_mt_exit(void) - { -- xt_unregister_match(&owner_mt_reg); -+ xt_unregister_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg)); - } - - module_init(owner_mt_init); -diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c -index 343e65f..130842c 100644 ---- a/net/netfilter/xt_physdev.c -+++ b/net/netfilter/xt_physdev.c -@@ -115,24 +115,33 @@ static int physdev_mt_check(const struct xt_mtchk_param *par) - return 0; - } - --static struct xt_match physdev_mt_reg __read_mostly = { -- .name = "physdev", -- .revision = 0, -- .family = NFPROTO_UNSPEC, -- .checkentry = physdev_mt_check, -- .match = physdev_mt, -- .matchsize = sizeof(struct xt_physdev_info), -- .me = THIS_MODULE, -+static struct xt_match physdev_mt_reg[] __read_mostly = { -+ { -+ .name = "physdev", -+ .family = NFPROTO_IPV4, -+ .checkentry = physdev_mt_check, -+ .match = physdev_mt, -+ .matchsize = sizeof(struct xt_physdev_info), -+ .me = THIS_MODULE, -+ }, -+ { -+ .name = "physdev", -+ .family = NFPROTO_IPV6, -+ .checkentry = physdev_mt_check, -+ .match = physdev_mt, -+ .matchsize = sizeof(struct xt_physdev_info), -+ .me = THIS_MODULE, -+ }, - }; - - static int __init physdev_mt_init(void) - { -- return xt_register_match(&physdev_mt_reg); -+ return xt_register_matches(physdev_mt_reg, ARRAY_SIZE(physdev_mt_reg)); - } - - static void __exit physdev_mt_exit(void) - { -- xt_unregister_match(&physdev_mt_reg); -+ xt_unregister_matches(physdev_mt_reg, ARRAY_SIZE(physdev_mt_reg)); - } - - module_init(physdev_mt_init); -diff --git a/net/netfilter/xt_realm.c b/net/netfilter/xt_realm.c -index 6df485f..61b2f1e 100644 ---- a/net/netfilter/xt_realm.c -+++ b/net/netfilter/xt_realm.c -@@ -33,7 +33,7 @@ static struct xt_match realm_mt_reg __read_mostly = { - .matchsize = sizeof(struct xt_realm_info), - .hooks = (1 << NF_INET_POST_ROUTING) | (1 << NF_INET_FORWARD) | - (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_LOCAL_IN), -- .family = NFPROTO_UNSPEC, -+ .family = NFPROTO_IPV4, - .me = THIS_MODULE - }; - diff --git a/1146-netfilter-x-tables-add-check-hooks-to-matches-and-targets.patch b/1146-netfilter-x-tables-add-check-hooks-to-matches-and-targets.patch deleted file mode 100644 index 8ccfb25a3..000000000 --- a/1146-netfilter-x-tables-add-check-hooks-to-matches-and-targets.patch +++ /dev/null @@ -1,487 +0,0 @@ -From 65acf9af5571ee9fd69dd8d8e4e5b7a423905d3b Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:22:59 +0200 -Subject: [PATCH] netfilter: x_tables: add .check_hooks to matches and targets - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 6813985ca456 - -commit 6813985ca456d1f5677ad9554f55805cbf27e16f -Author: Pablo Neira Ayuso -Date: Tue Apr 28 17:35:18 2026 +0200 - - netfilter: x_tables: add .check_hooks to matches and targets - - Add a new .check_hooks interface for checking if the match/target is - used from the validate hook according to its configuration. - - Move existing conditional hook check based on the match/target - configuration from .checkentry to .check_hooks for the following - matches/targets: - - - addrtype - - devgroup - - physdev - - policy - - set - - TCPMSS - - SET - - This is a preparation patch to fix nft_compat, not functional changes - are intended. - - Based on patch from Florian Westphal. - - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h -index 5897f3d..53b1f25 100644 ---- a/include/linux/netfilter/x_tables.h -+++ b/include/linux/netfilter/x_tables.h -@@ -156,6 +156,9 @@ struct xt_match { - /* Called when user tries to insert an entry of this type. */ - int (*checkentry)(const struct xt_mtchk_param *); - -+ /* Called to validate hooks based on the match configuration. */ -+ int (*check_hooks)(const struct xt_mtchk_param *); -+ - /* Called when entry of this type deleted. */ - void (*destroy)(const struct xt_mtdtor_param *); - #ifdef CONFIG_NETFILTER_XTABLES_COMPAT -@@ -197,6 +200,9 @@ struct xt_target { - /* Should return 0 on success or an error code otherwise (-Exxxx). */ - int (*checkentry)(const struct xt_tgchk_param *); - -+ /* Called to validate hooks based on the target configuration. */ -+ int (*check_hooks)(const struct xt_tgchk_param *); -+ - /* Called when entry of this type deleted. */ - void (*destroy)(const struct xt_tgdtor_param *); - #ifdef CONFIG_NETFILTER_XTABLES_COMPAT -@@ -289,8 +295,10 @@ bool xt_find_jump_offset(const unsigned int *offsets, - - int xt_check_proc_name(const char *name, unsigned int size); - -+int xt_check_hooks_match(struct xt_mtchk_param *par); - int xt_check_match(struct xt_mtchk_param *, unsigned int size, u16 proto, - bool inv_proto); -+int xt_check_hooks_target(struct xt_tgchk_param *par); - int xt_check_target(struct xt_tgchk_param *, unsigned int size, u16 proto, - bool inv_proto); - -diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c -index 10530a0..9be7832 100644 ---- a/net/netfilter/x_tables.c -+++ b/net/netfilter/x_tables.c -@@ -477,11 +477,9 @@ int xt_check_proc_name(const char *name, unsigned int size) - } - EXPORT_SYMBOL(xt_check_proc_name); - --int xt_check_match(struct xt_mtchk_param *par, -- unsigned int size, u16 proto, bool inv_proto) -+static int xt_check_match_common(struct xt_mtchk_param *par, -+ unsigned int size, u16 proto, bool inv_proto) - { -- int ret; -- - if (XT_ALIGN(par->match->matchsize) != size && - par->match->matchsize != -1) { - /* -@@ -530,6 +528,14 @@ int xt_check_match(struct xt_mtchk_param *par, - par->match->proto); - return -EINVAL; - } -+ -+ return 0; -+} -+ -+static int xt_checkentry_match(struct xt_mtchk_param *par) -+{ -+ int ret; -+ - if (par->match->checkentry != NULL) { - ret = par->match->checkentry(par); - if (ret < 0) -@@ -538,8 +544,34 @@ int xt_check_match(struct xt_mtchk_param *par, - /* Flag up potential errors. */ - return -EIO; - } -+ -+ return 0; -+} -+ -+int xt_check_hooks_match(struct xt_mtchk_param *par) -+{ -+ if (par->match->check_hooks != NULL) -+ return par->match->check_hooks(par); -+ - return 0; - } -+EXPORT_SYMBOL_GPL(xt_check_hooks_match); -+ -+int xt_check_match(struct xt_mtchk_param *par, -+ unsigned int size, u16 proto, bool inv_proto) -+{ -+ int ret; -+ -+ ret = xt_check_match_common(par, size, proto, inv_proto); -+ if (ret < 0) -+ return ret; -+ -+ ret = xt_check_hooks_match(par); -+ if (ret < 0) -+ return ret; -+ -+ return xt_checkentry_match(par); -+} - EXPORT_SYMBOL_GPL(xt_check_match); - - /** xt_check_entry_match - check that matches end before start of target -@@ -1008,11 +1040,9 @@ bool xt_find_jump_offset(const unsigned int *offsets, - } - EXPORT_SYMBOL(xt_find_jump_offset); - --int xt_check_target(struct xt_tgchk_param *par, -- unsigned int size, u16 proto, bool inv_proto) -+static int xt_check_target_common(struct xt_tgchk_param *par, -+ unsigned int size, u16 proto, bool inv_proto) - { -- int ret; -- - if (XT_ALIGN(par->target->targetsize) != size) { - pr_err_ratelimited("%s_tables: %s.%u target: invalid size %u (kernel) != (user) %u\n", - xt_prefix[par->family], par->target->name, -@@ -1057,6 +1087,23 @@ int xt_check_target(struct xt_tgchk_param *par, - par->target->proto); - return -EINVAL; - } -+ -+ return 0; -+} -+ -+int xt_check_hooks_target(struct xt_tgchk_param *par) -+{ -+ if (par->target->check_hooks != NULL) -+ return par->target->check_hooks(par); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(xt_check_hooks_target); -+ -+static int xt_checkentry_target(struct xt_tgchk_param *par) -+{ -+ int ret; -+ - if (par->target->checkentry != NULL) { - ret = par->target->checkentry(par); - if (ret < 0) -@@ -1067,6 +1114,22 @@ int xt_check_target(struct xt_tgchk_param *par, - } - return 0; - } -+ -+int xt_check_target(struct xt_tgchk_param *par, -+ unsigned int size, u16 proto, bool inv_proto) -+{ -+ int ret; -+ -+ ret = xt_check_target_common(par, size, proto, inv_proto); -+ if (ret < 0) -+ return ret; -+ -+ ret = xt_check_hooks_target(par); -+ if (ret < 0) -+ return ret; -+ -+ return xt_checkentry_target(par); -+} - EXPORT_SYMBOL_GPL(xt_check_target); - - /** -diff --git a/net/netfilter/xt_addrtype.c b/net/netfilter/xt_addrtype.c -index a770889..913dbe3 100644 ---- a/net/netfilter/xt_addrtype.c -+++ b/net/netfilter/xt_addrtype.c -@@ -153,14 +153,10 @@ addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) - return ret; - } - --static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) -+static int addrtype_mt_check_hooks(const struct xt_mtchk_param *par) - { -- const char *errmsg = "both incoming and outgoing interface limitation cannot be selected"; - struct xt_addrtype_info_v1 *info = par->matchinfo; -- -- if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN && -- info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) -- goto err; -+ const char *errmsg; - - if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) | - (1 << NF_INET_LOCAL_IN)) && -@@ -176,6 +172,21 @@ static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) - goto err; - } - -+ return 0; -+err: -+ pr_info_ratelimited("%s\n", errmsg); -+ return -EINVAL; -+} -+ -+static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) -+{ -+ const char *errmsg = "both incoming and outgoing interface limitation cannot be selected"; -+ struct xt_addrtype_info_v1 *info = par->matchinfo; -+ -+ if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN && -+ info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) -+ goto err; -+ - #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) - if (par->family == NFPROTO_IPV6) { - if ((info->source | info->dest) & XT_ADDRTYPE_BLACKHOLE) { -@@ -211,6 +222,7 @@ static struct xt_match addrtype_mt_reg[] __read_mostly = { - .family = NFPROTO_IPV4, - .revision = 1, - .match = addrtype_mt_v1, -+ .check_hooks = addrtype_mt_check_hooks, - .checkentry = addrtype_mt_checkentry_v1, - .matchsize = sizeof(struct xt_addrtype_info_v1), - .me = THIS_MODULE -@@ -221,6 +233,7 @@ static struct xt_match addrtype_mt_reg[] __read_mostly = { - .family = NFPROTO_IPV6, - .revision = 1, - .match = addrtype_mt_v1, -+ .check_hooks = addrtype_mt_check_hooks, - .checkentry = addrtype_mt_checkentry_v1, - .matchsize = sizeof(struct xt_addrtype_info_v1), - .me = THIS_MODULE -diff --git a/net/netfilter/xt_devgroup.c b/net/netfilter/xt_devgroup.c -index 9520dd0..6d1a44a 100644 ---- a/net/netfilter/xt_devgroup.c -+++ b/net/netfilter/xt_devgroup.c -@@ -33,14 +33,10 @@ static bool devgroup_mt(const struct sk_buff *skb, struct xt_action_param *par) - return true; - } - --static int devgroup_mt_checkentry(const struct xt_mtchk_param *par) -+static int devgroup_mt_check_hooks(const struct xt_mtchk_param *par) - { - const struct xt_devgroup_info *info = par->matchinfo; - -- if (info->flags & ~(XT_DEVGROUP_MATCH_SRC | XT_DEVGROUP_INVERT_SRC | -- XT_DEVGROUP_MATCH_DST | XT_DEVGROUP_INVERT_DST)) -- return -EINVAL; -- - if (info->flags & XT_DEVGROUP_MATCH_SRC && - par->hook_mask & ~((1 << NF_INET_PRE_ROUTING) | - (1 << NF_INET_LOCAL_IN) | -@@ -56,9 +52,21 @@ static int devgroup_mt_checkentry(const struct xt_mtchk_param *par) - return 0; - } - -+static int devgroup_mt_checkentry(const struct xt_mtchk_param *par) -+{ -+ const struct xt_devgroup_info *info = par->matchinfo; -+ -+ if (info->flags & ~(XT_DEVGROUP_MATCH_SRC | XT_DEVGROUP_INVERT_SRC | -+ XT_DEVGROUP_MATCH_DST | XT_DEVGROUP_INVERT_DST)) -+ return -EINVAL; -+ -+ return 0; -+} -+ - static struct xt_match devgroup_mt_reg __read_mostly = { - .name = "devgroup", - .match = devgroup_mt, -+ .check_hooks = devgroup_mt_check_hooks, - .checkentry = devgroup_mt_checkentry, - .matchsize = sizeof(struct xt_devgroup_info), - .family = NFPROTO_UNSPEC, -diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c -index 130842c..e6025d7 100644 ---- a/net/netfilter/xt_physdev.c -+++ b/net/netfilter/xt_physdev.c -@@ -91,14 +91,10 @@ physdev_mt(const struct sk_buff *skb, struct xt_action_param *par) - return (!!ret ^ !(info->invert & XT_PHYSDEV_OP_OUT)); - } - --static int physdev_mt_check(const struct xt_mtchk_param *par) -+static int physdev_mt_check_hooks(const struct xt_mtchk_param *par) - { - const struct xt_physdev_info *info = par->matchinfo; -- static bool brnf_probed __read_mostly; - -- if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || -- info->bitmask & ~XT_PHYSDEV_OP_MASK) -- return -EINVAL; - if (info->bitmask & (XT_PHYSDEV_OP_OUT | XT_PHYSDEV_OP_ISOUT) && - (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) || - info->invert & XT_PHYSDEV_OP_BRIDGED) && -@@ -107,6 +103,18 @@ static int physdev_mt_check(const struct xt_mtchk_param *par) - return -EINVAL; - } - -+ return 0; -+} -+ -+static int physdev_mt_check(const struct xt_mtchk_param *par) -+{ -+ const struct xt_physdev_info *info = par->matchinfo; -+ static bool brnf_probed __read_mostly; -+ -+ if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || -+ info->bitmask & ~XT_PHYSDEV_OP_MASK) -+ return -EINVAL; -+ - if (!brnf_probed) { - brnf_probed = true; - request_module("br_netfilter"); -@@ -119,6 +127,7 @@ static struct xt_match physdev_mt_reg[] __read_mostly = { - { - .name = "physdev", - .family = NFPROTO_IPV4, -+ .check_hooks = physdev_mt_check_hooks, - .checkentry = physdev_mt_check, - .match = physdev_mt, - .matchsize = sizeof(struct xt_physdev_info), -@@ -127,6 +136,7 @@ static struct xt_match physdev_mt_reg[] __read_mostly = { - { - .name = "physdev", - .family = NFPROTO_IPV6, -+ .check_hooks = physdev_mt_check_hooks, - .checkentry = physdev_mt_check, - .match = physdev_mt, - .matchsize = sizeof(struct xt_physdev_info), -diff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c -index b5fa655..ff54e3a 100644 ---- a/net/netfilter/xt_policy.c -+++ b/net/netfilter/xt_policy.c -@@ -126,13 +126,10 @@ policy_mt(const struct sk_buff *skb, struct xt_action_param *par) - return ret; - } - --static int policy_mt_check(const struct xt_mtchk_param *par) -+static int policy_mt_check_hooks(const struct xt_mtchk_param *par) - { - const struct xt_policy_info *info = par->matchinfo; -- const char *errmsg = "neither incoming nor outgoing policy selected"; -- -- if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) -- goto err; -+ const char *errmsg; - - if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) | - (1 << NF_INET_LOCAL_IN)) && info->flags & XT_POLICY_MATCH_OUT) { -@@ -144,6 +141,21 @@ static int policy_mt_check(const struct xt_mtchk_param *par) - errmsg = "input policy not valid in POSTROUTING and OUTPUT"; - goto err; - } -+ -+ return 0; -+err: -+ pr_info_ratelimited("%s\n", errmsg); -+ return -EINVAL; -+} -+ -+static int policy_mt_check(const struct xt_mtchk_param *par) -+{ -+ const struct xt_policy_info *info = par->matchinfo; -+ const char *errmsg = "neither incoming nor outgoing policy selected"; -+ -+ if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) -+ goto err; -+ - if (info->len > XT_POLICY_MAX_ELEM) { - errmsg = "too many policy elements"; - goto err; -@@ -158,6 +170,7 @@ static struct xt_match policy_mt_reg[] __read_mostly = { - { - .name = "policy", - .family = NFPROTO_IPV4, -+ .check_hooks = policy_mt_check_hooks, - .checkentry = policy_mt_check, - .match = policy_mt, - .matchsize = sizeof(struct xt_policy_info), -@@ -166,6 +179,7 @@ static struct xt_match policy_mt_reg[] __read_mostly = { - { - .name = "policy", - .family = NFPROTO_IPV6, -+ .check_hooks = policy_mt_check_hooks, - .checkentry = policy_mt_check, - .match = policy_mt, - .matchsize = sizeof(struct xt_policy_info), -diff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c -index 731bc2c..4ae04bb 100644 ---- a/net/netfilter/xt_set.c -+++ b/net/netfilter/xt_set.c -@@ -430,6 +430,29 @@ set_target_v3(struct sk_buff *skb, const struct xt_action_param *par) - return XT_CONTINUE; - } - -+static int -+set_target_v3_check_hooks(const struct xt_tgchk_param *par) -+{ -+ const struct xt_set_info_target_v3 *info = par->targinfo; -+ -+ if (info->map_set.index != IPSET_INVALID_ID) { -+ if (strncmp(par->table, "mangle", 7)) { -+ pr_info_ratelimited("--map-set only usable from mangle table\n"); -+ return -EINVAL; -+ } -+ if (((info->flags & IPSET_FLAG_MAP_SKBPRIO) | -+ (info->flags & IPSET_FLAG_MAP_SKBQUEUE)) && -+ (par->hook_mask & ~(1 << NF_INET_FORWARD | -+ 1 << NF_INET_LOCAL_OUT | -+ 1 << NF_INET_POST_ROUTING))) { -+ pr_info_ratelimited("mapping of prio or/and queue is allowed only from OUTPUT/FORWARD/POSTROUTING chains\n"); -+ return -EINVAL; -+ } -+ } -+ -+ return 0; -+} -+ - static int - set_target_v3_checkentry(const struct xt_tgchk_param *par) - { -@@ -459,20 +482,6 @@ set_target_v3_checkentry(const struct xt_tgchk_param *par) - } - - if (info->map_set.index != IPSET_INVALID_ID) { -- if (strncmp(par->table, "mangle", 7)) { -- pr_info_ratelimited("--map-set only usable from mangle table\n"); -- ret = -EINVAL; -- goto cleanup_del; -- } -- if (((info->flags & IPSET_FLAG_MAP_SKBPRIO) | -- (info->flags & IPSET_FLAG_MAP_SKBQUEUE)) && -- (par->hook_mask & ~(1 << NF_INET_FORWARD | -- 1 << NF_INET_LOCAL_OUT | -- 1 << NF_INET_POST_ROUTING))) { -- pr_info_ratelimited("mapping of prio or/and queue is allowed only from OUTPUT/FORWARD/POSTROUTING chains\n"); -- ret = -EINVAL; -- goto cleanup_del; -- } - index = ip_set_nfnl_get_byindex(par->net, - info->map_set.index); - if (index == IPSET_INVALID_ID) { -@@ -672,6 +681,7 @@ static struct xt_target set_targets[] __read_mostly = { - .family = NFPROTO_IPV4, - .target = set_target_v3, - .targetsize = sizeof(struct xt_set_info_target_v3), -+ .check_hooks = set_target_v3_check_hooks, - .checkentry = set_target_v3_checkentry, - .destroy = set_target_v3_destroy, - .me = THIS_MODULE -@@ -682,6 +692,7 @@ static struct xt_target set_targets[] __read_mostly = { - .family = NFPROTO_IPV6, - .target = set_target_v3, - .targetsize = sizeof(struct xt_set_info_target_v3), -+ .check_hooks = set_target_v3_check_hooks, - .checkentry = set_target_v3_checkentry, - .destroy = set_target_v3_destroy, - .me = THIS_MODULE diff --git a/1147-netfilter-nft-compat-run-xt-check-hooks-match-target-from-validate.patch b/1147-netfilter-nft-compat-run-xt-check-hooks-match-target-from-validate.patch deleted file mode 100644 index 2341a91e9..000000000 --- a/1147-netfilter-nft-compat-run-xt-check-hooks-match-target-from-validate.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 0a7bf7be14b96c957f43956b2cec03faeee6a6c7 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:23:00 +0200 -Subject: [PATCH] netfilter: nft_compat: run xt_check_hooks_{match,target}() - from .validate - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 2f768d638d97 - -commit 2f768d638d977eff824f64dcc9639e3fea32da8f -Author: Pablo Neira Ayuso -Date: Tue Apr 28 19:04:07 2026 +0200 - - netfilter: nft_compat: run xt_check_hooks_{match,target}() from .validate - - Several matches and one target check that the hook is correct from - checkentry(), however, the basechain is only available from - nft_table_validate(). - - This patch uses xt_check_hooks_{match,target}() from the nft_compat - expression .validate path. - - This patch sets the table in the nft_ctx struct in nft_table_validate() - which is required by this patch. - - Based on patch from Florian Westphal. - - Fixes: 0ca743a55991 ("netfilter: nf_tables: add compatibility layer for x_tables") - Reported-by: Xiang Mei - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 32155f1..188a621 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -4185,6 +4185,7 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) - struct nft_chain *chain; - struct nft_ctx ctx = { - .net = net, -+ .table = (struct nft_table *)table, - .family = table->family, - }; - int err = 0; -diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c -index 72711d6..c58a93d 100644 ---- a/net/netfilter/nft_compat.c -+++ b/net/netfilter/nft_compat.c -@@ -260,10 +260,10 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, - return ret; - } - -- nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv); -- - nft_compat_wait_for_destructors(ctx->net); - -+ nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv); -+ - ret = xt_check_target(&par, size, proto, inv); - if (ret < 0) { - if (ret == -ENOENT) { -@@ -352,8 +352,6 @@ static int nft_target_dump(struct sk_buff *skb, - static int nft_target_validate(const struct nft_ctx *ctx, - const struct nft_expr *expr) - { -- struct xt_target *target = expr->ops->data; -- unsigned int hook_mask = 0; - int ret; - - if (ctx->family != NFPROTO_IPV4 && -@@ -376,11 +374,21 @@ static int nft_target_validate(const struct nft_ctx *ctx, - const struct nft_base_chain *basechain = - nft_base_chain(ctx->chain); - const struct nf_hook_ops *ops = &basechain->ops; -+ unsigned int hook_mask = 1 << ops->hooknum; -+ struct xt_target *target = expr->ops->data; -+ void *info = nft_expr_priv(expr); -+ struct xt_tgchk_param par; -+ union nft_entry e = {}; - -- hook_mask = 1 << ops->hooknum; - if (target->hooks && !(hook_mask & target->hooks)) - return -EINVAL; - -+ nft_target_set_tgchk_param(&par, ctx, target, info, &e, 0, false); -+ -+ ret = xt_check_hooks_target(&par); -+ if (ret < 0) -+ return ret; -+ - ret = nft_compat_chain_validate_dependency(ctx, target->table); - if (ret < 0) - return ret; -@@ -513,10 +521,10 @@ __nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, - return ret; - } - -- nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv); -- - nft_compat_wait_for_destructors(ctx->net); - -+ nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv); -+ - return xt_check_match(&par, size, proto, inv); - } - -@@ -612,8 +620,6 @@ static int nft_match_large_dump(struct sk_buff *skb, - static int nft_match_validate(const struct nft_ctx *ctx, - const struct nft_expr *expr) - { -- struct xt_match *match = expr->ops->data; -- unsigned int hook_mask = 0; - int ret; - - if (ctx->family != NFPROTO_IPV4 && -@@ -636,11 +642,30 @@ static int nft_match_validate(const struct nft_ctx *ctx, - const struct nft_base_chain *basechain = - nft_base_chain(ctx->chain); - const struct nf_hook_ops *ops = &basechain->ops; -+ unsigned int hook_mask = 1 << ops->hooknum; -+ struct xt_match *match = expr->ops->data; -+ size_t size = XT_ALIGN(match->matchsize); -+ struct xt_mtchk_param par; -+ union nft_entry e = {}; -+ void *info; - -- hook_mask = 1 << ops->hooknum; - if (match->hooks && !(hook_mask & match->hooks)) - return -EINVAL; - -+ if (NFT_EXPR_SIZE(size) > NFT_MATCH_LARGE_THRESH) { -+ struct nft_xt_match_priv *priv = nft_expr_priv(expr); -+ -+ info = priv->info; -+ } else { -+ info = nft_expr_priv(expr); -+ } -+ -+ nft_match_set_mtchk_param(&par, ctx, match, info, &e, 0, false); -+ -+ ret = xt_check_hooks_match(&par); -+ if (ret < 0) -+ return ret; -+ - ret = nft_compat_chain_validate_dependency(ctx, match->table); - if (ret < 0) - return ret; diff --git a/1148-netfilter-xt-ct-fix-usersize-for-v1-and-v2-revision.patch b/1148-netfilter-xt-ct-fix-usersize-for-v1-and-v2-revision.patch deleted file mode 100644 index 5a2a35824..000000000 --- a/1148-netfilter-xt-ct-fix-usersize-for-v1-and-v2-revision.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 9b62200a0fb5be4d5f78d4911d534b2cda92d079 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:23:01 +0200 -Subject: [PATCH] netfilter: xt_CT: fix usersize for v1 and v2 revision - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 8bedb6c46945 - -commit 8bedb6c46945752a688d9b0cf2021e0e68b1876c -Author: Florian Westphal -Date: Tue Apr 28 19:37:57 2026 +0200 - - netfilter: xt_CT: fix usersize for v1 and v2 revision - - While resurrecting the conntrack-tool test cases I found following bug: - In: - iptables -I OUTPUT -t raw -p 13 -j CT --timeout test-generic - Out: - [0:0] -A OUTPUT -p 13 -j CT --timeout test - - Data after first four bytes of the timeout policy name is never - copied to userspace because its treated as kernel-only. - - Fixes: ec2318904965 ("xtables: extend matches and targets with .usersize") - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c -index 3ba94c3..23f46bc 100644 ---- a/net/netfilter/xt_CT.c -+++ b/net/netfilter/xt_CT.c -@@ -350,7 +350,7 @@ static struct xt_target xt_ct_tg_reg[] __read_mostly = { - .family = NFPROTO_IPV4, - .revision = 1, - .targetsize = sizeof(struct xt_ct_target_info_v1), -- .usersize = offsetof(struct xt_ct_target_info, ct), -+ .usersize = offsetof(struct xt_ct_target_info_v1, ct), - .checkentry = xt_ct_tg_check_v1, - .destroy = xt_ct_tg_destroy_v1, - .target = xt_ct_target_v1, -@@ -362,7 +362,7 @@ static struct xt_target xt_ct_tg_reg[] __read_mostly = { - .family = NFPROTO_IPV4, - .revision = 2, - .targetsize = sizeof(struct xt_ct_target_info_v1), -- .usersize = offsetof(struct xt_ct_target_info, ct), -+ .usersize = offsetof(struct xt_ct_target_info_v1, ct), - .checkentry = xt_ct_tg_check_v2, - .destroy = xt_ct_tg_destroy_v1, - .target = xt_ct_target_v1, -@@ -394,7 +394,7 @@ static struct xt_target xt_ct_tg_reg[] __read_mostly = { - .family = NFPROTO_IPV6, - .revision = 1, - .targetsize = sizeof(struct xt_ct_target_info_v1), -- .usersize = offsetof(struct xt_ct_target_info, ct), -+ .usersize = offsetof(struct xt_ct_target_info_v1, ct), - .checkentry = xt_ct_tg_check_v1, - .destroy = xt_ct_tg_destroy_v1, - .target = xt_ct_target_v1, -@@ -406,7 +406,7 @@ static struct xt_target xt_ct_tg_reg[] __read_mostly = { - .family = NFPROTO_IPV6, - .revision = 2, - .targetsize = sizeof(struct xt_ct_target_info_v1), -- .usersize = offsetof(struct xt_ct_target_info, ct), -+ .usersize = offsetof(struct xt_ct_target_info_v1, ct), - .checkentry = xt_ct_tg_check_v2, - .destroy = xt_ct_tg_destroy_v1, - .target = xt_ct_target_v1, diff --git a/1149-netfilter-nf-tables-fix-netdev-hook-allocation-memleak-with-dormant-tables.patch b/1149-netfilter-nf-tables-fix-netdev-hook-allocation-memleak-with-dormant-tables.patch deleted file mode 100644 index 617900440..000000000 --- a/1149-netfilter-nf-tables-fix-netdev-hook-allocation-memleak-with-dormant-tables.patch +++ /dev/null @@ -1,631 +0,0 @@ -From 56d449ab32e8a5457a93885e2d7a3e8d141ad11c Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:23:03 +0200 -Subject: [PATCH] netfilter: nf_tables: fix netdev hook allocation memleak with - dormant tables - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 63bac0278603 - -commit 63bac027860308d1344f761cb47aabb3b30973fd -Author: Florian Westphal -Date: Wed Apr 29 08:21:35 2026 +0200 - - netfilter: nf_tables: fix netdev hook allocation memleak with dormant tables - - sashiko says: - could the related code in __nf_tables_abort() leak the struct nft_hook objects when the table is dormant? - - In __nf_tables_abort(), when rolling back a NEWCHAIN transaction that - updates hooks, the code conditionally unregisters and frees the hooks only - if the table is not dormant [..] - if (!(table->flags & NFT_TABLE_F_DORMANT)) { - nft_netdev_unregister_hooks(net, - &nft_trans_chain_hooks(trans), - true); - } - ... - nft_trans_destroy(trans); - - Unfortunately netdev family mixes hook registration and allocation. - Push table struct down and only check for the flag to unregister. - - Fixes: 216e7bf7402c ("netfilter: nf_tables: skip netdev hook unregistration if table is dormant") - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index 188a621..9883e64 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -379,7 +379,34 @@ static void nft_netdev_hook_unlink_free_rcu(struct nft_hook *hook) - nft_netdev_hook_free_rcu(hook); - } - -+static void nft_trans_hook_destroy(struct nft_trans_hook *trans_hook) -+{ -+ list_del(&trans_hook->list); -+ kfree(trans_hook); -+} -+ -+static void nft_netdev_unregister_trans_hook(struct net *net, -+ const struct nft_table *table, -+ struct list_head *hook_list) -+{ -+ struct nft_trans_hook *trans_hook, *next; -+ struct nf_hook_ops *ops; -+ struct nft_hook *hook; -+ -+ list_for_each_entry_safe(trans_hook, next, hook_list, list) { -+ hook = trans_hook->hook; -+ -+ if (!(table->flags & NFT_TABLE_F_DORMANT)) { -+ list_for_each_entry(ops, &hook->ops_list, list) -+ nf_unregister_net_hook(net, ops); -+ } -+ nft_netdev_hook_unlink_free_rcu(hook); -+ nft_trans_hook_destroy(trans_hook); -+ } -+} -+ - static void nft_netdev_unregister_hooks(struct net *net, -+ const struct nft_table *table, - struct list_head *hook_list, - bool release_netdev) - { -@@ -387,8 +414,10 @@ static void nft_netdev_unregister_hooks(struct net *net, - struct nf_hook_ops *ops; - - list_for_each_entry_safe(hook, next, hook_list, list) { -- list_for_each_entry(ops, &hook->ops_list, list) -- nf_unregister_net_hook(net, ops); -+ if (!(table->flags & NFT_TABLE_F_DORMANT)) { -+ list_for_each_entry(ops, &hook->ops_list, list) -+ nf_unregister_net_hook(net, ops); -+ } - if (release_netdev) - nft_netdev_hook_unlink_free_rcu(hook); - } -@@ -425,20 +454,25 @@ static void __nf_tables_unregister_hook(struct net *net, - struct nft_base_chain *basechain; - const struct nf_hook_ops *ops; - -- if (table->flags & NFT_TABLE_F_DORMANT || -- !nft_is_base_chain(chain)) -+ if (!nft_is_base_chain(chain)) - return; - basechain = nft_base_chain(chain); - ops = &basechain->ops; - -+ /* must also be called for dormant tables */ -+ if (nft_base_chain_netdev(table->family, basechain->ops.hooknum)) { -+ nft_netdev_unregister_hooks(net, table, &basechain->hook_list, -+ release_netdev); -+ return; -+ } -+ -+ if (table->flags & NFT_TABLE_F_DORMANT) -+ return; -+ - if (basechain->type->ops_unregister) - return basechain->type->ops_unregister(net, ops); - -- if (nft_base_chain_netdev(table->family, basechain->ops.hooknum)) -- nft_netdev_unregister_hooks(net, &basechain->hook_list, -- release_netdev); -- else -- nf_unregister_net_hook(net, &basechain->ops); -+ nf_unregister_net_hook(net, &basechain->ops); - } - - static void nf_tables_unregister_hook(struct net *net, -@@ -1991,15 +2025,69 @@ static int nft_nla_put_hook_dev(struct sk_buff *skb, struct nft_hook *hook) - return nla_put_string(skb, attr, hook->ifname); - } - -+struct nft_hook_dump_ctx { -+ struct nft_hook *first; -+ int n; -+}; -+ -+static int nft_dump_basechain_hook_one(struct sk_buff *skb, -+ struct nft_hook *hook, -+ struct nft_hook_dump_ctx *dump_ctx) -+{ -+ if (!dump_ctx->first) -+ dump_ctx->first = hook; -+ -+ if (nft_nla_put_hook_dev(skb, hook)) -+ return -1; -+ -+ dump_ctx->n++; -+ -+ return 0; -+} -+ -+static int nft_dump_basechain_hook_list(struct sk_buff *skb, -+ const struct net *net, -+ const struct list_head *hook_list, -+ struct nft_hook_dump_ctx *dump_ctx) -+{ -+ struct nft_hook *hook; -+ int err; -+ -+ list_for_each_entry_rcu(hook, hook_list, list, -+ lockdep_commit_lock_is_held(net)) { -+ err = nft_dump_basechain_hook_one(skb, hook, dump_ctx); -+ if (err < 0) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int nft_dump_basechain_trans_hook_list(struct sk_buff *skb, -+ const struct list_head *trans_hook_list, -+ struct nft_hook_dump_ctx *dump_ctx) -+{ -+ struct nft_trans_hook *trans_hook; -+ int err; -+ -+ list_for_each_entry(trans_hook, trans_hook_list, list) { -+ err = nft_dump_basechain_hook_one(skb, trans_hook->hook, dump_ctx); -+ if (err < 0) -+ return err; -+ } -+ -+ return 0; -+} -+ - static int nft_dump_basechain_hook(struct sk_buff *skb, - const struct net *net, int family, - const struct nft_base_chain *basechain, -- const struct list_head *hook_list) -+ const struct list_head *hook_list, -+ const struct list_head *trans_hook_list) - { - const struct nf_hook_ops *ops = &basechain->ops; -- struct nft_hook *hook, *first = NULL; -+ struct nft_hook_dump_ctx dump_hook_ctx = {}; - struct nlattr *nest, *nest_devs; -- int n = 0; - - nest = nla_nest_start_noflag(skb, NFTA_CHAIN_HOOK); - if (nest == NULL) -@@ -2014,23 +2102,23 @@ static int nft_dump_basechain_hook(struct sk_buff *skb, - if (!nest_devs) - goto nla_put_failure; - -- if (!hook_list) -+ if (!hook_list && !trans_hook_list) - hook_list = &basechain->hook_list; - -- list_for_each_entry_rcu(hook, hook_list, list, -- lockdep_commit_lock_is_held(net)) { -- if (!first) -- first = hook; -- -- if (nft_nla_put_hook_dev(skb, hook)) -- goto nla_put_failure; -- n++; -+ if (hook_list && -+ nft_dump_basechain_hook_list(skb, net, hook_list, &dump_hook_ctx)) { -+ goto nla_put_failure; -+ } else if (trans_hook_list && -+ nft_dump_basechain_trans_hook_list(skb, trans_hook_list, -+ &dump_hook_ctx)) { -+ goto nla_put_failure; - } -+ - nla_nest_end(skb, nest_devs); - -- if (n == 1 && -- !hook_is_prefix(first) && -- nla_put_string(skb, NFTA_HOOK_DEV, first->ifname)) -+ if (dump_hook_ctx.n == 1 && -+ !hook_is_prefix(dump_hook_ctx.first) && -+ nla_put_string(skb, NFTA_HOOK_DEV, dump_hook_ctx.first->ifname)) - goto nla_put_failure; - } - nla_nest_end(skb, nest); -@@ -2044,7 +2132,8 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net, - u32 portid, u32 seq, int event, u32 flags, - int family, const struct nft_table *table, - const struct nft_chain *chain, -- const struct list_head *hook_list) -+ const struct list_head *hook_list, -+ const struct list_head *trans_hook_list) - { - struct nlmsghdr *nlh; - -@@ -2060,7 +2149,7 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net, - NFTA_CHAIN_PAD)) - goto nla_put_failure; - -- if (event == NFT_MSG_DELCHAIN && !hook_list) { -+ if (event == NFT_MSG_DELCHAIN && !hook_list && !trans_hook_list) { - nlmsg_end(skb, nlh); - return 0; - } -@@ -2069,7 +2158,8 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net, - const struct nft_base_chain *basechain = nft_base_chain(chain); - struct nft_stats __percpu *stats; - -- if (nft_dump_basechain_hook(skb, net, family, basechain, hook_list)) -+ if (nft_dump_basechain_hook(skb, net, family, basechain, -+ hook_list, trans_hook_list)) - goto nla_put_failure; - - if (nla_put_be32(skb, NFTA_CHAIN_POLICY, -@@ -2105,7 +2195,8 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net, - } - - static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event, -- const struct list_head *hook_list) -+ const struct list_head *hook_list, -+ const struct list_head *trans_hook_list) - { - struct nftables_pernet *nft_net; - struct sk_buff *skb; -@@ -2125,7 +2216,7 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event, - - err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq, - event, flags, ctx->family, ctx->table, -- ctx->chain, hook_list); -+ ctx->chain, hook_list, trans_hook_list); - if (err < 0) { - kfree_skb(skb); - goto err; -@@ -2171,7 +2262,7 @@ static int nf_tables_dump_chains(struct sk_buff *skb, - NFT_MSG_NEWCHAIN, - NLM_F_MULTI, - table->family, table, -- chain, NULL) < 0) -+ chain, NULL, NULL) < 0) - goto done; - - nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -@@ -2225,7 +2316,7 @@ static int nf_tables_getchain(struct sk_buff *skb, const struct nfnl_info *info, - - err = nf_tables_fill_chain_info(skb2, net, NETLINK_CB(skb).portid, - info->nlh->nlmsg_seq, NFT_MSG_NEWCHAIN, -- 0, family, table, chain, NULL); -+ 0, family, table, chain, NULL, NULL); - if (err < 0) - goto err_fill_chain_info; - -@@ -2388,8 +2479,12 @@ static struct nft_hook *nft_hook_list_find(struct list_head *hook_list, - - list_for_each_entry(hook, hook_list, list) { - if (!strncmp(hook->ifname, this->ifname, -- min(hook->ifnamelen, this->ifnamelen))) -+ min(hook->ifnamelen, this->ifnamelen))) { -+ if (hook->flags & NFT_HOOK_REMOVE) -+ continue; -+ - return hook; -+ } - } - - return NULL; -@@ -3148,6 +3243,32 @@ static int nf_tables_newchain(struct sk_buff *skb, const struct nfnl_info *info, - return nf_tables_addchain(&ctx, family, policy, flags, extack); - } - -+static int nft_trans_delhook(struct nft_hook *hook, -+ struct list_head *del_list) -+{ -+ struct nft_trans_hook *trans_hook; -+ -+ trans_hook = kmalloc(sizeof(*trans_hook), GFP_KERNEL); -+ if (!trans_hook) -+ return -ENOMEM; -+ -+ trans_hook->hook = hook; -+ list_add_tail(&trans_hook->list, del_list); -+ hook->flags |= NFT_HOOK_REMOVE; -+ -+ return 0; -+} -+ -+static void nft_trans_delhook_abort(struct list_head *del_list) -+{ -+ struct nft_trans_hook *trans_hook, *next; -+ -+ list_for_each_entry_safe(trans_hook, next, del_list, list) { -+ trans_hook->hook->flags &= ~NFT_HOOK_REMOVE; -+ nft_trans_hook_destroy(trans_hook); -+ } -+} -+ - static int nft_delchain_hook(struct nft_ctx *ctx, - struct nft_base_chain *basechain, - struct netlink_ext_ack *extack) -@@ -3174,7 +3295,10 @@ static int nft_delchain_hook(struct nft_ctx *ctx, - err = -ENOENT; - goto err_chain_del_hook; - } -- list_move(&hook->list, &chain_del_list); -+ if (nft_trans_delhook(hook, &chain_del_list) < 0) { -+ err = -ENOMEM; -+ goto err_chain_del_hook; -+ } - } - - trans = nft_trans_alloc_chain(ctx, NFT_MSG_DELCHAIN); -@@ -3194,7 +3318,7 @@ static int nft_delchain_hook(struct nft_ctx *ctx, - return 0; - - err_chain_del_hook: -- list_splice(&chain_del_list, &basechain->hook_list); -+ nft_trans_delhook_abort(&chain_del_list); - nft_chain_release_hook(&chain_hook); - - return err; -@@ -9139,6 +9263,24 @@ static void nft_hooks_destroy(struct list_head *hook_list) - nft_netdev_hook_unlink_free_rcu(hook); - } - -+static void nft_flowtable_unregister_trans_hook(struct net *net, -+ struct nft_flowtable *flowtable, -+ struct list_head *hook_list) -+{ -+ struct nft_trans_hook *trans_hook, *next; -+ struct nf_hook_ops *ops; -+ struct nft_hook *hook; -+ -+ list_for_each_entry_safe(trans_hook, next, hook_list, list) { -+ hook = trans_hook->hook; -+ list_for_each_entry(ops, &hook->ops_list, list) -+ nft_unregister_flowtable_ops(net, flowtable, ops); -+ -+ nft_netdev_hook_unlink_free_rcu(hook); -+ nft_trans_hook_destroy(trans_hook); -+ } -+} -+ - static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh, - struct nft_flowtable *flowtable, - struct netlink_ext_ack *extack) -@@ -9397,7 +9539,10 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx, - err = -ENOENT; - goto err_flowtable_del_hook; - } -- list_move(&hook->list, &flowtable_del_list); -+ if (nft_trans_delhook(hook, &flowtable_del_list) < 0) { -+ err = -ENOMEM; -+ goto err_flowtable_del_hook; -+ } - } - - trans = nft_trans_alloc(ctx, NFT_MSG_DELFLOWTABLE, -@@ -9418,7 +9563,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx, - return 0; - - err_flowtable_del_hook: -- list_splice(&flowtable_del_list, &flowtable->hook_list); -+ nft_trans_delhook_abort(&flowtable_del_list); - nft_flowtable_hook_release(&flowtable_hook); - - return err; -@@ -9483,8 +9628,10 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net, - u32 portid, u32 seq, int event, - u32 flags, int family, - struct nft_flowtable *flowtable, -- struct list_head *hook_list) -+ struct list_head *hook_list, -+ struct list_head *trans_hook_list) - { -+ struct nft_trans_hook *trans_hook; - struct nlattr *nest, *nest_devs; - struct nft_hook *hook; - struct nlmsghdr *nlh; -@@ -9501,7 +9648,7 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net, - NFTA_FLOWTABLE_PAD)) - goto nla_put_failure; - -- if (event == NFT_MSG_DELFLOWTABLE && !hook_list) { -+ if (event == NFT_MSG_DELFLOWTABLE && !hook_list && !trans_hook_list) { - nlmsg_end(skb, nlh); - return 0; - } -@@ -9521,13 +9668,20 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net, - if (!nest_devs) - goto nla_put_failure; - -- if (!hook_list) -+ if (!hook_list && !trans_hook_list) - hook_list = &flowtable->hook_list; - -- list_for_each_entry_rcu(hook, hook_list, list, -- lockdep_commit_lock_is_held(net)) { -- if (nft_nla_put_hook_dev(skb, hook)) -- goto nla_put_failure; -+ if (hook_list) { -+ list_for_each_entry_rcu(hook, hook_list, list, -+ lockdep_commit_lock_is_held(net)) { -+ if (nft_nla_put_hook_dev(skb, hook)) -+ goto nla_put_failure; -+ } -+ } else if (trans_hook_list) { -+ list_for_each_entry(trans_hook, trans_hook_list, list) { -+ if (nft_nla_put_hook_dev(skb, trans_hook->hook)) -+ goto nla_put_failure; -+ } - } - nla_nest_end(skb, nest_devs); - nla_nest_end(skb, nest); -@@ -9581,7 +9735,7 @@ static int nf_tables_dump_flowtable(struct sk_buff *skb, - NFT_MSG_NEWFLOWTABLE, - NLM_F_MULTI | NLM_F_APPEND, - table->family, -- flowtable, NULL) < 0) -+ flowtable, NULL, NULL) < 0) - goto done; - - nl_dump_check_consistent(cb, nlmsg_hdr(skb)); -@@ -9681,7 +9835,7 @@ static int nf_tables_getflowtable(struct sk_buff *skb, - err = nf_tables_fill_flowtable_info(skb2, net, NETLINK_CB(skb).portid, - info->nlh->nlmsg_seq, - NFT_MSG_NEWFLOWTABLE, 0, family, -- flowtable, NULL); -+ flowtable, NULL, NULL); - if (err < 0) - goto err_fill_flowtable_info; - -@@ -9694,7 +9848,9 @@ static int nf_tables_getflowtable(struct sk_buff *skb, - - static void nf_tables_flowtable_notify(struct nft_ctx *ctx, - struct nft_flowtable *flowtable, -- struct list_head *hook_list, int event) -+ struct list_head *hook_list, -+ struct list_head *trans_hook_list, -+ int event) - { - struct nftables_pernet *nft_net = nft_pernet(ctx->net); - struct sk_buff *skb; -@@ -9714,7 +9870,8 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx, - - err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid, - ctx->seq, event, flags, -- ctx->family, flowtable, hook_list); -+ ctx->family, flowtable, -+ hook_list, trans_hook_list); - if (err < 0) { - kfree_skb(skb); - goto err; -@@ -10248,9 +10405,7 @@ static void nft_commit_release(struct nft_trans *trans) - break; - case NFT_MSG_DELCHAIN: - case NFT_MSG_DESTROYCHAIN: -- if (nft_trans_chain_update(trans)) -- nft_hooks_destroy(&nft_trans_chain_hooks(trans)); -- else -+ if (!nft_trans_chain_update(trans)) - nf_tables_chain_destroy(nft_trans_chain(trans)); - break; - case NFT_MSG_DELRULE: -@@ -10271,9 +10426,7 @@ static void nft_commit_release(struct nft_trans *trans) - break; - case NFT_MSG_DELFLOWTABLE: - case NFT_MSG_DESTROYFLOWTABLE: -- if (nft_trans_flowtable_update(trans)) -- nft_hooks_destroy(&nft_trans_flowtable_hooks(trans)); -- else -+ if (!nft_trans_flowtable_update(trans)) - nf_tables_flowtable_destroy(nft_trans_flowtable(trans)); - break; - } -@@ -11048,31 +11201,28 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) - if (nft_trans_chain_update(trans)) { - nft_chain_commit_update(nft_trans_container_chain(trans)); - nf_tables_chain_notify(&ctx, NFT_MSG_NEWCHAIN, -- &nft_trans_chain_hooks(trans)); -+ &nft_trans_chain_hooks(trans), NULL); - list_splice_rcu(&nft_trans_chain_hooks(trans), - &nft_trans_basechain(trans)->hook_list); - /* trans destroyed after rcu grace period */ - } else { - nft_chain_commit_drop_policy(nft_trans_container_chain(trans)); - nft_clear(net, nft_trans_chain(trans)); -- nf_tables_chain_notify(&ctx, NFT_MSG_NEWCHAIN, NULL); -+ nf_tables_chain_notify(&ctx, NFT_MSG_NEWCHAIN, NULL, NULL); - nft_trans_destroy(trans); - } - break; - case NFT_MSG_DELCHAIN: - case NFT_MSG_DESTROYCHAIN: - if (nft_trans_chain_update(trans)) { -- nf_tables_chain_notify(&ctx, NFT_MSG_DELCHAIN, -+ nf_tables_chain_notify(&ctx, NFT_MSG_DELCHAIN, NULL, - &nft_trans_chain_hooks(trans)); -- if (!(table->flags & NFT_TABLE_F_DORMANT)) { -- nft_netdev_unregister_hooks(net, -- &nft_trans_chain_hooks(trans), -- true); -- } -+ nft_netdev_unregister_trans_hook(net, table, -+ &nft_trans_chain_hooks(trans)); - } else { - nft_chain_del(nft_trans_chain(trans)); - nf_tables_chain_notify(&ctx, NFT_MSG_DELCHAIN, -- NULL); -+ NULL, NULL); - nf_tables_unregister_hook(ctx.net, ctx.table, - nft_trans_chain(trans)); - } -@@ -11178,6 +11328,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) - nf_tables_flowtable_notify(&ctx, - nft_trans_flowtable(trans), - &nft_trans_flowtable_hooks(trans), -+ NULL, - NFT_MSG_NEWFLOWTABLE); - list_splice_rcu(&nft_trans_flowtable_hooks(trans), - &nft_trans_flowtable(trans)->hook_list); -@@ -11186,6 +11337,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) - nf_tables_flowtable_notify(&ctx, - nft_trans_flowtable(trans), - NULL, -+ NULL, - NFT_MSG_NEWFLOWTABLE); - } - nft_trans_destroy(trans); -@@ -11195,16 +11347,18 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) - if (nft_trans_flowtable_update(trans)) { - nf_tables_flowtable_notify(&ctx, - nft_trans_flowtable(trans), -+ NULL, - &nft_trans_flowtable_hooks(trans), - trans->msg_type); -- nft_unregister_flowtable_net_hooks(net, -- nft_trans_flowtable(trans), -- &nft_trans_flowtable_hooks(trans)); -+ nft_flowtable_unregister_trans_hook(net, -+ nft_trans_flowtable(trans), -+ &nft_trans_flowtable_hooks(trans)); - } else { - list_del_rcu(&nft_trans_flowtable(trans)->list); - nf_tables_flowtable_notify(&ctx, - nft_trans_flowtable(trans), - NULL, -+ NULL, - trans->msg_type); - nft_unregister_flowtable_net_hooks(net, - nft_trans_flowtable(trans), -@@ -11346,11 +11500,9 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) - break; - case NFT_MSG_NEWCHAIN: - if (nft_trans_chain_update(trans)) { -- if (!(table->flags & NFT_TABLE_F_DORMANT)) { -- nft_netdev_unregister_hooks(net, -- &nft_trans_chain_hooks(trans), -- true); -- } -+ nft_netdev_unregister_hooks(net, table, -+ &nft_trans_chain_hooks(trans), -+ true); - free_percpu(nft_trans_chain_stats(trans)); - kfree(nft_trans_chain_name(trans)); - nft_trans_destroy(trans); -@@ -11368,8 +11520,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) - case NFT_MSG_DELCHAIN: - case NFT_MSG_DESTROYCHAIN: - if (nft_trans_chain_update(trans)) { -- list_splice(&nft_trans_chain_hooks(trans), -- &nft_trans_basechain(trans)->hook_list); -+ nft_trans_delhook_abort(&nft_trans_chain_hooks(trans)); - } else { - nft_use_inc_restore(&table->use); - nft_clear(trans->net, nft_trans_chain(trans)); -@@ -11483,8 +11634,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) - case NFT_MSG_DELFLOWTABLE: - case NFT_MSG_DESTROYFLOWTABLE: - if (nft_trans_flowtable_update(trans)) { -- list_splice(&nft_trans_flowtable_hooks(trans), -- &nft_trans_flowtable(trans)->hook_list); -+ nft_trans_delhook_abort(&nft_trans_flowtable_hooks(trans)); - } else { - nft_use_inc_restore(&table->use); - nft_clear(trans->net, nft_trans_flowtable(trans)); diff --git a/1150-netfilter-nf-conntrack-expect-restore-helper-propagation-via-expectation.patch b/1150-netfilter-nf-conntrack-expect-restore-helper-propagation-via-expectation.patch deleted file mode 100644 index 642e727c7..000000000 --- a/1150-netfilter-nf-conntrack-expect-restore-helper-propagation-via-expectation.patch +++ /dev/null @@ -1,260 +0,0 @@ -From 5a3930625f5b94ea1c8906d5f8ec7a6c34133018 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:24:34 +0200 -Subject: [PATCH] netfilter: nf_conntrack_expect: restore helper propagation - via expectation - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit dcb0f9aefdd6 - -commit dcb0f9aefdd604d36710fda53c25bd7cf4a3e37a -Author: Pablo Neira Ayuso -Date: Thu May 7 13:00:28 2026 +0200 - - netfilter: nf_conntrack_expect: restore helper propagation via expectation - - A recent series to fix expectations broke helper propagation via - expectation, this mechanism is used by the sip and h323 helper. This - also propagates the conntrack helper to expected connections. I changed - semantics of exp->helper which now tells us the actual helper that - created the expectation. - - Add an explicit assign_helper field to expectations for this purpose - and update helpers to use it. - - Restore this feature for userspace conntrack helper via ctnetlink - nfqueue integration so it is again possible to attach a helper to an - expectation, where it makes sense. This is not restored via ctnetlink - expectation creation as there is no client for such feature. Use the - expectation layer 4 protocol number for the helper lookup for - consistency. - - Make sure the expectation using this helper propagation mechanism also - go away when the helper is unregistered. - - Fixes: 9c42bc9db90a ("netfilter: nf_conntrack_expect: honor expectation helper field") - Fixes: 917b61fa2042 ("netfilter: ctnetlink: ignore explicit helper on new expectations") - Reported-by: Ilya Maximets - Tested-by: Ilya Maximets - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h -index e9a8350..80f50fd 100644 ---- a/include/net/netfilter/nf_conntrack_expect.h -+++ b/include/net/netfilter/nf_conntrack_expect.h -@@ -45,9 +45,12 @@ struct nf_conntrack_expect { - void (*expectfn)(struct nf_conn *new, - struct nf_conntrack_expect *this); - -- /* Helper to assign to new connection */ -+ /* Helper that created this expectation */ - struct nf_conntrack_helper __rcu *helper; - -+ /* Helper to assign to new connection */ -+ struct nf_conntrack_helper __rcu *assign_helper; -+ - /* The conntrack of the master connection */ - struct nf_conn *master; - -diff --git a/net/netfilter/nf_conntrack_broadcast.c b/net/netfilter/nf_conntrack_broadcast.c -index 4f39bf7..75e53fd 100644 ---- a/net/netfilter/nf_conntrack_broadcast.c -+++ b/net/netfilter/nf_conntrack_broadcast.c -@@ -72,6 +72,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, - exp->flags = NF_CT_EXPECT_PERMANENT; - exp->class = NF_CT_EXPECT_CLASS_DEFAULT; - rcu_assign_pointer(exp->helper, helper); -+ rcu_assign_pointer(exp->assign_helper, NULL); - write_pnet(&exp->net, net); - #ifdef CONFIG_NF_CONNTRACK_ZONES - exp->zone = ct->zone; -diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c -index 963f9ac..02a73b2 100644 ---- a/net/netfilter/nf_conntrack_core.c -+++ b/net/netfilter/nf_conntrack_core.c -@@ -1819,14 +1819,17 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, - spin_lock_bh(&nf_conntrack_expect_lock); - exp = nf_ct_find_expectation(net, zone, tuple, !tmpl || nf_ct_is_confirmed(tmpl)); - if (exp) { -+ struct nf_conntrack_helper *assign_helper; -+ - /* Welcome, Mr. Bond. We've been expecting you... */ - __set_bit(IPS_EXPECTED_BIT, &ct->status); - /* exp->master safe, refcnt bumped in nf_ct_find_expectation */ - ct->master = exp->master; -- if (exp->helper) { -+ assign_helper = rcu_dereference(exp->assign_helper); -+ if (assign_helper) { - help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); - if (help) -- rcu_assign_pointer(help->helper, exp->helper); -+ rcu_assign_pointer(help->helper, assign_helper); - } - - #ifdef CONFIG_NF_CONNTRACK_MARK -diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c -index db28801..1bb5bf8 100644 ---- a/net/netfilter/nf_conntrack_expect.c -+++ b/net/netfilter/nf_conntrack_expect.c -@@ -344,6 +344,7 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class, - helper = rcu_dereference(help->helper); - - rcu_assign_pointer(exp->helper, helper); -+ rcu_assign_pointer(exp->assign_helper, NULL); - write_pnet(&exp->net, net); - #ifdef CONFIG_NF_CONNTRACK_ZONES - exp->zone = ct->zone; -diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c -index fbf69d4..8a14404 100644 ---- a/net/netfilter/nf_conntrack_h323_main.c -+++ b/net/netfilter/nf_conntrack_h323_main.c -@@ -642,7 +642,7 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct, - &ct->tuplehash[!dir].tuple.src.u3, - &ct->tuplehash[!dir].tuple.dst.u3, - IPPROTO_TCP, NULL, &port); -- rcu_assign_pointer(exp->helper, &nf_conntrack_helper_h245); -+ rcu_assign_pointer(exp->assign_helper, &nf_conntrack_helper_h245); - - nathook = rcu_dereference(nfct_h323_nat_hook); - if (memcmp(&ct->tuplehash[dir].tuple.src.u3, -@@ -766,7 +766,7 @@ static int expect_callforwarding(struct sk_buff *skb, - nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), - &ct->tuplehash[!dir].tuple.src.u3, &addr, - IPPROTO_TCP, NULL, &port); -- rcu_assign_pointer(exp->helper, nf_conntrack_helper_q931); -+ rcu_assign_pointer(exp->assign_helper, nf_conntrack_helper_q931); - - nathook = rcu_dereference(nfct_h323_nat_hook); - if (memcmp(&ct->tuplehash[dir].tuple.src.u3, -@@ -1233,7 +1233,7 @@ static int expect_q931(struct sk_buff *skb, struct nf_conn *ct, - &ct->tuplehash[!dir].tuple.src.u3 : NULL, - &ct->tuplehash[!dir].tuple.dst.u3, - IPPROTO_TCP, NULL, &port); -- rcu_assign_pointer(exp->helper, nf_conntrack_helper_q931); -+ rcu_assign_pointer(exp->assign_helper, nf_conntrack_helper_q931); - exp->flags = NF_CT_EXPECT_PERMANENT; /* Accept multiple calls */ - - nathook = rcu_dereference(nfct_h323_nat_hook); -@@ -1305,7 +1305,7 @@ static int process_gcf(struct sk_buff *skb, struct nf_conn *ct, - nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), - &ct->tuplehash[!dir].tuple.src.u3, &addr, - IPPROTO_UDP, NULL, &port); -- rcu_assign_pointer(exp->helper, nf_conntrack_helper_ras); -+ rcu_assign_pointer(exp->assign_helper, nf_conntrack_helper_ras); - - if (nf_ct_expect_related(exp, 0) == 0) { - pr_debug("nf_ct_ras: expect RAS "); -@@ -1522,7 +1522,7 @@ static int process_acf(struct sk_buff *skb, struct nf_conn *ct, - &ct->tuplehash[!dir].tuple.src.u3, &addr, - IPPROTO_TCP, NULL, &port); - exp->flags = NF_CT_EXPECT_PERMANENT; -- rcu_assign_pointer(exp->helper, nf_conntrack_helper_q931); -+ rcu_assign_pointer(exp->assign_helper, nf_conntrack_helper_q931); - - if (nf_ct_expect_related(exp, 0) == 0) { - pr_debug("nf_ct_ras: expect Q.931 "); -@@ -1576,7 +1576,7 @@ static int process_lcf(struct sk_buff *skb, struct nf_conn *ct, - &ct->tuplehash[!dir].tuple.src.u3, &addr, - IPPROTO_TCP, NULL, &port); - exp->flags = NF_CT_EXPECT_PERMANENT; -- rcu_assign_pointer(exp->helper, nf_conntrack_helper_q931); -+ rcu_assign_pointer(exp->assign_helper, nf_conntrack_helper_q931); - - if (nf_ct_expect_related(exp, 0) == 0) { - pr_debug("nf_ct_ras: expect Q.931 "); -diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c -index a715304..b594cd2 100644 ---- a/net/netfilter/nf_conntrack_helper.c -+++ b/net/netfilter/nf_conntrack_helper.c -@@ -400,6 +400,11 @@ static bool expect_iter_me(struct nf_conntrack_expect *exp, void *data) - - this = rcu_dereference_protected(exp->helper, - lockdep_is_held(&nf_conntrack_expect_lock)); -+ if (this == me) -+ return true; -+ -+ this = rcu_dereference_protected(exp->assign_helper, -+ lockdep_is_held(&nf_conntrack_expect_lock)); - return this == me; - } - -diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c -index dcef3ef..7e71cbc 100644 ---- a/net/netfilter/nf_conntrack_netlink.c -+++ b/net/netfilter/nf_conntrack_netlink.c -@@ -2655,6 +2655,7 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = { - - static struct nf_conntrack_expect * - ctnetlink_alloc_expect(const struct nlattr *const cda[], struct nf_conn *ct, -+ const struct nf_conntrack_helper *assign_helper, - struct nf_conntrack_tuple *tuple, - struct nf_conntrack_tuple *mask); - -@@ -2881,6 +2882,7 @@ static int - ctnetlink_glue_attach_expect(const struct nlattr *attr, struct nf_conn *ct, - u32 portid, u32 report) - { -+ struct nf_conntrack_helper *assign_helper = NULL; - struct nlattr *cda[CTA_EXPECT_MAX+1]; - struct nf_conntrack_tuple tuple, mask; - struct nf_conntrack_expect *exp; -@@ -2896,8 +2898,18 @@ ctnetlink_glue_attach_expect(const struct nlattr *attr, struct nf_conn *ct, - if (err < 0) - return err; - -+ if (cda[CTA_EXPECT_HELP_NAME]) { -+ const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]); -+ -+ assign_helper = __nf_conntrack_helper_find(helpname, -+ nf_ct_l3num(ct), -+ tuple.dst.protonum); -+ if (!assign_helper) -+ return -EOPNOTSUPP; -+ } -+ - exp = ctnetlink_alloc_expect((const struct nlattr * const *)cda, ct, -- &tuple, &mask); -+ assign_helper, &tuple, &mask); - if (IS_ERR(exp)) - return PTR_ERR(exp); - -@@ -3536,6 +3548,7 @@ ctnetlink_parse_expect_nat(const struct nlattr *attr, - - static struct nf_conntrack_expect * - ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, -+ const struct nf_conntrack_helper *assign_helper, - struct nf_conntrack_tuple *tuple, - struct nf_conntrack_tuple *mask) - { -@@ -3589,6 +3602,7 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, - exp->zone = ct->zone; - #endif - rcu_assign_pointer(exp->helper, helper); -+ rcu_assign_pointer(exp->assign_helper, assign_helper); - exp->tuple = *tuple; - exp->mask.src.u3 = mask->src.u3; - exp->mask.src.u.all = mask->src.u.all; -@@ -3644,7 +3658,7 @@ ctnetlink_create_expect(struct net *net, - ct = nf_ct_tuplehash_to_ctrack(h); - - rcu_read_lock(); -- exp = ctnetlink_alloc_expect(cda, ct, &tuple, &mask); -+ exp = ctnetlink_alloc_expect(cda, ct, NULL, &tuple, &mask); - if (IS_ERR(exp)) { - err = PTR_ERR(exp); - goto err_rcu; -diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c -index b31f31e..25ab92e 100644 ---- a/net/netfilter/nf_conntrack_sip.c -+++ b/net/netfilter/nf_conntrack_sip.c -@@ -1378,7 +1378,7 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff, - nf_ct_expect_init(exp, SIP_EXPECT_SIGNALLING, nf_ct_l3num(ct), - saddr, &daddr, proto, NULL, &port); - exp->timeout.expires = sip_timeout * HZ; -- rcu_assign_pointer(exp->helper, helper); -+ rcu_assign_pointer(exp->assign_helper, helper); - exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE; - - hooks = rcu_dereference(nf_nat_sip_hooks); diff --git a/1151-netfilter-ctnetlink-check-tuple-and-mask-in-expectations-created-via-nfqueue.patch b/1151-netfilter-ctnetlink-check-tuple-and-mask-in-expectations-created-via-nfqueue.patch deleted file mode 100644 index cf4c74620..000000000 --- a/1151-netfilter-ctnetlink-check-tuple-and-mask-in-expectations-created-via-nfqueue.patch +++ /dev/null @@ -1,37 +0,0 @@ -From b837d5c40d7bd2c2bb19b0ac2bcf96a81a130009 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:24:36 +0200 -Subject: [PATCH] netfilter: ctnetlink: check tuple and mask in expectations - created via nfqueue - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit d8ef54c83ad7 - -commit d8ef54c83ad70b81735b506431affadd2f720aa1 -Author: Pablo Neira Ayuso -Date: Thu May 7 23:57:55 2026 +0200 - - netfilter: ctnetlink: check tuple and mask in expectations created via nfqueue - - Ensure the expectation tuple and mask attributes are present in netlink - message, otherwise null-ptr-deref is possible. - - Fixes: bd0779370588 ("netfilter: nfnetlink_queue: allow to attach expectations to conntracks") - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c -index 7e71cbc..caf0506 100644 ---- a/net/netfilter/nf_conntrack_netlink.c -+++ b/net/netfilter/nf_conntrack_netlink.c -@@ -2893,6 +2893,9 @@ ctnetlink_glue_attach_expect(const struct nlattr *attr, struct nf_conn *ct, - if (err < 0) - return err; - -+ if (!cda[CTA_EXPECT_TUPLE] || !cda[CTA_EXPECT_MASK]) -+ return -EINVAL; -+ - err = ctnetlink_glue_exp_parse((const struct nlattr * const *)cda, - ct, &tuple, &mask); - if (err < 0) diff --git a/1152-netfilter-nf-conntrack-sip-get-helper-before-allocating-expectation.patch b/1152-netfilter-nf-conntrack-sip-get-helper-before-allocating-expectation.patch deleted file mode 100644 index 9dbbfde5a..000000000 --- a/1152-netfilter-nf-conntrack-sip-get-helper-before-allocating-expectation.patch +++ /dev/null @@ -1,56 +0,0 @@ -From f2a8d75fdf87f1a3075b27c58f10f0ac902475bc Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:24:37 +0200 -Subject: [PATCH] netfilter: nf_conntrack_sip: get helper before allocating - expectation - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit eb6317739b1e - -commit eb6317739b1ea3ab28791e1f91b24781905fa815 -Author: Li Xiasong -Date: Thu May 7 22:04:22 2026 +0800 - - netfilter: nf_conntrack_sip: get helper before allocating expectation - - process_register_request() allocates an expectation and then checks - whether a conntrack helper is available. If helper lookup fails, the - function returns early and the allocated expectation is left behind. - - Reorder the code to fetch and validate helper before calling - nf_ct_expect_alloc(). This keeps the logic simpler and removes the leak - path while preserving existing behavior. - - Fixes: e14575fa7529 ("netfilter: nf_conntrack: use rcu accessors where needed") - Cc: stable@vger.kernel.org - Signed-off-by: Li Xiasong - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c -index 25ab92e..d5bc99b 100644 ---- a/net/netfilter/nf_conntrack_sip.c -+++ b/net/netfilter/nf_conntrack_sip.c -@@ -1361,6 +1361,10 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff, - goto store_cseq; - } - -+ helper = rcu_dereference(nfct_help(ct)->helper); -+ if (!helper) -+ return NF_DROP; -+ - exp = nf_ct_expect_alloc(ct); - if (!exp) { - nf_ct_helper_log(skb, ct, "cannot alloc expectation"); -@@ -1371,10 +1375,6 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff, - if (sip_direct_signalling) - saddr = &ct->tuplehash[!dir].tuple.src.u3; - -- helper = rcu_dereference(nfct_help(ct)->helper); -- if (!helper) -- return NF_DROP; -- - nf_ct_expect_init(exp, SIP_EXPECT_SIGNALLING, nf_ct_l3num(ct), - saddr, &daddr, proto, NULL, &port); - exp->timeout.expires = sip_timeout * HZ; diff --git a/1153-netfilter-nft-ct-fix-missing-expect-put-in-obj-eval.patch b/1153-netfilter-nft-ct-fix-missing-expect-put-in-obj-eval.patch deleted file mode 100644 index 901639790..000000000 --- a/1153-netfilter-nft-ct-fix-missing-expect-put-in-obj-eval.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 3bbba78afad15b303372a701c571840395dea7a1 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:24:38 +0200 -Subject: [PATCH] netfilter: nft_ct: fix missing expect put in obj eval - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 19f94b6fee75 - -commit 19f94b6fee75b3ef7fbc06f3745b9a771a8a19a4 -Author: Li Xiasong -Date: Thu May 7 22:04:23 2026 +0800 - - netfilter: nft_ct: fix missing expect put in obj eval - - nft_ct_expect_obj_eval() allocates an expectation and may call - nf_ct_expect_related(), but never drops its local reference. - - Add nf_ct_expect_put(exp) before return to balance allocation. - - Fixes: 857b46027d6f ("netfilter: nft_ct: add ct expectations support") - Cc: stable@vger.kernel.org - Signed-off-by: Li Xiasong - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c -index d0090d0..d877767 100644 ---- a/net/netfilter/nft_ct.c -+++ b/net/netfilter/nft_ct.c -@@ -1378,6 +1378,8 @@ static void nft_ct_expect_obj_eval(struct nft_object *obj, - - if (nf_ct_expect_related(exp, 0) != 0) - regs->verdict.code = NF_DROP; -+ -+ nf_ct_expect_put(exp); - } - - static const struct nla_policy nft_ct_expect_policy[NFTA_CT_EXPECT_MAX + 1] = { diff --git a/1154-netfilter-nf-conntrack-helper-fix-possible-null-deref-during-error-log.patch b/1154-netfilter-nf-conntrack-helper-fix-possible-null-deref-during-error-log.patch deleted file mode 100644 index 48c5526ea..000000000 --- a/1154-netfilter-nf-conntrack-helper-fix-possible-null-deref-during-error-log.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 57807b90c78a36d8729fc8d8a04ce31bd4f3e4ff Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 20 May 2026 11:48:56 +0200 -Subject: [PATCH] netfilter: nf_conntrack_helper: fix possible null deref - during error log - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 1afc25ae7528 - -commit 1afc25ae75288b3ce59e9e5a4b448bd354c9e565 -Author: Florian Westphal -Date: Sat May 9 10:27:06 2026 +0200 - - netfilter: nf_conntrack_helper: fix possible null deref during error log - - Reported by sashiko: there is a small race window. - - If a helper module is unloaded or a userspace-defined helper is - removed, nf_conntrack_helper_unregister() sets ->helper to NULL. - - Handle this safely. This needs a second patch to close related - race during nf_conntrack_helper_unregister(). - - Fixes: b20ab9cc63ca ("netfilter: nf_ct_helper: better logging for dropped packets") - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c -index b594cd2..17e971b 100644 ---- a/net/netfilter/nf_conntrack_helper.c -+++ b/net/netfilter/nf_conntrack_helper.c -@@ -321,8 +321,8 @@ __printf(3, 4) - void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct, - const char *fmt, ...) - { -+ const char *helper_name = "(null)"; - const struct nf_conn_help *help; -- const struct nf_conntrack_helper *helper; - struct va_format vaf; - va_list args; - -@@ -331,14 +331,17 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct, - vaf.fmt = fmt; - vaf.va = &args; - -- /* Called from the helper function, this call never fails */ - help = nfct_help(ct); -+ if (help) { -+ const struct nf_conntrack_helper *helper; - -- /* rcu_read_lock()ed by nf_hook_thresh */ -- helper = rcu_dereference(help->helper); -+ helper = rcu_dereference(help->helper); -+ if (helper) -+ helper_name = helper->name; -+ } - - nf_log_packet(nf_ct_net(ct), nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL, -- "nf_ct_%s: dropping packet: %pV ", helper->name, &vaf); -+ "helper %s dropping packet: %pV ", helper_name, &vaf); - - va_end(args); - } diff --git a/1155-netfilter-ip6t-hbh-reject-oversized-option-lists.patch b/1155-netfilter-ip6t-hbh-reject-oversized-option-lists.patch deleted file mode 100644 index 41341060e..000000000 --- a/1155-netfilter-ip6t-hbh-reject-oversized-option-lists.patch +++ /dev/null @@ -1,56 +0,0 @@ -From c3badd18c01702498ec26b9c13396a7fc2e8fc11 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 20 May 2026 11:48:58 +0200 -Subject: [PATCH] netfilter: ip6t_hbh: reject oversized option lists - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 4322dcde6b41 - -commit 4322dcde6b4173c2d8e8e6118ed290794263bcc8 -Author: Zhengchuan Liang -Date: Wed May 13 15:57:17 2026 +0800 - - netfilter: ip6t_hbh: reject oversized option lists - - struct ip6t_opts stores at most IP6T_OPTS_OPTSNR option descriptors, - but hbh_mt6_check() does not reject larger optsnr values supplied from - userspace. - - Validate optsnr in the rule setup path so only match data that fits the - fixed-size opts array can be installed. This follows the existing xtables - pattern of rejecting invalid user-provided counts in checkentry() and - keeps the packet matching path unchanged. - - `struct ip6t_opts` has a fixed `opts[IP6T_OPTS_OPTSNR]` array, - where `IP6T_OPTS_OPTSNR` is 16, then off-by-one array access is possible: - - [ 137.924693][ T8692] UBSAN: array-index-out-of-bounds in ../net/ipv6/netfilter/ip6t_hbh.c:110:29 - [ 137.926167][ T8692] index 16 is out of range for type '__u16 [16]' - - Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") - Cc: stable@kernel.org - Reported-by: Yuan Tan - Reported-by: Yifan Wu - Reported-by: Juefei Pu - Reported-by: Xin Liu - Signed-off-by: Zhengchuan Liang - Signed-off-by: Ren Wei - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c -index e7a3fb9..450dd53 100644 ---- a/net/ipv6/netfilter/ip6t_hbh.c -+++ b/net/ipv6/netfilter/ip6t_hbh.c -@@ -168,6 +168,10 @@ static int hbh_mt6_check(const struct xt_mtchk_param *par) - pr_debug("unknown flags %X\n", optsinfo->invflags); - return -EINVAL; - } -+ if (optsinfo->optsnr > IP6T_OPTS_OPTSNR) { -+ pr_debug("too many supported opts specified\n"); -+ return -EINVAL; -+ } - - if (optsinfo->flags & IP6T_OPTS_NSTRICT) { - pr_debug("Not strict - not implemented"); diff --git a/1156-netfilter-br-netfilter-reallocate-headroom-if-necessary-in-neigh-hh-bridge.patch b/1156-netfilter-br-netfilter-reallocate-headroom-if-necessary-in-neigh-hh-bridge.patch deleted file mode 100644 index 408226e81..000000000 --- a/1156-netfilter-br-netfilter-reallocate-headroom-if-necessary-in-neigh-hh-bridge.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 5c589ceb09725bf23a6c443837049ee5212c8bb2 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 20 May 2026 11:48:59 +0200 -Subject: [PATCH] netfilter: br_netfilter: Reallocate headroom if necessary in - neigh_hh_bridge() - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit b2870fc21601 - -commit b2870fc21601db9133bc70c48c603b487614fa3b -Author: Lorenzo Bianconi -Date: Thu May 14 16:46:38 2026 +0200 - - netfilter: br_netfilter: Reallocate headroom if necessary in neigh_hh_bridge() - - neigh_hh_bridge() assumes the skb always has sufficient headroom to copy - the aligned L2 header. This assumption can trigger the crash reported - below using the following netfilter setup: - - $modprobe br_netfilter - $sysctl -w net.bridge.bridge-nf-call-iptables=1 - - $root@OpenWrt:~# nft list ruleset - table ip nat { - chain prerouting { - type nat hook prerouting priority dstnat; policy accept; - ip daddr 192.168.83.123 dnat to 192.168.83.120 - } - } - - - iperf3 client (192.168.83.119) --> bridge (192.168.83.118) --> iperf3 server (192.168.83.120) - - the iperf3 client is sending packet for 192.168.83.123 to the bridge device. - - [ 1579.036575] Unable to handle kernel write to read-only memory at virtual address ffffff8004d76ffe - [ 1579.045482] Mem abort info: - [ 1579.048273] ESR = 0x000000009600004f - [ 1579.052024] EC = 0x25: DABT (current EL), IL = 32 bits - [ 1579.057363] SET = 0, FnV = 0 - [ 1579.060417] EA = 0, S1PTW = 0 - [ 1579.063550] FSC = 0x0f: level 3 permission fault - [ 1579.068345] Data abort info: - [ 1579.071224] ISV = 0, ISS = 0x0000004f, ISS2 = 0x00000000 - [ 1579.076720] CM = 0, WnR = 1, TnD = 0, TagAccess = 0 - [ 1579.081770] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 - [ 1579.087092] swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000080dc4000 - [ 1579.093794] [ffffff8004d76ffe] pgd=180000009ffff003, p4d=180000009ffff003, pud=180000009ffff003, pmd=180000009ffe3003, pte=0060000084d76787 - [ 1579.106343] Internal error: Oops: 000000009600004f [#1] SMP - [ 1579.193824] CPU: 0 UID: 0 PID: 235 Comm: napi/qdma_eth-3 Tainted: G O 6.12.57 #0 - [ 1579.202614] Tainted: [O]=OOT_MODULE - [ 1579.206102] Hardware name: Airoha AN7581 Evaluation Board (DT) - [ 1579.211929] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) - [ 1579.218889] pc : br_nf_pre_routing_finish_bridge+0x1ac/0xcc8 [br_netfilter] - [ 1579.225859] lr : br_nf_pre_routing_finish_bridge+0x18c/0xcc8 [br_netfilter] - [ 1579.232822] sp : ffffffc0817cba20 - [ 1579.236128] x29: ffffffc0817cba20 x28: 0000000000000000 x27: ffffff8002b89000 - [ 1579.243273] x26: ffffff8004d7700e x25: 0000000000000008 x24: 0000000000000000 - [ 1579.250416] x23: ffffffc08179d4c0 x22: 0000000000000000 x21: ffffffc08179d4c0 - [ 1579.257561] x20: ffffff8004d9b800 x19: ffffff8015010000 x18: 0000000000000014 - [ 1579.264704] x17: ffffffbf9e930000 x16: ffffffc0817c8000 x15: 0000000000000070 - [ 1579.271848] x14: 0000000000000080 x13: 0000000000000001 x12: 0000000000000000 - [ 1579.278993] x11: ffffffc0798caae0 x10: ffffff8014db6fd8 x9 : 0000000000000000 - [ 1579.286136] x8 : 0000000000000003 x7 : ffffffc08171f628 x6 : 000000001a3b83d3 - [ 1579.293281] x5 : 0000000000000000 x4 : 1beb76f22fee0000 x3 : ffffff8004d7700e - [ 1579.300425] x2 : 0000000000000000 x1 : ffffff8004d9b8bc x0 : ffffff80026ed000 - [ 1579.307570] Call trace: - [ 1579.310018] br_nf_pre_routing_finish_bridge+0x1ac/0xcc8 [br_netfilter] - [ 1579.316632] br_nf_hook_thresh+0xd4/0x14bc [br_netfilter] - [ 1579.322032] br_nf_hook_thresh+0x250/0x14bc [br_netfilter] - [ 1579.327517] br_nf_hook_thresh+0x76c/0x14bc [br_netfilter] - [ 1579.333003] br_handle_frame+0x180/0x480 - [ 1579.336935] __netif_receive_skb_core.constprop.0+0x540/0xf40 - [ 1579.342682] __netif_receive_skb_one_core+0x28/0x50 - [ 1579.347561] process_backlog+0x98/0x1e0 - [ 1579.351398] __napi_poll+0x34/0x1c4 - [ 1579.354887] net_rx_action+0x178/0x330 - [ 1579.358638] handle_softirqs+0x108/0x2d4 - [ 1579.362560] __do_softirq+0x10/0x18 - [ 1579.366051] ____do_softirq+0xc/0x20 - [ 1579.369627] call_on_irq_stack+0x30/0x4c - [ 1579.373550] do_softirq_own_stack+0x18/0x20 - [ 1579.377734] do_softirq+0x4c/0x60 - [ 1579.381050] __local_bh_enable_ip+0x88/0x98 - [ 1579.385234] napi_threaded_poll_loop+0x188/0x21c - [ 1579.389853] napi_threaded_poll+0x70/0x80 - [ 1579.393863] kthread+0xd8/0xdc - [ 1579.396918] ret_from_fork+0x10/0x20 - [ 1579.400499] Code: 88dffc22 3707ffc2 f9406663 f9406684 (f81f0064) - [ 1579.406589] ---[ end trace 0000000000000000 ]--- - [ 1579.411209] Kernel panic - not syncing: Oops: Fatal exception in interrupt - [ 1579.418083] SMP: stopping secondary CPUs - [ 1579.422012] Kernel Offset: disabled - - Fix the issue reallocating the skb headroom if necessary in neigh_hh_bridge routine. - - Fixes: e179e6322ac33 ("netfilter: bridge-netfilter: Fix MAC header handling with IP DNAT") - Reviewed-by: Ido Schimmel - Signed-off-by: Lorenzo Bianconi - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/include/net/neighbour.h b/include/net/neighbour.h -index a44f262..81807ec 100644 ---- a/include/net/neighbour.h -+++ b/include/net/neighbour.h -@@ -475,11 +475,15 @@ static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) - #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) - static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb) - { -- unsigned int seq, hh_alen; -+ unsigned int seq, hh_alen = HH_DATA_ALIGN(ETH_HLEN); -+ int err; -+ -+ err = skb_cow_head(skb, hh_alen); -+ if (err) -+ return err; - - do { - seq = read_seqbegin(&hh->hh_lock); -- hh_alen = HH_DATA_ALIGN(ETH_HLEN); - memcpy(skb->data - hh_alen, hh->hh_data, ETH_ALEN + hh_alen - ETH_HLEN); - } while (read_seqretry(&hh->hh_lock, seq)); - return 0; -diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c -index 1ba0780..1e5ac85 100644 ---- a/net/bridge/br_netfilter_hooks.c -+++ b/net/bridge/br_netfilter_hooks.c -@@ -296,7 +296,11 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_ - goto free_skb; - } - -- neigh_hh_bridge(&neigh->hh, skb); -+ if (neigh_hh_bridge(&neigh->hh, skb)) { -+ neigh_release(neigh); -+ goto free_skb; -+ } -+ - skb->dev = br_indev; - - ret = br_handle_frame_finish(net, sk, skb); diff --git a/1157-netfilter-nf-queue-hold-bridge-skb-dev-while-queued.patch b/1157-netfilter-nf-queue-hold-bridge-skb-dev-while-queued.patch deleted file mode 100644 index fff6410f6..000000000 --- a/1157-netfilter-nf-queue-hold-bridge-skb-dev-while-queued.patch +++ /dev/null @@ -1,97 +0,0 @@ -From a5a3e9f4eb2479abc1e49647644becd5106e74ab Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 20 May 2026 11:49:00 +0200 -Subject: [PATCH] netfilter: nf_queue: hold bridge skb->dev while queued - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit e196115ec330 - -commit e196115ec330a18de415bdb9f5071aa9f08e53ce -Author: Haoze Xie -Date: Fri May 15 11:19:02 2026 +0800 - - netfilter: nf_queue: hold bridge skb->dev while queued - - br_pass_frame_up() rewrites skb->dev from the ingress port to the bridge - master before queueing bridge LOCAL_IN packets. NFQUEUE only holds - references on state.in/out and bridge physdevs, so a queued bridge - packet can retain a freed bridge master in skb->dev until reinjection. - - When the verdict is reinjected later, br_netif_receive_skb() re-enters - the receive path with skb->dev still pointing at the freed bridge master, - triggering a use-after-free. - - Store skb->dev in the queue entry, hold a reference on it for the queue - lifetime, and use the saved device when dropping queued packets during - NETDEV_DOWN handling. - - Fixes: ac2863445686 ("netfilter: bridge: add nf_afinfo to enable queuing to userspace") - Cc: stable@kernel.org - Reported-by: Yuan Tan - Reported-by: Yifan Wu - Reported-by: Juefei Pu - Reported-by: Xin Liu - Signed-off-by: Haoze Xie - Signed-off-by: Ren Wei - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h -index 4aeffdd..b880f18 100644 ---- a/include/net/netfilter/nf_queue.h -+++ b/include/net/netfilter/nf_queue.h -@@ -12,6 +12,7 @@ - struct nf_queue_entry { - struct list_head list; - struct sk_buff *skb; -+ struct net_device *skb_dev; - unsigned int id; - unsigned int hook_index; /* index in hook_entries->hook[] */ - #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) -diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c -index 7f12e56..dd416c8 100644 ---- a/net/netfilter/nf_queue.c -+++ b/net/netfilter/nf_queue.c -@@ -60,6 +60,7 @@ static void nf_queue_entry_release_refs(struct nf_queue_entry *entry) - struct nf_hook_state *state = &entry->state; - - /* Release those devices we held, or Alexey will kill me. */ -+ dev_put(entry->skb_dev); - dev_put(state->in); - dev_put(state->out); - if (state->sk) -@@ -101,6 +102,7 @@ bool nf_queue_entry_get_refs(struct nf_queue_entry *entry) - if (state->sk && !refcount_inc_not_zero(&state->sk->sk_refcnt)) - return false; - -+ dev_hold(entry->skb_dev); - dev_hold(state->in); - dev_hold(state->out); - -@@ -201,11 +203,11 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state, - - *entry = (struct nf_queue_entry) { - .skb = skb, -+ .skb_dev = skb->dev, - .state = *state, - .hook_index = index, - .size = sizeof(*entry) + route_key_size, - }; -- - __nf_queue_entry_init_physdevs(entry); - - if (!nf_queue_entry_get_refs(entry)) { -diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c -index 0bb1656..64496e7 100644 ---- a/net/netfilter/nfnetlink_queue.c -+++ b/net/netfilter/nfnetlink_queue.c -@@ -1132,6 +1132,8 @@ dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex) - if (physinif == ifindex || physoutif == ifindex) - return 1; - #endif -+ if (entry->skb_dev && entry->skb_dev->ifindex == ifindex) -+ return 1; - if (entry->state.in) - if (entry->state.in->ifindex == ifindex) - return 1; diff --git a/1158-netfilter-conntrack-tcp-do-not-force-close-on-invalid-seq-rst-without-direction-.patch b/1158-netfilter-conntrack-tcp-do-not-force-close-on-invalid-seq-rst-without-direction-.patch deleted file mode 100644 index eeb6ecd8b..000000000 --- a/1158-netfilter-conntrack-tcp-do-not-force-close-on-invalid-seq-rst-without-direction-.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 4a13cd8d6754b3c1c69f9c883caa7ee03674a53b Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Tue, 26 May 2026 13:22:20 +0200 -Subject: [PATCH] netfilter: conntrack: tcp: do not force CLOSE on invalid-seq - RST without direction check - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit bed6e04be8e6 - -commit bed6e04be8e6b9133d8b16d5a42d0e0ce674fa9a -Author: Hamza Mahfooz -Date: Mon May 11 10:43:14 2026 -0400 - - netfilter: conntrack: tcp: do not force CLOSE on invalid-seq RST without direction check - - An unintended behavior in the TCP conntrack state machine allows a - connection to be forced into the CLOSE state using an RST packet with an - invalid sequence number. - - Specifically, after a SYN packet is observed, an RST with an invalid SEQ - can transition the conntrack entry to TCP_CONNTRACK_CLOSE, regardless of - whether the RST corresponds to the expected reply direction. The relevant - code path assumes the RST is a response to an outgoing SYN, but does not - validate packet direction or ensure that a matching SYN was actually sent - in the opposite direction. - - As a result, a crafted packet sequence consisting of a SYN followed by an - invalid-sequence RST can prematurely terminate an active NAT entry. This - makes connection teardown easier than intended. - - So, tighten the state transition logic to ensure that RST-triggered - CLOSE transitions only occur when the RST is a valid response to a - previously observed SYN in the correct direction. - - Cc: stable@vger.kernel.org - Fixes: 9fb9cbb1082d ("[NETFILTER]: Add nf_conntrack subsystem.") - Signed-off-by: Hamza Mahfooz - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c -index b67426c..e99ab1e 100644 ---- a/net/netfilter/nf_conntrack_proto_tcp.c -+++ b/net/netfilter/nf_conntrack_proto_tcp.c -@@ -1221,7 +1221,8 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct, - new_state = old_state; - } - if (((test_bit(IPS_SEEN_REPLY_BIT, &ct->status) -- && ct->proto.tcp.last_index == TCP_SYN_SET) -+ && ct->proto.tcp.last_index == TCP_SYN_SET -+ && ct->proto.tcp.last_dir != dir) - || (!test_bit(IPS_ASSURED_BIT, &ct->status) - && ct->proto.tcp.last_index == TCP_ACK_SET)) - && ntohl(th->ack_seq) == ct->proto.tcp.last_end) { diff --git a/1159-netfilter-synproxy-refresh-tcphdr-after-skb-ensure-writable.patch b/1159-netfilter-synproxy-refresh-tcphdr-after-skb-ensure-writable.patch deleted file mode 100644 index 1839f07da..000000000 --- a/1159-netfilter-synproxy-refresh-tcphdr-after-skb-ensure-writable.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 35ea4ea680d6794f01d54eec2b1e507a45f422cf Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Tue, 26 May 2026 13:22:20 +0200 -Subject: [PATCH] netfilter: synproxy: refresh tcphdr after skb_ensure_writable - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 92170e6afe92 - -commit 92170e6afe927ab2792a3f71902845789c8e31b1 -Author: Chris Mason -Date: Tue May 19 12:36:14 2026 -0700 - - netfilter: synproxy: refresh tcphdr after skb_ensure_writable - - synproxy_tstamp_adjust() rewrites the TCP timestamp option in place - and then patches the TCP checksum via inet_proto_csum_replace4() on - the caller-supplied tcphdr pointer. Both ipv4_synproxy_hook() and - ipv6_synproxy_hook() obtain that pointer with skb_header_pointer() - before calling in, so it may either alias skb->head directly or - point at the caller's on-stack _tcph buffer. - - Between obtaining the pointer and using it, the function calls - skb_ensure_writable(skb, optend), which on a cloned or non-linear - skb invokes pskb_expand_head() and frees the old skb->head. After - that point the cached th is stale: - - caller (ipv[46]_synproxy_hook) - th = skb_header_pointer(skb, ..., &_tcph) - synproxy_tstamp_adjust(skb, protoff, th, ...) - skb_ensure_writable(skb, optend) - pskb_expand_head() /* kfree(old skb->head) */ - ... - inet_proto_csum_replace4(&th->check, ...) - /* writes into freed head, or - into the caller's stack copy - leaving the on-wire checksum - stale */ - - The option bytes are written through skb->data and are fine; only - the checksum update goes through th and so lands in the wrong - place. The result is either a write into freed slab memory or a - packet leaving with a checksum that does not match its payload. - - Fix by re-deriving th from skb->data + protoff immediately after - skb_ensure_writable() succeeds, so the subsequent checksum update - targets the linear, writable header. - - Fixes: 48b1de4c110a ("netfilter: add SYNPROXY core/target") - Assisted-by: kres (claude-opus-4-7) - Signed-off-by: Chris Mason - Reviewed-by: Fernando Fernandez Mancera - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c -index 3fa3f5d..6a851ac 100644 ---- a/net/netfilter/nf_synproxy_core.c -+++ b/net/netfilter/nf_synproxy_core.c -@@ -199,6 +199,8 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff, - if (skb_ensure_writable(skb, optend)) - return 0; - -+ th = (struct tcphdr *)(skb->data + protoff); -+ - while (optoff < optend) { - unsigned char *op = skb->data + optoff; - diff --git a/1160-netfilter-nf-conntrack-gre-fix-gre-keymap-list-corruption.patch b/1160-netfilter-nf-conntrack-gre-fix-gre-keymap-list-corruption.patch deleted file mode 100644 index e5c7d4079..000000000 --- a/1160-netfilter-nf-conntrack-gre-fix-gre-keymap-list-corruption.patch +++ /dev/null @@ -1,246 +0,0 @@ -From 8fa68cde22f8c43d3f1bc0d4c7bf7c3fd8492c2e Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Tue, 26 May 2026 13:22:21 +0200 -Subject: [PATCH] netfilter: nf_conntrack_gre: fix gre keymap list corruption - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 47980b6dbf83 - -Conflict is due to missing kmalloc_obj() conversion in cs-10. - -commit 47980b6dbf83961eec1c1363ea986e9c06ff8054 -Author: Florian Westphal -Date: Thu May 14 14:21:57 2026 +0200 - - netfilter: nf_conntrack_gre: fix gre keymap list corruption - - Quoting reporter: - A race between GRE keymap insertion and destruction can corrupt the - kernel list or use a freed object. `nf_ct_gre_keymap_add()` publishes a - new keymap pointer before the embedded `list_head` is linked, while - `nf_ct_gre_keymap_destroy()` can concurrently delete and free that - same object. An unprivileged user can reach this through the PPTP - conntrack helper by racing PPTP control messages or helper teardown, - leading to KASAN-detectable list corruption/UAF in kernel context. - - ## Root Cause Analysis - `exp_gre()` installs GRE expectations for a PPTP control flow and then - adds two GRE keymap entries [..] - - The add path publishes `ct_pptp_info->keymap[dir]` before linking the - embedded list node [..] - Concurrent teardown deletes that partially initialized object. - - Make add/destroy symmetric: install both, destroy both while under lock. - - Furthermore, we should refuse to publish a new mapping in case ct is going - away, else we may leak the allocation. - - The "retrans" detection is strange: existing mapping is checked for key - equality with the new mapping, then for "is on the list" via list walk. - - But I can't see how an existing keymap entry can be NOT on list. - - Change this to only check if we're asked to map same tuple again -- if so, - skip re-install, else signal failure. - - Last, add a bug trap for the keymap list; it has to be empty when namespace - is going away. - - Reported-by: Leo Lin - Signed-off-by: Florian Westphal - -Assisted-by: Patchpal AI -Signed-off-by: Florian Westphal - -diff --git a/include/linux/netfilter/nf_conntrack_proto_gre.h b/include/linux/netfilter/nf_conntrack_proto_gre.h -index 34ce5d2..4014f78 100644 ---- a/include/linux/netfilter/nf_conntrack_proto_gre.h -+++ b/include/linux/netfilter/nf_conntrack_proto_gre.h -@@ -21,9 +21,10 @@ struct nf_ct_gre_keymap { - struct rcu_head rcu; - }; - --/* add new tuple->key_reply pair to keymap */ --int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, -- struct nf_conntrack_tuple *t); -+/* add tuple->key_reply pairs to keymap */ -+bool nf_ct_gre_keymap_add(struct nf_conn *ct, -+ const struct nf_conntrack_tuple *orig, -+ const struct nf_conntrack_tuple *repl); - - /* delete keymap entries */ - void nf_ct_gre_keymap_destroy(struct nf_conn *ct); -diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c -index 02a73b2..04f7a13 100644 ---- a/net/netfilter/nf_conntrack_core.c -+++ b/net/netfilter/nf_conntrack_core.c -@@ -576,6 +576,13 @@ static void destroy_gre_conntrack(struct nf_conn *ct) - #endif - } - -+static void warn_on_keymap_list_leak(const struct net *net) -+{ -+#ifdef CONFIG_NF_CT_PROTO_GRE -+ WARN_ON_ONCE(!list_empty(&net->ct.nf_ct_proto.gre.keymap_list)); -+#endif -+} -+ - void nf_ct_destroy(struct nf_conntrack *nfct) - { - struct nf_conn *ct = (struct nf_conn *)nfct; -@@ -2525,6 +2532,7 @@ void nf_conntrack_cleanup_net_list(struct list_head *net_exit_list) - } - - list_for_each_entry(net, net_exit_list, exit_list) { -+ warn_on_keymap_list_leak(net); - nf_conntrack_ecache_pernet_fini(net); - nf_conntrack_expect_pernet_fini(net); - free_percpu(net->ct.stat); -diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c -index 4c67963..dc23e41 100644 ---- a/net/netfilter/nf_conntrack_pptp.c -+++ b/net/netfilter/nf_conntrack_pptp.c -@@ -225,13 +225,9 @@ static int exp_gre(struct nf_conn *ct, __be16 callid, __be16 peer_callid) - if (nf_ct_expect_related(exp_reply, 0) != 0) - goto out_unexpect_orig; - -- /* Add GRE keymap entries */ -- if (nf_ct_gre_keymap_add(ct, IP_CT_DIR_ORIGINAL, &exp_orig->tuple) != 0) -+ if (!nf_ct_gre_keymap_add(ct, &exp_orig->tuple, -+ &exp_reply->tuple)) - goto out_unexpect_both; -- if (nf_ct_gre_keymap_add(ct, IP_CT_DIR_REPLY, &exp_reply->tuple) != 0) { -- nf_ct_gre_keymap_destroy(ct); -- goto out_unexpect_both; -- } - ret = 0; - - out_put_both: -diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c -index af369e6..d637080 100644 ---- a/net/netfilter/nf_conntrack_proto_gre.c -+++ b/net/netfilter/nf_conntrack_proto_gre.c -@@ -85,41 +85,97 @@ static __be16 gre_keymap_lookup(struct net *net, struct nf_conntrack_tuple *t) - return key; - } - --/* add a single keymap entry, associate with specified master ct */ --int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, -- struct nf_conntrack_tuple *t) -+enum nf_ct_gre_km_act { -+ NF_CT_GRE_KM_NEW, -+ NF_CT_GRE_KM_BAD, -+ NF_CT_GRE_KM_DUP -+}; -+ -+static enum nf_ct_gre_km_act -+nf_ct_gre_km_acceptable(const struct nf_ct_pptp_master *ct_pptp_info, -+ const struct nf_conntrack_tuple *orig, -+ const struct nf_conntrack_tuple *repl) -+{ -+ struct nf_ct_gre_keymap *km_orig, *km_repl; -+ -+ lockdep_assert_held(&keymap_lock); -+ -+ km_orig = ct_pptp_info->keymap[IP_CT_DIR_ORIGINAL]; -+ km_repl = ct_pptp_info->keymap[IP_CT_DIR_REPLY]; -+ -+ if (km_orig && km_repl) { -+ if (!gre_key_cmpfn(km_orig, orig)) -+ return NF_CT_GRE_KM_BAD; -+ -+ if (!gre_key_cmpfn(km_repl, repl)) -+ return NF_CT_GRE_KM_BAD; -+ -+ return NF_CT_GRE_KM_DUP; -+ } -+ -+ DEBUG_NET_WARN_ON_ONCE(km_orig); -+ DEBUG_NET_WARN_ON_ONCE(km_repl); -+ return NF_CT_GRE_KM_NEW; -+} -+ -+/* add keymap entries, associate with specified master ct */ -+bool nf_ct_gre_keymap_add(struct nf_conn *ct, -+ const struct nf_conntrack_tuple *orig, -+ const struct nf_conntrack_tuple *repl) - { - struct net *net = nf_ct_net(ct); - struct nf_gre_net *net_gre = gre_pernet(net); - struct nf_ct_pptp_master *ct_pptp_info = nfct_help_data(ct); -- struct nf_ct_gre_keymap **kmp, *km; -- -- kmp = &ct_pptp_info->keymap[dir]; -- if (*kmp) { -- /* check whether it's a retransmission */ -- list_for_each_entry_rcu(km, &net_gre->keymap_list, list) { -- if (gre_key_cmpfn(km, t) && km == *kmp) -- return 0; -- } -- pr_debug("trying to override keymap_%s for ct %p\n", -- dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct); -- return -EEXIST; -- } -+ struct nf_ct_gre_keymap *km_orig, *km_repl; -+ bool ret = false; - -- km = kmalloc(sizeof(*km), GFP_ATOMIC); -- if (!km) -- return -ENOMEM; -- memcpy(&km->tuple, t, sizeof(*t)); -- *kmp = km; -+ km_orig = kmalloc(sizeof(*km_orig), GFP_ATOMIC); -+ if (!km_orig) -+ return false; -+ km_repl = kmalloc(sizeof(*km_repl), GFP_ATOMIC); -+ if (!km_repl) -+ goto km_free; - -- pr_debug("adding new entry %p: ", km); -- nf_ct_dump_tuple(&km->tuple); -+ memcpy(&km_orig->tuple, orig, sizeof(*orig)); -+ memcpy(&km_repl->tuple, repl, sizeof(*repl)); - - spin_lock_bh(&keymap_lock); -- list_add_tail(&km->list, &net_gre->keymap_list); -+ if (nf_ct_is_dying(ct)) -+ goto unlock_free; -+ -+ switch (nf_ct_gre_km_acceptable(ct_pptp_info, orig, repl)) { -+ case NF_CT_GRE_KM_NEW: -+ break; -+ case NF_CT_GRE_KM_DUP: -+ ret = true; -+ goto unlock_free; -+ case NF_CT_GRE_KM_BAD: -+ pr_debug("trying to override keymap for ct %p\n", ct); -+ goto unlock_free; -+ } -+ -+ if (ct_pptp_info->keymap[IP_CT_DIR_ORIGINAL] || -+ ct_pptp_info->keymap[IP_CT_DIR_REPLY]) -+ goto unlock_free; -+ -+ pr_debug("adding new entries %p,%p: ", km_orig, km_repl); -+ nf_ct_dump_tuple(&km_orig->tuple); -+ nf_ct_dump_tuple(&km_repl->tuple); -+ -+ list_add_tail_rcu(&km_orig->list, &net_gre->keymap_list); -+ list_add_tail_rcu(&km_repl->list, &net_gre->keymap_list); -+ ct_pptp_info->keymap[IP_CT_DIR_ORIGINAL] = km_orig; -+ ct_pptp_info->keymap[IP_CT_DIR_REPLY] = km_repl; - spin_unlock_bh(&keymap_lock); - -- return 0; -+ return true; -+ -+unlock_free: -+ spin_unlock_bh(&keymap_lock); -+km_free: -+ kfree(km_orig); -+ kfree(km_repl); -+ return ret; - } - EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_add); - diff --git a/1161-netfilter-disable-payload-mangling-in-userns.patch b/1161-netfilter-disable-payload-mangling-in-userns.patch deleted file mode 100644 index 4cda0c63b..000000000 --- a/1161-netfilter-disable-payload-mangling-in-userns.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 968cc2c96390f06e56ed6a43f935bfebdefed28f Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Sat, 16 May 2026 23:23:21 +0800 -Subject: [PATCH] netfilter: disable payload mangling in userns - -Several parts of network stack rely on iph->ihl validation -done by network stack before PRE_ROUTING. - -Disable this feature for user namespaces for now. - -tcp option handling is likely safe even for LOCAL_IN, so this -this leaves tcp option mangling via nft_exthdr.c as-is. - -I don't think these are the only means to alter packets, but these -appear to be relatively prominent. - -This could be relaxed later. Example: - - allow userns for ingress hook. - - allow userns if base is transport header. - - Also, we should revalidate or restrict generally: - - Don't allow linklayer writes to spill into network header - - restrict ipv4 and ipv6 to 'known safe' writes, e.g. - saddr/daddr/check/tos - -Reported-by: Qi Tang -Reported-by: Tong Liu -Tested-by: Qi Tang -Link: https://lore.kernel.org/netfilter-devel/20260515100411.3141-1-fw@strlen.de/ -Signed-off-by: Florian Westphal - -diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c -index 64496e7..8d4fa10 100644 ---- a/net/netfilter/nfnetlink_queue.c -+++ b/net/netfilter/nfnetlink_queue.c -@@ -1061,6 +1061,9 @@ nfqnl_mangle(void *data, unsigned int data_len, struct nf_queue_entry *e, int di - { - struct sk_buff *nskb; - -+ if (e->state.net->user_ns != &init_user_ns) -+ return -EPERM; -+ - if (diff < 0) { - unsigned int min_len = skb_transport_offset(e->skb); - -@@ -1458,8 +1461,7 @@ static int nfqnl_recv_verdict(struct sk_buff *skb, const struct nfnl_info *info, - if (nfqnl_mangle(nla_data(nfqa[NFQA_PAYLOAD]), - payload_len, entry, diff) < 0) - verdict = NF_DROP; -- -- if (ct && diff) -+ else if (ct && diff) - nfnl_ct->seq_adjust(entry->skb, ct, ctinfo, diff); - } - -diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c -index 7dfc534..0dba42e 100644 ---- a/net/netfilter/nft_payload.c -+++ b/net/netfilter/nft_payload.c -@@ -944,6 +944,9 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, - u32 csum_offset, csum_type = NFT_PAYLOAD_CSUM_NONE; - int err; - -+ if (ctx->net->user_ns != &init_user_ns) -+ return -EPERM; -+ - priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE])); - priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET])); - priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN])); diff --git a/1162-netfilter-synproxy-add-mutex-to-guard-hook-reference-counting.patch b/1162-netfilter-synproxy-add-mutex-to-guard-hook-reference-counting.patch deleted file mode 100644 index d220c9401..000000000 --- a/1162-netfilter-synproxy-add-mutex-to-guard-hook-reference-counting.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 640441348258220e78daed40528b85b8afcedab6 Mon Sep 17 00:00:00 2001 -From: Fernando Fernandez Mancera -Date: Tue, 26 May 2026 23:58:31 +0200 -Subject: [PATCH] netfilter: synproxy: add mutex to guard hook reference - counting - -[ Upstream commit 2fcba19caaeb2a33017459d3430f057967bb91b6 ] - -As the synproxy infrastructure register netfilter hooks on-demand when a -user adds the first iptables target or nftables expression, if done -concurrently they can race each other. - -Introduce a mutex to serialize the refcount control blocks access from -both frontends. While a per namespace mutex might be more efficient, it -is not needed for target/expression like SYNPROXY. - -Fixes: ad49d86e07a4 ("netfilter: nf_tables: Add synproxy support") -Signed-off-by: Fernando Fernandez Mancera -Signed-off-by: Florian Westphal -Signed-off-by: Pablo Neira Ayuso -Signed-off-by: Sasha Levin - -diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c -index 6a851ac..a277b2b 100644 ---- a/net/netfilter/nf_synproxy_core.c -+++ b/net/netfilter/nf_synproxy_core.c -@@ -21,6 +21,8 @@ - #include - #include - -+static DEFINE_MUTEX(synproxy_mutex); -+ - unsigned int synproxy_net_id; - EXPORT_SYMBOL_GPL(synproxy_net_id); - -@@ -768,26 +770,31 @@ static const struct nf_hook_ops ipv4_synproxy_ops[] = { - - int nf_synproxy_ipv4_init(struct synproxy_net *snet, struct net *net) - { -- int err; -+ int err = 0; - -+ mutex_lock(&synproxy_mutex); - if (snet->hook_ref4 == 0) { - err = nf_register_net_hooks(net, ipv4_synproxy_ops, - ARRAY_SIZE(ipv4_synproxy_ops)); - if (err) -- return err; -+ goto out; - } - - snet->hook_ref4++; -- return 0; -+out: -+ mutex_unlock(&synproxy_mutex); -+ return err; - } - EXPORT_SYMBOL_GPL(nf_synproxy_ipv4_init); - - void nf_synproxy_ipv4_fini(struct synproxy_net *snet, struct net *net) - { -+ mutex_lock(&synproxy_mutex); - snet->hook_ref4--; - if (snet->hook_ref4 == 0) - nf_unregister_net_hooks(net, ipv4_synproxy_ops, - ARRAY_SIZE(ipv4_synproxy_ops)); -+ mutex_unlock(&synproxy_mutex); - } - EXPORT_SYMBOL_GPL(nf_synproxy_ipv4_fini); - -@@ -1192,27 +1199,32 @@ static const struct nf_hook_ops ipv6_synproxy_ops[] = { - int - nf_synproxy_ipv6_init(struct synproxy_net *snet, struct net *net) - { -- int err; -+ int err = 0; - -+ mutex_lock(&synproxy_mutex); - if (snet->hook_ref6 == 0) { - err = nf_register_net_hooks(net, ipv6_synproxy_ops, - ARRAY_SIZE(ipv6_synproxy_ops)); - if (err) -- return err; -+ goto out; - } - - snet->hook_ref6++; -- return 0; -+out: -+ mutex_unlock(&synproxy_mutex); -+ return err; - } - EXPORT_SYMBOL_GPL(nf_synproxy_ipv6_init); - - void - nf_synproxy_ipv6_fini(struct synproxy_net *snet, struct net *net) - { -+ mutex_lock(&synproxy_mutex); - snet->hook_ref6--; - if (snet->hook_ref6 == 0) - nf_unregister_net_hooks(net, ipv6_synproxy_ops, - ARRAY_SIZE(ipv6_synproxy_ops)); -+ mutex_unlock(&synproxy_mutex); - } - EXPORT_SYMBOL_GPL(nf_synproxy_ipv6_fini); - #endif /* CONFIG_IPV6 */ diff --git a/1163-netfilter-conntrack-irc-fix-possible-out-of-bounds-read.patch b/1163-netfilter-conntrack-irc-fix-possible-out-of-bounds-read.patch deleted file mode 100644 index 079cba287..000000000 --- a/1163-netfilter-conntrack-irc-fix-possible-out-of-bounds-read.patch +++ /dev/null @@ -1,42 +0,0 @@ -From ddddd8271359961e403d11c90c9ba9fc38914f7e Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 27 May 2026 12:20:19 +0200 -Subject: [PATCH] netfilter: conntrack_irc: fix possible out-of-bounds read - -[ Upstream commit 66eba0ffce3b7e11449946b4cbbef8ea36112f56 ] - -When parsing fails after we've matched the command string we -should bail out instead of trying to match a different command. - -This helper should be deprecated, given prevalence of TLS I doubt it has -any relevance in 2026. - -Fixes: 869f37d8e48f ("[NETFILTER]: nf_conntrack/nf_nat: add IRC helper port") -Closes: https://sashiko.dev/#/patchset/20260525182924.28456-1-fw%40strlen.de -Signed-off-by: Florian Westphal -Reviewed-by: Fernando Fernandez Mancera -Signed-off-by: Pablo Neira Ayuso -Signed-off-by: Sasha Levin - -diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c -index 5703846..0f50ea9 100644 ---- a/net/netfilter/nf_conntrack_irc.c -+++ b/net/netfilter/nf_conntrack_irc.c -@@ -208,7 +208,7 @@ static int help(struct sk_buff *skb, unsigned int protoff, - if (parse_dcc(data, data_limit, &dcc_ip, - &dcc_port, &addr_beg_p, &addr_end_p)) { - pr_debug("unable to parse dcc command\n"); -- continue; -+ goto out; - } - - pr_debug("DCC bound ip/port: %pI4:%u\n", -@@ -222,7 +222,7 @@ static int help(struct sk_buff *skb, unsigned int protoff, - net_warn_ratelimited("Forged DCC command from %pI4: %pI4:%u\n", - &tuple->src.u3.ip, - &dcc_ip, dcc_port); -- continue; -+ goto out; - } - - exp = nf_ct_expect_alloc(ct); diff --git a/1164-netfilter-nft-tunnel-fix-use-after-free-on-object-destroy.patch b/1164-netfilter-nft-tunnel-fix-use-after-free-on-object-destroy.patch deleted file mode 100644 index ef6b14728..000000000 --- a/1164-netfilter-nft-tunnel-fix-use-after-free-on-object-destroy.patch +++ /dev/null @@ -1,40 +0,0 @@ -From fda6573a46ad24f35348e024905ee5bdf729797e Mon Sep 17 00:00:00 2001 -From: Tristan Madani -Date: Wed, 27 May 2026 13:57:50 +0000 -Subject: [PATCH] netfilter: nft_tunnel: fix use-after-free on object destroy - -commit c32b26aaa2f9216520a38b3f4bfeec846eb3eb8a upstream. - -nft_tunnel_obj_destroy() calls metadata_dst_free() which directly -kfree()s the metadata_dst, ignoring the dst_entry refcount. Packets -that took a reference via dst_hold() in nft_tunnel_obj_eval() and -are still queued (e.g. in a netem qdisc) are left with a dangling -pointer. When these packets are eventually dequeued, dst_release() -operates on freed memory. - -Replace metadata_dst_free() with dst_release() so the metadata_dst -is freed only after all references are dropped. The dst subsystem -already handles metadata_dst cleanup in dst_destroy() when -DST_METADATA is set. - -Fixes: af308b94a2a4 ("netfilter: nf_tables: add tunnel support") -Cc: stable@vger.kernel.org -Signed-off-by: Tristan Madani -Reviewed-by: Fernando Fernandez Mancera -Signed-off-by: Florian Westphal -Signed-off-by: Pablo Neira Ayuso -Signed-off-by: Greg Kroah-Hartman - -diff --git a/net/netfilter/nft_tunnel.c b/net/netfilter/nft_tunnel.c -index e18d322..714b6a5 100644 ---- a/net/netfilter/nft_tunnel.c -+++ b/net/netfilter/nft_tunnel.c -@@ -705,7 +705,7 @@ static void nft_tunnel_obj_destroy(const struct nft_ctx *ctx, - { - struct nft_tunnel_obj *priv = nft_obj_data(obj); - -- metadata_dst_free(priv->md); -+ dst_release(&priv->md->dst); - } - - static struct nft_object_type nft_tunnel_obj_type; diff --git a/1165-netfilter-nft-ct-bail-out-on-template-ct-in-get-eval.patch b/1165-netfilter-nft-ct-bail-out-on-template-ct-in-get-eval.patch deleted file mode 100644 index 15393ccf6..000000000 --- a/1165-netfilter-nft-ct-bail-out-on-template-ct-in-get-eval.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 8470f676eadeab99132708acb1a85915664d6115 Mon Sep 17 00:00:00 2001 -From: Jiayuan Chen -Date: Thu, 28 May 2026 19:09:19 +0800 -Subject: [PATCH] netfilter: nft_ct: bail out on template ct in get eval - -[ Upstream commit 3027ecbdb5fdf9200251c21d4818e4c447ef78e1 ] - -I noticed this issue while looking at a historic syzbot report [1]. - -A rule like the one below is enough to trigger the bug: - - table ip t { - chain pre { - type filter hook prerouting priority raw; - ct zone set 1 - ct original saddr 1.2.3.4 accept - } - } - -The first expression attaches a per-cpu template ct via -nft_ct_set_zone_eval() (nf_ct_tmpl_alloc -> kzalloc, tuple is all -zero, nf_ct_l3num(ct) == 0). The next expression then calls -nft_ct_get_eval() on the same skb, treats the template as a real ct -and hits the 16-byte memcpy path. With dreg at NFT_REG32_15 this -overflows past struct nft_regs on the kernel stack; with smaller -dreg values it silently clobbers adjacent registers. - -Reject template ct at the eval entry and in nft_ct_get_fast_eval(), -mirroring the check nft_ct_set_eval() already has. Additionally, -bound the address copy in NFT_CT_SRC / NFT_CT_DST by priv->len -instead of by nf_ct_l3num(ct): nf_ct_get_tuple() zeroes the tuple -before pkt_to_tuple() fills in only the protocol-relevant leading -bytes, so the trailing bytes of tuple->{src,dst}.u3.all are -well-defined zero. priv->len is validated at rule load, so the -copy size is now bounded by the destination register rather than -by an untrusted field on the conntrack. - -[1]: https://syzkaller.appspot.com/bug?id=389cf09cb72926114fce90dc85a2c3231dcb647c - -Fixes: 45d9bcda21f4 ("netfilter: nf_tables: validate len in nft_validate_data_load()") -Suggested-by: Florian Westphal -Signed-off-by: Jiayuan Chen -Signed-off-by: Florian Westphal -Signed-off-by: Pablo Neira Ayuso -Signed-off-by: Sasha Levin - -diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c -index d877767..d411971 100644 ---- a/net/netfilter/nft_ct.c -+++ b/net/netfilter/nft_ct.c -@@ -77,7 +77,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr, - break; - } - -- if (ct == NULL) -+ if (!ct || nf_ct_is_template(ct)) - goto err; - - switch (priv->key) { -@@ -179,12 +179,10 @@ static void nft_ct_get_eval(const struct nft_expr *expr, - tuple = &ct->tuplehash[priv->dir].tuple; - switch (priv->key) { - case NFT_CT_SRC: -- memcpy(dest, tuple->src.u3.all, -- nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16); -+ memcpy(dest, tuple->src.u3.all, priv->len); - return; - case NFT_CT_DST: -- memcpy(dest, tuple->dst.u3.all, -- nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16); -+ memcpy(dest, tuple->dst.u3.all, priv->len); - return; - case NFT_CT_PROTO_SRC: - nft_reg_store16(dest, (__force u16)tuple->src.u.all); -diff --git a/net/netfilter/nft_ct_fast.c b/net/netfilter/nft_ct_fast.c -index e684c8a..ecf7b3a 100644 ---- a/net/netfilter/nft_ct_fast.c -+++ b/net/netfilter/nft_ct_fast.c -@@ -30,7 +30,7 @@ void nft_ct_get_fast_eval(const struct nft_expr *expr, - break; - } - -- if (!ct) { -+ if (!ct || nf_ct_is_template(ct)) { - regs->verdict.code = NFT_BREAK; - return; - } diff --git a/1166-netfilter-revalidate-bridge-ports.patch b/1166-netfilter-revalidate-bridge-ports.patch deleted file mode 100644 index e78a8917e..000000000 --- a/1166-netfilter-revalidate-bridge-ports.patch +++ /dev/null @@ -1,228 +0,0 @@ -From 43330a1e8aace6b5a8de9aba127e9e394ab49b0f Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Tue, 2 Jun 2026 17:04:25 +0200 -Subject: [PATCH] netfilter: revalidate bridge ports - -[ Upstream commit ccb9fd4b87538ccf19ccff78ee26700526d94867 ] - -ebt_redirect_tg() dereferences br_port_get_rcu() return without a -NULL check, causing a kernel panic when the bridge port has been -removed between the original hook invocation and an NFQUEUE -reinject. - -A mere NULL check isn't sufficient, however. As sashiko review -points out userspace can not only remove the port from the bridge, -it could also place the device in a different virtual device, e.g. -macvlan. - -If this happens, we must drop the packet, there is no way for us to -reinject it into the bridge path. - -Switch to _upper API, we don't need the bridge port structure. -Also, this fix keeps another bug intact: - -Both nfnetlink_log and nfnetlink_queue use CONFIG_BRIDGE_NETFILTER -too aggressive, which prevents certain logging features when queueing -in bridge family: NETFILTER_FAMILY_BRIDGE can be enabled while the old -CONFIG_BRIDGE_NETFILTER cruft is off. - -Fixes tag is a common ancestor, this was always broken. - -Fixes: f350a0a87374 ("bridge: use rx_handler_data pointer to store net_bridge_port pointer") -Reported-by: Ji'an Zhou -Assisted-by: Claude:claude-sonnet-4-6 -Signed-off-by: Florian Westphal -Signed-off-by: Pablo Neira Ayuso -Signed-off-by: Sasha Levin - -diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c -index 3fda71a..73f185c 100644 ---- a/net/bridge/netfilter/ebt_dnat.c -+++ b/net/bridge/netfilter/ebt_dnat.c -@@ -39,7 +39,9 @@ ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par) - dev = xt_in(par); - break; - case NF_BR_PRE_ROUTING: -- dev = br_port_get_rcu(xt_in(par))->br->dev; -+ dev = netdev_master_upper_dev_get_rcu(xt_in(par)); -+ if (!dev) /* bridge port removed? */ -+ return EBT_DROP; - break; - default: - dev = NULL; -diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c -index 3077905..83486cd 100644 ---- a/net/bridge/netfilter/ebt_redirect.c -+++ b/net/bridge/netfilter/ebt_redirect.c -@@ -24,12 +24,18 @@ ebt_redirect_tg(struct sk_buff *skb, const struct xt_action_param *par) - if (skb_ensure_writable(skb, 0)) - return EBT_DROP; - -- if (xt_hooknum(par) != NF_BR_BROUTING) -- /* rcu_read_lock()ed by nf_hook_thresh */ -- ether_addr_copy(eth_hdr(skb)->h_dest, -- br_port_get_rcu(xt_in(par))->br->dev->dev_addr); -- else -+ if (xt_hooknum(par) != NF_BR_BROUTING) { -+ const struct net_device *dev; -+ -+ dev = netdev_master_upper_dev_get_rcu(xt_in(par)); -+ if (!dev) -+ return EBT_DROP; -+ -+ ether_addr_copy(eth_hdr(skb)->h_dest, dev->dev_addr); -+ } else { - ether_addr_copy(eth_hdr(skb)->h_dest, xt_in(par)->dev_addr); -+ } -+ - skb->pkt_type = PACKET_HOST; - return info->target; - } -diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c -index b1f3eda..25a30bf 100644 ---- a/net/netfilter/nfnetlink_log.c -+++ b/net/netfilter/nfnetlink_log.c -@@ -450,6 +450,23 @@ static int nfulnl_put_bridge(struct nfulnl_instance *inst, const struct sk_buff - return -1; - } - -+#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) -+static int nflog_put_master_ifindex(struct sk_buff *nlskb, int attr, -+ const struct net_device *dev) -+{ -+ const struct net_device *upper; -+ -+ if (dev && !netif_is_bridge_port(dev)) -+ return 0; -+ -+ upper = netdev_master_upper_dev_get_rcu((struct net_device *)dev); -+ if (upper && nla_put_be32(nlskb, attr, htonl(upper->ifindex))) -+ return -EMSGSIZE; -+ -+ return 0; -+} -+#endif -+ - /* This is an inline function, we don't really care about a long - * list of arguments */ - static inline int -@@ -504,8 +521,7 @@ __build_packet_message(struct nfnl_log_net *log, - /* rcu_read_lock()ed by nf_hook_thresh or - * nf_log_packet. - */ -- nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV, -- htonl(br_port_get_rcu(indev)->br->dev->ifindex))) -+ nflog_put_master_ifindex(inst->skb, NFULA_IFINDEX_INDEV, indev)) - goto nla_put_failure; - } else { - int physinif; -@@ -541,8 +557,7 @@ __build_packet_message(struct nfnl_log_net *log, - /* rcu_read_lock()ed by nf_hook_thresh or - * nf_log_packet. - */ -- nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV, -- htonl(br_port_get_rcu(outdev)->br->dev->ifindex))) -+ nflog_put_master_ifindex(inst->skb, NFULA_IFINDEX_OUTDEV, outdev)) - goto nla_put_failure; - } else { - struct net_device *physoutdev; -diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c -index 8d4fa10..87ac5c8 100644 ---- a/net/netfilter/nfnetlink_queue.c -+++ b/net/netfilter/nfnetlink_queue.c -@@ -369,10 +369,47 @@ static void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) - nf_queue_entry_free(entry); - } - -+static bool nf_bridge_port_valid(const struct net_device *dev) -+{ -+ if (!dev) -+ return true; -+ -+ return netif_is_bridge_port(dev); -+} -+ -+/* queued skbs leave rcu protection. We bump device refcount so that -+ * the device cannot go away. However, while packet was out the port -+ * could have been removed from the bridge. -+ * -+ * Ensure in+outdev are still part of a bridge at reinject time. -+ * -+ * The device rx_handler_data could even be pointing at data that is -+ * not a net_bridge_port structure. -+ */ -+static bool nf_bridge_ports_valid(const struct nf_queue_entry *entry) -+{ -+#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) -+ if (!nf_bridge_port_valid(entry->physin) || -+ !nf_bridge_port_valid(entry->physout)) -+ return false; -+#endif -+ if (entry->state.pf != PF_BRIDGE) -+ return true; -+ -+ if (!nf_bridge_port_valid(entry->state.in) || -+ !nf_bridge_port_valid(entry->state.out)) -+ return false; -+ -+ return true; -+} -+ - static void nfqnl_reinject(struct nf_queue_entry *entry, unsigned int verdict) - { - const struct nf_ct_hook *ct_hook; - -+ if (!nf_bridge_ports_valid(entry)) -+ verdict = NF_DROP; -+ - if (verdict == NF_ACCEPT || - verdict == NF_REPEAT || - verdict == NF_STOP) { -@@ -548,6 +585,23 @@ static int nf_queue_checksum_help(struct sk_buff *entskb) - return skb_checksum_help(entskb); - } - -+#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) -+static int nfqnl_put_master_ifindex(struct sk_buff *nlskb, int attr, -+ const struct net_device *dev) -+{ -+ const struct net_device *upper; -+ -+ if (dev && !netif_is_bridge_port(dev)) -+ return 0; -+ -+ upper = netdev_master_upper_dev_get_rcu((struct net_device *)dev); -+ if (upper && nla_put_be32(nlskb, attr, htonl(upper->ifindex))) -+ return -EMSGSIZE; -+ -+ return 0; -+} -+#endif -+ - static struct sk_buff * - nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, - struct nf_queue_entry *entry, -@@ -681,10 +735,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, - * netfilter_bridge) */ - if (nla_put_be32(skb, NFQA_IFINDEX_PHYSINDEV, - htonl(indev->ifindex)) || -- /* this is the bridge group "brX" */ -- /* rcu_read_lock()ed by __nf_queue */ -- nla_put_be32(skb, NFQA_IFINDEX_INDEV, -- htonl(br_port_get_rcu(indev)->br->dev->ifindex))) -+ nfqnl_put_master_ifindex(skb, NFQA_IFINDEX_INDEV, indev)) - goto nla_put_failure; - } else { - int physinif; -@@ -715,10 +766,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, - * netfilter_bridge) */ - if (nla_put_be32(skb, NFQA_IFINDEX_PHYSOUTDEV, - htonl(outdev->ifindex)) || -- /* this is the bridge group "brX" */ -- /* rcu_read_lock()ed by __nf_queue */ -- nla_put_be32(skb, NFQA_IFINDEX_OUTDEV, -- htonl(br_port_get_rcu(outdev)->br->dev->ifindex))) -+ nfqnl_put_master_ifindex(skb, NFQA_IFINDEX_OUTDEV, outdev)) - goto nla_put_failure; - } else { - int physoutif; diff --git a/1167-netfilter-nf-conntrack-destroy-stale-expectfn-expectations-on-unregister.patch b/1167-netfilter-nf-conntrack-destroy-stale-expectfn-expectations-on-unregister.patch deleted file mode 100644 index 22765311d..000000000 --- a/1167-netfilter-nf-conntrack-destroy-stale-expectfn-expectations-on-unregister.patch +++ /dev/null @@ -1,138 +0,0 @@ -From f92c90a2a3e6ff6f9f7fe88fde9004b4ca8f956d Mon Sep 17 00:00:00 2001 -From: Weiming Shi -Date: Wed, 3 Jun 2026 00:38:17 -0700 -Subject: [PATCH] netfilter: nf_conntrack: destroy stale expectfn expectations - on unregister - -[ Upstream commit c3009418f9fa1dcb3eb86f4d8c92583537b5faa3 ] - -NAT helpers such as nf_nat_h323 store a raw pointer to module text in -exp->expectfn (e.g. ip_nat_q931_expect). nf_ct_helper_expectfn_unregister() -only unlinks the callback descriptor and never walks the expectation table, -so an expectation pending at module removal survives with a dangling -exp->expectfn into freed module text. - -When the expected connection arrives, init_conntrack() invokes -exp->expectfn(), now a stale pointer into the unloaded module. Reproduced -on a KASAN build by loading the H.323 helpers, creating a Q.931 -expectation, unloading nf_nat_h323, then connecting to the expected port: - - Oops: int3: 0000 [#1] SMP KASAN NOPTI - RIP: 0010:0xffffffffa06102d1 - init_conntrack.isra.0 (net/netfilter/nf_conntrack_core.c:1862) - nf_conntrack_in (net/netfilter/nf_conntrack_core.c:2049) - ipv4_conntrack_local (net/netfilter/nf_conntrack_proto.c:223) - nf_hook_slow (net/netfilter/core.c:619) - __ip_local_out (net/ipv4/ip_output.c:120) - __tcp_transmit_skb (net/ipv4/tcp_output.c:1715) - tcp_connect (net/ipv4/tcp_output.c:4374) - tcp_v4_connect (net/ipv4/tcp_ipv4.c:345) - __sys_connect (net/socket.c:2167) - Modules linked in: nf_conntrack_h323 [last unloaded: nf_nat_h323] - -Reaching the dangling state requires CAP_SYS_MODULE in the initial user -namespace to remove a NAT helper that still has live expectations, so this -is a robustness fix; leaving an expectation pointing at freed text is wrong -regardless. - -Add nf_ct_helper_expectfn_destroy(), which walks the expectation table and -drops every expectation whose ->expectfn matches the descriptor being torn -down. Call it from each NAT helper's exit path after the existing RCU grace -period, so no expectation outlives the code it points at and no extra -synchronize_rcu() is introduced. With the fix, the same reproducer runs to -completion without the Oops. - -Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port") -Reported-by: Xiang Mei -Assisted-by: Claude:claude-opus-4-8 -Signed-off-by: Weiming Shi -Signed-off-by: Pablo Neira Ayuso -Signed-off-by: Sasha Levin - -diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h -index de2f956..24cf3d2 100644 ---- a/include/net/netfilter/nf_conntrack_helper.h -+++ b/include/net/netfilter/nf_conntrack_helper.h -@@ -155,6 +155,7 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct, - - void nf_ct_helper_expectfn_register(struct nf_ct_helper_expectfn *n); - void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n); -+void nf_ct_helper_expectfn_destroy(const struct nf_ct_helper_expectfn *n); - struct nf_ct_helper_expectfn * - nf_ct_helper_expectfn_find_by_name(const char *name); - struct nf_ct_helper_expectfn * -diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c -index faee20a..10e1b08 100644 ---- a/net/ipv4/netfilter/nf_nat_h323.c -+++ b/net/ipv4/netfilter/nf_nat_h323.c -@@ -555,6 +555,8 @@ static void __exit nf_nat_h323_fini(void) - nf_ct_helper_expectfn_unregister(&q931_nat); - nf_ct_helper_expectfn_unregister(&callforwarding_nat); - synchronize_rcu(); -+ nf_ct_helper_expectfn_destroy(&q931_nat); -+ nf_ct_helper_expectfn_destroy(&callforwarding_nat); - } - - /****************************************************************************/ -diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c -index 17e971b..2c5a717 100644 ---- a/net/netfilter/nf_conntrack_helper.c -+++ b/net/netfilter/nf_conntrack_helper.c -@@ -283,6 +283,25 @@ void nf_ct_helper_expectfn_unregister(struct nf_ct_helper_expectfn *n) - } - EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_unregister); - -+static bool expect_iter_expectfn(struct nf_conntrack_expect *exp, void *data) -+{ -+ const struct nf_ct_helper_expectfn *n = data; -+ -+ /* Relies on registered expectfn descriptors having unique ->expectfn -+ * pointers, which holds for the in-tree NAT helpers. -+ */ -+ return exp->expectfn == n->expectfn; -+} -+ -+/* Destroy expectations still pointing at @n->expectfn; call after the -+ * caller's RCU grace period so none outlives the (often modular) callback. -+ */ -+void nf_ct_helper_expectfn_destroy(const struct nf_ct_helper_expectfn *n) -+{ -+ nf_ct_expect_iterate_destroy(expect_iter_expectfn, (void *)n); -+} -+EXPORT_SYMBOL_GPL(nf_ct_helper_expectfn_destroy); -+ - /* Caller should hold the rcu lock */ - struct nf_ct_helper_expectfn * - nf_ct_helper_expectfn_find_by_name(const char *name) -diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c -index d380e1a..12bc8c9 100644 ---- a/net/netfilter/nf_nat_core.c -+++ b/net/netfilter/nf_nat_core.c -@@ -1355,6 +1355,7 @@ static int __init nf_nat_init(void) - RCU_INIT_POINTER(nf_nat_hook, NULL); - nf_ct_helper_expectfn_unregister(&follow_master_nat); - synchronize_net(); -+ nf_ct_helper_expectfn_destroy(&follow_master_nat); - unregister_pernet_subsys(&nat_net_ops); - kvfree(nf_nat_bysource); - } -@@ -1372,6 +1373,7 @@ static void __exit nf_nat_cleanup(void) - RCU_INIT_POINTER(nf_nat_hook, NULL); - - synchronize_net(); -+ nf_ct_helper_expectfn_destroy(&follow_master_nat); - kvfree(nf_nat_bysource); - unregister_pernet_subsys(&nat_net_ops); - } -diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c -index 9fbfc6b..00838c0 100644 ---- a/net/netfilter/nf_nat_sip.c -+++ b/net/netfilter/nf_nat_sip.c -@@ -655,6 +655,7 @@ static void __exit nf_nat_sip_fini(void) - RCU_INIT_POINTER(nf_nat_sip_hooks, NULL); - nf_ct_helper_expectfn_unregister(&sip_nat); - synchronize_rcu(); -+ nf_ct_helper_expectfn_destroy(&sip_nat); - } - - static const struct nf_nat_sip_hooks sip_hooks = { diff --git a/1168-netfilter-nf-log-validate-mac-header-was-set-before-dumping-it.patch b/1168-netfilter-nf-log-validate-mac-header-was-set-before-dumping-it.patch deleted file mode 100644 index fc957f7ad..000000000 --- a/1168-netfilter-nf-log-validate-mac-header-was-set-before-dumping-it.patch +++ /dev/null @@ -1,63 +0,0 @@ -From c38d41134085193efd5b237cf513ad5b3421a60d Mon Sep 17 00:00:00 2001 -From: Xiang Mei -Date: Tue, 9 Jun 2026 15:55:02 -0700 -Subject: [PATCH] netfilter: nf_log: validate MAC header was set before dumping - it - -[ Upstream commit a84b6fedbc97078788be78dbdd7517d143ad1a77 ] - -The fallback path of dump_mac_header() guards the MAC header access -only with "skb->mac_header != skb->network_header", without checking -skb_mac_header_was_set(). When the MAC header is unset, mac_header is -0xffff, so the test passes and skb_mac_header(skb) returns -skb->head + 0xffff, ~64 KiB past the buffer; the loop then reads -dev->hard_header_len bytes out of bounds into the kernel log. - -This is reachable via the netdev logger: nf_log_unknown_packet() calls -dump_mac_header() unconditionally, and an skb sent through AF_PACKET -with PACKET_QDISC_BYPASS reaches the egress hook with mac_header still -unset (__dev_queue_xmit(), which would reset it, is bypassed). - -Add the skb_mac_header_was_set() check the ARPHRD_ETHER path already -uses, and replace the open-coded MAC header length test with -skb_mac_header_len(). Only skbs with an unset MAC header are affected; -valid ones are dumped as before. - - BUG: KASAN: slab-out-of-bounds in dump_mac_header (net/netfilter/nf_log_syslog.c:831) - Read of size 1 at addr ffff88800ea49d3f by task exploit/148 - Call Trace: - kasan_report (mm/kasan/report.c:595) - dump_mac_header (net/netfilter/nf_log_syslog.c:831) - nf_log_netdev_packet (net/netfilter/nf_log_syslog.c:938 net/netfilter/nf_log_syslog.c:963) - nf_log_packet (net/netfilter/nf_log.c:260) - nft_log_eval (net/netfilter/nft_log.c:60) - nft_do_chain (net/netfilter/nf_tables_core.c:285) - nft_do_chain_netdev (net/netfilter/nft_chain_filter.c:307) - nf_hook_slow (net/netfilter/core.c:619) - nf_hook_direct_egress (net/packet/af_packet.c:257) - packet_xmit (net/packet/af_packet.c:280) - packet_sendmsg (net/packet/af_packet.c:3114) - __sys_sendto (net/socket.c:2265) - -Fixes: 7eb9282cd0ef ("netfilter: ipt_LOG/ip6t_LOG: add option to print decoded MAC header") -Reported-by: Weiming Shi -Assisted-by: Claude:claude-opus-4-8 -Signed-off-by: Xiang Mei -Signed-off-by: Pablo Neira Ayuso -Signed-off-by: Sasha Levin - -diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c -index 5840222..09b9152 100644 ---- a/net/netfilter/nf_log_syslog.c -+++ b/net/netfilter/nf_log_syslog.c -@@ -799,8 +799,8 @@ static void dump_mac_header(struct nf_log_buf *m, - - fallback: - nf_log_buf_add(m, "MAC="); -- if (dev->hard_header_len && -- skb->mac_header != skb->network_header) { -+ if (dev->hard_header_len && skb_mac_header_was_set(skb) && -+ skb_mac_header_len(skb) != 0) { - const unsigned char *p = skb_mac_header(skb); - unsigned int i; - diff --git a/1169-netfilter-nft-exthdr-fix-register-tracking-for-f-present-flag.patch b/1169-netfilter-nft-exthdr-fix-register-tracking-for-f-present-flag.patch deleted file mode 100644 index d0aa5a96b..000000000 --- a/1169-netfilter-nft-exthdr-fix-register-tracking-for-f-present-flag.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 67b27434c43b68a97becda98c9f0c8cf6cba2134 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Tue, 9 Jun 2026 21:28:09 +0200 -Subject: [PATCH] netfilter: nft_exthdr: fix register tracking for F_PRESENT - flag - -[ Upstream commit 772cecf198da732faebb5dcfc46d66a505be8495 ] - -nft_exthdr_init() passes user-controlled priv->len to -nft_parse_register_store(), which marks that many bytes in the -register bitmap as initialized. However, when NFT_EXTHDR_F_PRESENT -is set, the eval paths write only 1 byte (nft_reg_store8) or -4 bytes (*dest = 0 on TCP/DCCP error path). When len > 4, -registers beyond the first are never written, retaining -uninitialized stack data from nft_regs. - -Bail out if userspace requests too much data when F_PRESENT is set. - -Reported-by: Ji'an Zhou -Fixes: c078ca3b0c5b ("netfilter: nft_exthdr: Add support for existence check") -Signed-off-by: Florian Westphal -Signed-off-by: Pablo Neira Ayuso -Signed-off-by: Sasha Levin - -diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c -index c74012c..1fc2a94 100644 ---- a/net/netfilter/nft_exthdr.c -+++ b/net/netfilter/nft_exthdr.c -@@ -530,6 +530,9 @@ static int nft_exthdr_init(const struct nft_ctx *ctx, - return err; - } - -+ if ((flags & NFT_EXTHDR_F_PRESENT) && len != 1) -+ return -EINVAL; -+ - priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]); - priv->offset = offset; - priv->len = len; diff --git a/1170-netfilter-nft-fib-fix-stale-stack-leak-via-the-oifname-register.patch b/1170-netfilter-nft-fib-fix-stale-stack-leak-via-the-oifname-register.patch deleted file mode 100644 index b97d289fb..000000000 --- a/1170-netfilter-nft-fib-fix-stale-stack-leak-via-the-oifname-register.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 8c84885e9790823828bb8084736ea15769b1ac16 Mon Sep 17 00:00:00 2001 -From: Davide Ornaghi -Date: Mon, 15 Jun 2026 09:34:53 -0400 -Subject: [PATCH] netfilter: nft_fib: fix stale stack leak via the OIFNAME - register - -[ Upstream commit ab185e0c4fb82dfba6fb86f8271e06f931d9c64c ] - -For NFT_FIB_RESULT_OIFNAME the destination register is declared with -len = IFNAMSIZ (four 32-bit registers), but on the lookup-fail, -RTN_LOCAL and oif-mismatch paths nft_fib{4,6}_eval() only writes one -register via "*dest = 0". The remaining three registers are left as -whatever was on the stack in nft_do_chain()'s struct nft_regs, and a -downstream expression that loads the register span can leak that -uninitialised kernel stack to userspace. - -The NFTA_FIB_F_PRESENT existence check has the same shape: it is only -meaningful for NFT_FIB_RESULT_OIF, yet it was accepted for any result type -while the eval stores a single byte via nft_reg_store8(), leaving the rest -of the declared span stale. - -Fix both: - - - replace the bare "*dest = 0" in the eval with nft_fib_store_result(), - which strscpy_pad()s the whole IFNAMSIZ for OIFNAME (and is already - used on the other early-return path), and - - - restrict NFTA_FIB_F_PRESENT to NFT_FIB_RESULT_OIF and declare its - destination as a single u8, so the marked span matches the one byte - the eval writes. - -Fixes: f6d0cbcf09c5 ("netfilter: nf_tables: add fib expression") -Suggested-by: Florian Westphal -Cc: stable@vger.kernel.org -Signed-off-by: Davide Ornaghi -Signed-off-by: Pablo Neira Ayuso -[ kept the tree's older `ip6_route_lookup()`/`rt6_info` IPv6 context and changed only `*dest = 0;` to `nft_fib_store_result(dest, priv, NULL);` ] -Signed-off-by: Sasha Levin -Signed-off-by: Greg Kroah-Hartman - -diff --git a/net/ipv4/netfilter/nft_fib_ipv4.c b/net/ipv4/netfilter/nft_fib_ipv4.c -index f514eb5..1c22ee4 100644 ---- a/net/ipv4/netfilter/nft_fib_ipv4.c -+++ b/net/ipv4/netfilter/nft_fib_ipv4.c -@@ -127,7 +127,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs, - fl4.saddr = get_saddr(iph->daddr); - } - -- *dest = 0; -+ nft_fib_store_result(dest, priv, NULL); - - if (fib_lookup(nft_net(pkt), &fl4, &res, FIB_LOOKUP_IGNORE_LINKSTATE)) - return; -diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c -index 421036a..3005dfb 100644 ---- a/net/ipv6/netfilter/nft_fib_ipv6.c -+++ b/net/ipv6/netfilter/nft_fib_ipv6.c -@@ -192,7 +192,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs, - - lookup_flags = nft_fib6_flowi_init(&fl6, priv, pkt, oif, iph); - -- *dest = 0; -+ nft_fib_store_result(dest, priv, NULL); - rt = (void *)ip6_route_lookup(nft_net(pkt), &fl6, pkt->skb, - lookup_flags); - if (rt->dst.error) -diff --git a/net/netfilter/nft_fib.c b/net/netfilter/nft_fib.c -index 96e02a8..2284613 100644 ---- a/net/netfilter/nft_fib.c -+++ b/net/netfilter/nft_fib.c -@@ -107,6 +107,12 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr, - return -EINVAL; - } - -+ if (priv->flags & NFTA_FIB_F_PRESENT) { -+ if (priv->result != NFT_FIB_RESULT_OIF) -+ return -EINVAL; -+ len = sizeof(u8); -+ } -+ - err = nft_parse_register_store(ctx, tb[NFTA_FIB_DREG], &priv->dreg, - NULL, NFT_DATA_VALUE, len); - if (err < 0) diff --git a/1171-netfilter-nf-dup-netdev-add-nf-dev-xmit-recursion-helpers-and-use-them.patch b/1171-netfilter-nf-dup-netdev-add-nf-dev-xmit-recursion-helpers-and-use-them.patch deleted file mode 100644 index 937bd4d1c..000000000 --- a/1171-netfilter-nf-dup-netdev-add-nf-dev-xmit-recursion-helpers-and-use-them.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 2354e975932dabb06fad239f07a3b68fd1809737 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Wed, 10 Jun 2026 00:03:19 +0200 -Subject: [PATCH] netfilter: nf_dup_netdev: add nf_dev_xmit_recursion*() - helpers and use them - -Update nft_dup and nft_fwd to use the nf_dev_xmit_recursion() helpers. -This patch also disables BH when transmitting the skb to address a -possible migration to different CPU leading to imbalanced decrementation -of the recursion counters. - -This is modeled after Florian Westphal's dev_xmit_recursion*() API -available since commit 97cdcf37b57e ("net: place xmit recursion in -softnet data") according to its current state in the tree. - -Fixes: 1d47b55b36d2 ("netfilter: nft_fwd_netdev: use recursion counter in neigh egress path") -Fixes: f37ad9127039 ("netfilter: nf_dup_netdev: Move the recursion counter struct netdev_xmit") -Signed-off-by: Pablo Neira Ayuso - -diff --git a/include/net/netfilter/nf_dup_netdev.h b/include/net/netfilter/nf_dup_netdev.h -index 609bcf4..b175d27 100644 ---- a/include/net/netfilter/nf_dup_netdev.h -+++ b/include/net/netfilter/nf_dup_netdev.h -@@ -3,23 +3,10 @@ - #define _NF_DUP_NETDEV_H_ - - #include --#include --#include - - void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif); - void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif); - --#define NF_RECURSION_LIMIT 2 -- --static inline u8 *nf_get_nf_dup_skb_recursion(void) --{ --#ifndef CONFIG_PREEMPT_RT -- return this_cpu_ptr(&softnet_data.xmit.nf_dup_skb_recursion); --#else -- return ¤t->net_xmit.nf_dup_skb_recursion; --#endif --} -- - struct nft_offload_ctx; - struct nft_flow_rule; - -diff --git a/net/netfilter/nf_dup_netdev.c b/net/netfilter/nf_dup_netdev.c -index 516bcf4..ab39733 100644 ---- a/net/netfilter/nf_dup_netdev.c -+++ b/net/netfilter/nf_dup_netdev.c -@@ -17,28 +17,24 @@ - - static DEFINE_PER_CPU(u8, nf_dup_skb_recursion); - --#define NF_RECURSION_LIMIT 2 -- --#ifndef CONFIG_PREEMPT_RT --static u8 *nf_get_nf_dup_skb_recursion(void) -+static bool nf_dev_xmit_recursion(void) - { -- return this_cpu_ptr(&softnet_data.xmit.nf_dup_skb_recursion); -+ return unlikely(__this_cpu_read(nf_dup_skb_recursion) > NF_RECURSION_LIMIT); - } --#else - --static u8 *nf_get_nf_dup_skb_recursion(void) -+static void nf_dev_xmit_recursion_inc(void) - { -- return ¤t->net_xmit.nf_dup_skb_recursion; -+ __this_cpu_inc(nf_dup_skb_recursion); - } - --#endif -+static void nf_dev_xmit_recursion_dec(void) -+{ -+ __this_cpu_dec(nf_dup_skb_recursion); -+} - - static void nf_do_netdev_egress(struct sk_buff *skb, struct net_device *dev, - enum nf_dev_hooks hook) - { -- if (__this_cpu_read(nf_dup_skb_recursion) > NF_RECURSION_LIMIT) -- goto err; -- - if (hook == NF_NETDEV_INGRESS && skb_mac_header_was_set(skb)) { - if (skb_cow_head(skb, skb->mac_len)) - goto err; -@@ -48,9 +44,15 @@ static void nf_do_netdev_egress(struct sk_buff *skb, struct net_device *dev, - - skb->dev = dev; - skb_clear_tstamp(skb); -- __this_cpu_inc(nf_dup_skb_recursion); -+ local_bh_disable(); -+ if (nf_dev_xmit_recursion()) { -+ local_bh_enable(); -+ goto err; -+ } -+ nf_dev_xmit_recursion_inc(); - dev_queue_xmit(skb); -- __this_cpu_dec(nf_dup_skb_recursion); -+ nf_dev_xmit_recursion_dec(); -+ local_bh_enable(); - return; - err: - kfree_skb(skb); -diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c -index a9743a1..8b0de2d 100644 ---- a/net/netfilter/nft_fwd_netdev.c -+++ b/net/netfilter/nft_fwd_netdev.c -@@ -21,6 +21,25 @@ struct nft_fwd_netdev { - u8 sreg_dev; - }; - -+ -+#define NF_RECURSION_LIMIT 2 -+static DEFINE_PER_CPU(u8, nf_dup_skb_recursion); -+ -+static bool nf_dev_xmit_recursion(void) -+{ -+ return unlikely(__this_cpu_read(nf_dup_skb_recursion) > NF_RECURSION_LIMIT); -+} -+ -+static void nf_dev_xmit_recursion_inc(void) -+{ -+ __this_cpu_inc(nf_dup_skb_recursion); -+} -+ -+static void nf_dev_xmit_recursion_dec(void) -+{ -+ __this_cpu_dec(nf_dup_skb_recursion); -+} -+ - static void nft_fwd_netdev_eval(const struct nft_expr *expr, - struct nft_regs *regs, - const struct nft_pktinfo *pkt) -@@ -95,7 +114,6 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr, - struct nft_regs *regs, - const struct nft_pktinfo *pkt) - { -- u8 *nf_dup_skb_recursion = nf_get_nf_dup_skb_recursion(); - struct nft_fwd_neigh *priv = nft_expr_priv(expr); - void *addr = ®s->data[priv->sreg_addr]; - int oif = regs->data[priv->sreg_dev]; -@@ -144,13 +162,15 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr, - goto out; - } - -- if (*nf_dup_skb_recursion > NF_RECURSION_LIMIT) { -+ dev = dev_get_by_index_rcu(nft_net(pkt), oif); -+ if (!dev) { - verdict = NF_DROP; - goto out; - } - -- dev = dev_get_by_index_rcu(nft_net(pkt), oif); -- if (dev == NULL) { -+ local_bh_disable(); -+ if (nf_dev_xmit_recursion()) { -+ local_bh_enable(); - verdict = NF_DROP; - goto out; - } -@@ -159,16 +179,18 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr, - if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { - skb = skb_expand_head(skb, hh_len); - if (!skb) { -- verdict = NF_STOLEN; -+ local_bh_enable(); - goto out; - } - } - - skb->dev = dev; - skb_clear_tstamp(skb); -- (*nf_dup_skb_recursion)++; -+ -+ nf_dev_xmit_recursion_inc(); - neigh_xmit(neigh_table, dev, addr, skb); -- (*nf_dup_skb_recursion)--; -+ nf_dev_xmit_recursion_dec(); -+ local_bh_enable(); - out: - regs->verdict.code = verdict; - } diff --git a/1172-netfilter-ctnetlink-use-nf-ct-exp-net-in-expectation-dump.patch b/1172-netfilter-ctnetlink-use-nf-ct-exp-net-in-expectation-dump.patch deleted file mode 100644 index 31a76ed36..000000000 --- a/1172-netfilter-ctnetlink-use-nf-ct-exp-net-in-expectation-dump.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 13e0a1308f7e0d30a339e4d839576bddd419dd69 Mon Sep 17 00:00:00 2001 -From: Pratham Gupta -Date: Mon, 4 May 2026 22:11:57 -0700 -Subject: [PATCH] netfilter: ctnetlink: use nf_ct_exp_net() in expectation dump - -commit a7f57320bbbc67e347bf5fff4b4a9bab980d5956 upstream. - -Commit 02a3231b6d82 ("netfilter: nf_conntrack_expect: store netns and zone in expectation") -introduced exp->net so RCU-only expectation paths no longer need to -dereference exp->master for netns lookups. - -Commit 3db5647984de ("netfilter: nf_conntrack_expect: skip expectations in other netns via proc") -updated the proc path accordingly, but ctnetlink_exp_dump_table() still -compares against nf_ct_net(exp->master). - -Use nf_ct_exp_net(exp) here as well so the netlink dump path matches -the rest of the March 2026 expectation netns/RCU cleanup. - -Fixes: 02a3231b6d82 ("netfilter: nf_conntrack_expect: store netns and zone in expectation") -Cc: stable@vger.kernel.org -Signed-off-by: Pratham Gupta -Signed-off-by: Florian Westphal -Signed-off-by: Greg Kroah-Hartman - -diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c -index caf0506..b375374 100644 ---- a/net/netfilter/nf_conntrack_netlink.c -+++ b/net/netfilter/nf_conntrack_netlink.c -@@ -3194,7 +3194,7 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) - if (l3proto && exp->tuple.src.l3num != l3proto) - continue; - -- if (!net_eq(nf_ct_net(exp->master), net)) -+ if (!net_eq(nf_ct_exp_net(exp), net)) - continue; - - if (cb->args[1]) { diff --git a/1173-selftests-netfilter-nft-concat-range-sh-add-check-for-double-create-bug.patch b/1173-selftests-netfilter-nft-concat-range-sh-add-check-for-double-create-bug.patch deleted file mode 100644 index 278ac197b..000000000 --- a/1173-selftests-netfilter-nft-concat-range-sh-add-check-for-double-create-bug.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 42c3e9df13adbd54053eaacbfe7337844a243a2b Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 16:57:34 +0200 -Subject: [PATCH] selftests: netfilter: nft_concat_range.sh: add check for - double-create bug - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 94bd247bc25b - -commit 94bd247bc25b7f1560f96e9c912db3ec1fc878ea -Author: Florian Westphal -Date: Wed Sep 10 01:39:48 2025 +0200 - - selftests: netfilter: nft_concat_range.sh: add check for double-create bug - - Add a test case for bug resolved with: - 'netfilter: nft_set_pipapo_avx2: fix skip of expired entries'. - - It passes on nf.git (it uses the generic/C version for insertion - duplicate check) but fails on unpatched nf-next if AVX2 is supported: - - cannot create same element twice 0s [FAIL] - Could create element twice in same transaction - table inet filter { # handle 8 - [..] - elements = { 1.2.3.4 . 1.2.4.1 counter packets 0 bytes 0, - 1.2.4.1 . 1.2.3.4 counter packets 0 bytes 0, - 1.2.3.4 . 1.2.4.1 counter packets 0 bytes 0, - 1.2.4.1 . 1.2.3.4 counter packets 0 bytes 0 } - - Reviewed-by: Stefano Brivio - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/tools/testing/selftests/net/netfilter/nft_concat_range.sh b/tools/testing/selftests/net/netfilter/nft_concat_range.sh -index 20e76b3..ad97c62 100755 ---- a/tools/testing/selftests/net/netfilter/nft_concat_range.sh -+++ b/tools/testing/selftests/net/netfilter/nft_concat_range.sh -@@ -29,7 +29,7 @@ TYPES="net_port port_net net6_port port_proto net6_port_mac net6_port_mac_proto - net6_port_net6_port net_port_mac_proto_net" - - # Reported bugs, also described by TYPE_ variables below --BUGS="flush_remove_add reload net_port_proto_match avx2_mismatch" -+BUGS="flush_remove_add reload net_port_proto_match avx2_mismatch doublecreate" - - # List of possible paths to pktgen script from kernel tree for performance tests - PKTGEN_SCRIPT_PATHS=" -@@ -408,6 +408,18 @@ perf_duration 0 - " - - -+TYPE_doublecreate=" -+display cannot create same element twice -+type_spec ipv4_addr . ipv4_addr -+chain_spec ip saddr . ip daddr -+dst addr4 -+proto icmp -+ -+race_repeat 0 -+ -+perf_duration 0 -+" -+ - # Set template for all tests, types and rules are filled in depending on test - set_template=' - flush ruleset -@@ -1900,6 +1912,48 @@ test_bug_avx2_mismatch() - fi - } - -+test_bug_doublecreate() -+{ -+ local elements="1.2.3.4 . 1.2.4.1, 1.2.4.1 . 1.2.3.4" -+ local ret=1 -+ local i -+ -+ setup veth send_"${proto}" set || return ${ksft_skip} -+ -+ add "{ $elements }" || return 1 -+ # expected to work: 'add' on existing should be no-op. -+ add "{ $elements }" || return 1 -+ -+ # 'create' should return an error. -+ if nft create element inet filter test "{ $elements }" 2>/dev/null; then -+ err "Could create an existing element" -+ return 1 -+ fi -+nft -f - </dev/null -+flush set inet filter test -+create element inet filter test { $elements } -+create element inet filter test { $elements } -+EOF -+ ret=$? -+ if [ $ret -eq 0 ]; then -+ err "Could create element twice in one transaction" -+ err "$(nft -a list ruleset)" -+ return 1 -+ fi -+ -+nft -f - </dev/null -+flush set inet filter test -+create element inet filter test { $elements } -+EOF -+ ret=$? -+ if [ $ret -ne 0 ]; then -+ err "Could not flush and re-create element in one transaction" -+ return 1 -+ fi -+ -+ return 0 -+} -+ - test_reported_issues() { - eval test_bug_"${subtest}" - } diff --git a/1174-selftests-netfilter-nft-concat-range-sh-add-check-for-overlap-detection-bug.patch b/1174-selftests-netfilter-nft-concat-range-sh-add-check-for-overlap-detection-bug.patch deleted file mode 100644 index 874db2ce9..000000000 --- a/1174-selftests-netfilter-nft-concat-range-sh-add-check-for-overlap-detection-bug.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 5f36590a1e7231d0c4575a7e243be208dbf96157 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:09:36 +0200 -Subject: [PATCH] selftests: netfilter: nft_concat_range.sh: add check for - overlap detection bug - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit a675d1caa204 - -commit a675d1caa2041f05f6343fad67b04f8babf32217 -Author: Florian Westphal -Date: Thu Dec 4 12:20:36 2025 +0100 - - selftests: netfilter: nft_concat_range.sh: add check for overlap detection bug - - without 'netfilter: nft_set_pipapo: fix range overlap detection': - - reject overlapping range on add 0s [FAIL] - Returned success for add { 1.2.3.4 . 1.2.4.1-1.2.4.2 } given set: - table inet filter { - [..] - elements = { 1.2.3.4 . 1.2.4.1 counter packets 0 bytes 0, - 1.2.3.0-1.2.3.4 . 1.2.4.2 counter packets 0 bytes 0 } - } - - The element collides with existing ones and was not added, but kernel - returned success to userspace. - - Signed-off-by: Florian Westphal - -Signed-off-by: Florian Westphal - -diff --git a/tools/testing/selftests/net/netfilter/nft_concat_range.sh b/tools/testing/selftests/net/netfilter/nft_concat_range.sh -index ad97c62..394166f 100755 ---- a/tools/testing/selftests/net/netfilter/nft_concat_range.sh -+++ b/tools/testing/selftests/net/netfilter/nft_concat_range.sh -@@ -29,7 +29,7 @@ TYPES="net_port port_net net6_port port_proto net6_port_mac net6_port_mac_proto - net6_port_net6_port net_port_mac_proto_net" - - # Reported bugs, also described by TYPE_ variables below --BUGS="flush_remove_add reload net_port_proto_match avx2_mismatch doublecreate" -+BUGS="flush_remove_add reload net_port_proto_match avx2_mismatch doublecreate insert_overlap" - - # List of possible paths to pktgen script from kernel tree for performance tests - PKTGEN_SCRIPT_PATHS=" -@@ -420,6 +420,18 @@ race_repeat 0 - perf_duration 0 - " - -+TYPE_insert_overlap=" -+display reject overlapping range on add -+type_spec ipv4_addr . ipv4_addr -+chain_spec ip saddr . ip daddr -+dst addr4 -+proto icmp -+ -+race_repeat 0 -+ -+perf_duration 0 -+" -+ - # Set template for all tests, types and rules are filled in depending on test - set_template=' - flush ruleset -@@ -1954,6 +1966,37 @@ EOF - return 0 - } - -+add_fail() -+{ -+ if nft add element inet filter test "$1" 2>/dev/null ; then -+ err "Returned success for add ${1} given set:" -+ err "$(nft -a list set inet filter test )" -+ return 1 -+ fi -+ -+ return 0 -+} -+ -+test_bug_insert_overlap() -+{ -+ local elements="1.2.3.4 . 1.2.4.1" -+ -+ setup veth send_"${proto}" set || return ${ksft_skip} -+ -+ add "{ $elements }" || return 1 -+ -+ elements="1.2.3.0-1.2.3.4 . 1.2.4.1" -+ add_fail "{ $elements }" || return 1 -+ -+ elements="1.2.3.0-1.2.3.4 . 1.2.4.2" -+ add "{ $elements }" || return 1 -+ -+ elements="1.2.3.4 . 1.2.4.1-1.2.4.2" -+ add_fail "{ $elements }" || return 1 -+ -+ return 0 -+} -+ - test_reported_issues() { - eval test_bug_"${subtest}" - } diff --git a/1175-selftests-netfilter-nft-concat-range-sh-add-check-for-flush-reload-bug.patch b/1175-selftests-netfilter-nft-concat-range-sh-add-check-for-flush-reload-bug.patch deleted file mode 100644 index 266c010be..000000000 --- a/1175-selftests-netfilter-nft-concat-range-sh-add-check-for-flush-reload-bug.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 610978474e5b971198d6181be868483d0da92936 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 13 May 2026 17:16:14 +0200 -Subject: [PATCH] selftests: netfilter: nft_concat_range.sh: add check for - flush+reload bug - -JIRA: https://redhat.atlassian.net/browse/RHEL-168848 -Upstream Status: commit 6caefcd9491c - -commit 6caefcd9491c408a4d161f7b60c8bb3d956526dd -Author: Florian Westphal -Date: Wed Mar 25 14:10:56 2026 +0100 - - selftests: netfilter: nft_concat_range.sh: add check for flush+reload bug - - This test will fail without - the preceding commit ("netfilter: nft_set_pipapo_avx2: fix match retart if found element is expired"): - - reject overlapping range on add 0s [ OK ] - reload with flush /dev/stdin:59:32-52: Error: Could not process rule: File exists - add element inet filter test { 10.0.0.29 . 10.0.2.29 } - - Reviewed-by: Stefano Brivio - Signed-off-by: Florian Westphal - Signed-off-by: Pablo Neira Ayuso - -Signed-off-by: Florian Westphal - -diff --git a/tools/testing/selftests/net/netfilter/nft_concat_range.sh b/tools/testing/selftests/net/netfilter/nft_concat_range.sh -index 394166f..a387266 100755 ---- a/tools/testing/selftests/net/netfilter/nft_concat_range.sh -+++ b/tools/testing/selftests/net/netfilter/nft_concat_range.sh -@@ -29,7 +29,8 @@ TYPES="net_port port_net net6_port port_proto net6_port_mac net6_port_mac_proto - net6_port_net6_port net_port_mac_proto_net" - - # Reported bugs, also described by TYPE_ variables below --BUGS="flush_remove_add reload net_port_proto_match avx2_mismatch doublecreate insert_overlap" -+BUGS="flush_remove_add reload net_port_proto_match avx2_mismatch doublecreate -+ insert_overlap load_flush_load4 load_flush_load8" - - # List of possible paths to pktgen script from kernel tree for performance tests - PKTGEN_SCRIPT_PATHS=" -@@ -432,6 +433,30 @@ race_repeat 0 - perf_duration 0 - " - -+TYPE_load_flush_load4=" -+display reload with flush, 4bit groups -+type_spec ipv4_addr . ipv4_addr -+chain_spec ip saddr . ip daddr -+dst addr4 -+proto icmp -+ -+race_repeat 0 -+ -+perf_duration 0 -+" -+ -+TYPE_load_flush_load8=" -+display reload with flush, 8bit groups -+type_spec ipv4_addr . ipv4_addr -+chain_spec ip saddr . ip daddr -+dst addr4 -+proto icmp -+ -+race_repeat 0 -+ -+perf_duration 0 -+" -+ - # Set template for all tests, types and rules are filled in depending on test - set_template=' - flush ruleset -@@ -1981,6 +2006,12 @@ test_bug_insert_overlap() - { - local elements="1.2.3.4 . 1.2.4.1" - -+ # This test has to be skipped, RHEL-10.2 ntentionally lacks -+ # 7711f4bb4b36 ("netfilter: nft_set_pipapo: fix range overlap detection") -+ # because this fix could cause issues with existing deployments -+ # (ruleset restore failure). -+ return ${ksft_skip} -+ - setup veth send_"${proto}" set || return ${ksft_skip} - - add "{ $elements }" || return 1 -@@ -1997,6 +2028,49 @@ test_bug_insert_overlap() - return 0 - } - -+test_bug_load_flush_load4() -+{ -+ local i -+ -+ setup veth send_"${proto}" set || return ${ksft_skip} -+ -+ for i in $(seq 0 255); do -+ local addelem="add element inet filter test" -+ local j -+ -+ for j in $(seq 0 20); do -+ echo "$addelem { 10.$j.0.$i . 10.$j.1.$i }" -+ echo "$addelem { 10.$j.0.$i . 10.$j.2.$i }" -+ done -+ done > "$tmp" -+ -+ nft -f "$tmp" || return 1 -+ -+ ( echo "flush set inet filter test";cat "$tmp") | nft -f - -+ [ $? -eq 0 ] || return 1 -+ -+ return 0 -+} -+ -+test_bug_load_flush_load8() -+{ -+ local i -+ -+ setup veth send_"${proto}" set || return ${ksft_skip} -+ -+ for i in $(seq 1 100); do -+ echo "add element inet filter test { 10.0.0.$i . 10.0.1.$i }" -+ echo "add element inet filter test { 10.0.0.$i . 10.0.2.$i }" -+ done > "$tmp" -+ -+ nft -f "$tmp" || return 1 -+ -+ ( echo "flush set inet filter test";cat "$tmp") | nft -f - -+ [ $? -eq 0 ] || return 1 -+ -+ return 0 -+} -+ - test_reported_issues() { - eval test_bug_"${subtest}" - } diff --git a/1176-netfilter-nf-conntrack-expect-store-master-tuple-in-expectation.patch b/1176-netfilter-nf-conntrack-expect-store-master-tuple-in-expectation.patch deleted file mode 100644 index a36e06c9e..000000000 --- a/1176-netfilter-nf-conntrack-expect-store-master-tuple-in-expectation.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 979c13114c0bb6ab9135e2c93e00c79c412aef09 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Mon, 22 Jun 2026 21:35:14 +0200 -Subject: [PATCH] netfilter: nf_conntrack_expect: store master_tuple in - expectation - -Store master conntrack tuple in the expectation since exp->master might -refer to a different conntrack when accessed from rcu read side lock -area due to typesafe rcu rules. - -Fixes: 02a3231b6d82 ("netfilter: nf_conntrack_expect: store netns and zone in expectation") -Signed-off-by: Pablo Neira Ayuso - -diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h -index 80f50fd..ec4dd61 100644 ---- a/include/net/netfilter/nf_conntrack_expect.h -+++ b/include/net/netfilter/nf_conntrack_expect.h -@@ -22,16 +22,10 @@ struct nf_conntrack_expect { - /* Hash member */ - struct hlist_node hnode; - -- /* Network namespace */ -- possible_net_t net; -- - /* We expect this tuple, with the following mask */ - struct nf_conntrack_tuple tuple; - struct nf_conntrack_tuple_mask mask; - --#ifdef CONFIG_NF_CONNTRACK_ZONES -- struct nf_conntrack_zone zone; --#endif - /* Usage count. */ - refcount_t use; - -@@ -48,9 +42,6 @@ struct nf_conntrack_expect { - /* Helper that created this expectation */ - struct nf_conntrack_helper __rcu *helper; - -- /* Helper to assign to new connection */ -- struct nf_conntrack_helper __rcu *assign_helper; -- - /* The conntrack of the master connection */ - struct nf_conn *master; - -@@ -67,6 +58,15 @@ struct nf_conntrack_expect { - #endif - - struct rcu_head rcu; -+ -+/* Network namespace */ -+ RH_KABI_EXTEND(possible_net_t net) -+#ifdef CONFIG_NF_CONNTRACK_ZONES -+ RH_KABI_EXTEND(struct nf_conntrack_zone zone) -+#endif -+ /* Helper to assign to new connection */ -+ RH_KABI_EXTEND(struct nf_conntrack_helper __rcu *assign_helper) -+ RH_KABI_EXTEND(struct nf_conntrack_tuple master_tuple) - }; - - static inline struct net *nf_ct_exp_net(struct nf_conntrack_expect *exp) -diff --git a/net/netfilter/nf_conntrack_broadcast.c b/net/netfilter/nf_conntrack_broadcast.c -index 75e53fd..46218c7 100644 ---- a/net/netfilter/nf_conntrack_broadcast.c -+++ b/net/netfilter/nf_conntrack_broadcast.c -@@ -59,6 +59,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, - if (exp == NULL) - goto out; - -+ exp->master_tuple = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; - exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; - - helper = rcu_dereference(help->helper); -diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c -index 1bb5bf8..9f74935 100644 ---- a/net/netfilter/nf_conntrack_expect.c -+++ b/net/netfilter/nf_conntrack_expect.c -@@ -352,6 +352,8 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class, - exp->tuple.src.l3num = family; - exp->tuple.dst.protonum = proto; - -+ exp->master_tuple = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; -+ - if (saddr) { - memcpy(&exp->tuple.src.u3, saddr, len); - if (sizeof(exp->tuple.src.u3) > len) -diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c -index b375374..8d69397 100644 ---- a/net/netfilter/nf_conntrack_netlink.c -+++ b/net/netfilter/nf_conntrack_netlink.c -@@ -3027,7 +3027,6 @@ static int - ctnetlink_exp_dump_expect(struct sk_buff *skb, - const struct nf_conntrack_expect *exp) - { -- struct nf_conn *master = exp->master; - long timeout = ((long)exp->timeout.expires - (long)jiffies) / HZ; - struct nf_conntrack_helper *helper; - #if IS_ENABLED(CONFIG_NF_NAT) -@@ -3043,9 +3042,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, - goto nla_put_failure; - if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0) - goto nla_put_failure; -- if (ctnetlink_exp_dump_tuple(skb, -- &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple, -- CTA_EXPECT_MASTER) < 0) -+ if (ctnetlink_exp_dump_tuple(skb, &exp->master_tuple, CTA_EXPECT_MASTER) < 0) - goto nla_put_failure; - - #if IS_ENABLED(CONFIG_NF_NAT) -@@ -3058,9 +3055,9 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, - if (nla_put_be32(skb, CTA_EXPECT_NAT_DIR, htonl(exp->dir))) - goto nla_put_failure; - -- nat_tuple.src.l3num = nf_ct_l3num(master); -+ nat_tuple.src.l3num = exp->master_tuple.src.l3num; - nat_tuple.src.u3 = exp->saved_addr; -- nat_tuple.dst.protonum = nf_ct_protonum(master); -+ nat_tuple.dst.protonum = exp->master_tuple.dst.protonum; - nat_tuple.src.u = exp->saved_proto; - - if (ctnetlink_exp_dump_tuple(skb, &nat_tuple, -@@ -3606,6 +3603,7 @@ ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, - #endif - rcu_assign_pointer(exp->helper, helper); - rcu_assign_pointer(exp->assign_helper, assign_helper); -+ exp->master_tuple = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; - exp->tuple = *tuple; - exp->mask.src.u3 = mask->src.u3; - exp->mask.src.u.all = mask->src.u.all; diff --git a/1177-accel-ivpu-fix-signed-integer-truncation-in-ipc-receive.patch b/1177-accel-ivpu-fix-signed-integer-truncation-in-ipc-receive.patch deleted file mode 100644 index 82451f890..000000000 --- a/1177-accel-ivpu-fix-signed-integer-truncation-in-ipc-receive.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 4788556d4dd9d717037e385de178974e9649231d Mon Sep 17 00:00:00 2001 -From: Andrzej Kacprowski -Date: Mon, 1 Jun 2026 18:16:43 +0200 -Subject: [PATCH] accel/ivpu: Fix signed integer truncation in IPC receive - -commit d9faef564438d1e4579c692c046603e7ada7bdf4 upstream. - -Fix potential buffer overflow where firmware-supplied data_size is cast -to signed int before being used in min_t(). Large unsigned values -(>= 0x80000000) become negative, causing unsigned wraparound and -oversized memcpy operations that can overflow the stack buffer. - -Change min_t(int, ...) to min() as both values are unsigned and can be -handled by min() without explicit cast. - -Fixes: 3b434a3445ff ("accel/ivpu: Use threaded IRQ to handle JOB done messages") -Cc: stable@vger.kernel.org # v6.12+ -Signed-off-by: Andrzej Kacprowski -Reviewed-by: Karol Wachowski -Signed-off-by: Karol Wachowski -Link: https://patch.msgid.link/20260601161643.229342-1-andrzej.kacprowski@linux.intel.com -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c -index 5f00809..7fea203 100644 ---- a/drivers/accel/ivpu/ivpu_ipc.c -+++ b/drivers/accel/ivpu/ivpu_ipc.c -@@ -276,7 +276,7 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, - if (ipc_buf) - memcpy(ipc_buf, rx_msg->ipc_hdr, sizeof(*ipc_buf)); - if (rx_msg->jsm_msg) { -- u32 size = min_t(int, rx_msg->ipc_hdr->data_size, sizeof(*jsm_msg)); -+ u32 size = min(rx_msg->ipc_hdr->data_size, sizeof(*jsm_msg)); - - if (rx_msg->jsm_msg->result != VPU_JSM_STATUS_SUCCESS) { - ivpu_err(vdev, "IPC resp result error: %d\n", rx_msg->jsm_msg->result); diff --git a/1178-kvm-nvmx-put-vmcs12-pages-if-nested-vm-enter-fails-due-to-invalid-guest-state.patch b/1178-kvm-nvmx-put-vmcs12-pages-if-nested-vm-enter-fails-due-to-invalid-guest-state.patch deleted file mode 100644 index 3544294fd..000000000 --- a/1178-kvm-nvmx-put-vmcs12-pages-if-nested-vm-enter-fails-due-to-invalid-guest-state.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 6992f3340e823bbac7290990fb50008cda860209 Mon Sep 17 00:00:00 2001 -From: Aidan Wallace -Date: Wed, 22 Jul 2026 00:14:03 -0500 -Subject: [PATCH] KVM: nVMX: Put vmcs12 pages if nested VM-Enter fails due to - invalid guest state - -JIRA: https://redhat.atlassian.net/browse/RHEL-213327 - -KVM: nVMX: Put vmcs12 pages if nested VM-Enter fails due to invalid guest state - -Put all vmcs12 pages if KVM synthesizes a nested VM-Exit due to invalid -guest while emulating VMLAUNCH or VMRESUME. The invalid guest state path -doesn't use nested_vmx_vmexit() as that API is intended to be used if and -only if L2 is active, and the open coded equivalent neglects to put the -vmcs12 pages. Failure to put the vmcs12 pages leaks any pinned pages -(and/or mappings) if L1 retries VMLAUNCH/VMRESUME. - -Note, the !from_vmenter scenario doesn't suffer the same problem, as -vmx_get_nested_state_pages() only gets/pins/maps the vmcs12 pages if L2 is -active, i.e. if a "full" VM-Exit is guaranteed before KVM will retry -getting vmcs12 pages. - -Fixes: 96c66e87deee ("KVM/nVMX: Use kvm_vcpu_map when mapping the virtual APIC page") -Fixes: 3278e0492554 ("KVM/nVMX: Use kvm_vcpu_map when mapping the posted interrupt descriptor table") -Fixes: fe1911aa443e ("KVM: nVMX: Use kvm_vcpu_map() to get/pin vmcs12's APIC-access page") -Reported-by: Minh Nguyen -Cc: stable@vger.kernel.org -Signed-off-by: Sean Christopherson -Signed-off-by: Paolo Bonzini -(cherry picked from commit 2f2312c422fd2695da772cecb30c69994b795964) -Signed-off-by: Aidan Wallace - -diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c -index 7c55551..5570e0c 100644 ---- a/arch/x86/kvm/vmx/nested.c -+++ b/arch/x86/kvm/vmx/nested.c -@@ -3661,6 +3661,8 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, - if (!from_vmentry) - return NVMX_VMENTRY_VMEXIT; - -+ nested_put_vmcs12_pages(vcpu); -+ - load_vmcs12_host_state(vcpu, vmcs12); - vmcs12->vm_exit_reason = exit_reason.full; - if (enable_shadow_vmcs || nested_vmx_is_evmptr12_valid(vmx)) diff --git a/1179-kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch b/1179-kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch deleted file mode 100644 index 132abd16a..000000000 --- a/1179-kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 45246f884605223c7ab63808e12c973c63aba44e Mon Sep 17 00:00:00 2001 -From: Aidan Wallace -Date: Wed, 22 Jul 2026 00:15:53 -0500 -Subject: [PATCH] KVM: x86: Check for invalid/obsolete root *after* making MMU - pages available - -JIRA: https://redhat.atlassian.net/browse/RHEL-213327 - -KVM: x86: Check for invalid/obsolete root *after* making MMU pages available - -Check for a "stale" page fault, i.e. for an invalid and/or obsolete root, -after making MMU pages available for the shadow MMU. If reclaiming shadow -pages zaps an in-use root, i.e. marks it invalid, then KVM will attempt to -map memory into an invalid root. On its own, populating an invalid root is -"fine", but because child shadow pages inherit their parent's role, any -children created during the map/fetch will be created as invalid pages, -thus violating KVM's invariant that invalid pages are never on the list of -active MMU pages. - -Note, the underlying flaw has existed since KVM first started tracking -invalid roots in 2008 (commit 2e53d63acba7, "KVM: MMU: ignore zapped root -pagetables"), but the true badness only came along in 2020 (Linux 5.9) -with the invariant that invalid shadow pages can't be on the list of -active pages. - -Note #2, inheriting role.invalid when creating child shadow pages is also -far from ideal; that flaw will be addressed separately. - -Reported-by: Hyunwoo Kim -Fixes: f95eec9bed76 ("KVM: x86/mmu: Don't put invalid SPs back on the list of active pages") -Cc: stable@vger.kernel.org -Signed-off-by: Sean Christopherson -Signed-off-by: Paolo Bonzini -(cherry picked from commit 2abd5287f08319fa35764566b15c6e22cb1068db) -Signed-off-by: Aidan Wallace - -diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index 6415891..ce15356 100644 ---- a/arch/x86/kvm/mmu/mmu.c -+++ b/arch/x86/kvm/mmu/mmu.c -@@ -4788,16 +4788,17 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault - if (r != RET_PF_CONTINUE) - return r; - -- r = RET_PF_RETRY; - write_lock(&vcpu->kvm->mmu_lock); - -- if (is_page_fault_stale(vcpu, fault)) -- goto out_unlock; -- - r = make_mmu_pages_available(vcpu); - if (r) - goto out_unlock; - -+ if (is_page_fault_stale(vcpu, fault)) { -+ r = RET_PF_RETRY; -+ goto out_unlock; -+ } -+ - r = direct_map(vcpu, fault); - - out_unlock: -diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h -index ed762bb..af220c9 100644 ---- a/arch/x86/kvm/mmu/paging_tmpl.h -+++ b/arch/x86/kvm/mmu/paging_tmpl.h -@@ -827,15 +827,17 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault - } - #endif - -- r = RET_PF_RETRY; - write_lock(&vcpu->kvm->mmu_lock); - -- if (is_page_fault_stale(vcpu, fault)) -- goto out_unlock; -- - r = make_mmu_pages_available(vcpu); - if (r) - goto out_unlock; -+ -+ if (is_page_fault_stale(vcpu, fault)) { -+ r = RET_PF_RETRY; -+ goto out_unlock; -+ } -+ - r = FNAME(fetch)(vcpu, fault, &walker); - - out_unlock: diff --git a/1180-kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch b/1180-kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch deleted file mode 100644 index 42d767de0..000000000 --- a/1180-kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 665c3ad7f18b63fba85a93250a75d44a5454734d Mon Sep 17 00:00:00 2001 -From: Aidan Wallace -Date: Wed, 22 Jul 2026 00:43:20 -0500 -Subject: [PATCH] KVM: nVMX: Hide shadow VMCS right after VMCLEAR - -JIRA: https://redhat.atlassian.net/browse/RHEL-213327 - -KVM: nVMX: Hide shadow VMCS right after VMCLEAR - -free_nested() frees the shadow VMCS while vmcs01 still points to it. But -because it is asynchronous with respect to loaded_vmcs_clear(), the vCPU -might migrate before the pointer is cleared and __loaded_vmcs_clear() -may then execute VMCLEAR. - -The VMCS needs to stay attached until its explicit VMCLEAR completes, but -then it can be hidden and the page safely freed. - -Fixes: 355f4fb1405e ("kvm: nVMX: VMCLEAR an active shadow VMCS after last use") -Cc: stable@vger.kernel.org -Signed-off-by: Hyunwoo Kim -Signed-off-by: Paolo Bonzini -(cherry picked from commit 622ebfac01ba4f9c0060cebd41257fe46fc4a0b3) -Signed-off-by: Aidan Wallace - -diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c -index 5570e0c..49d7cda 100644 ---- a/arch/x86/kvm/vmx/nested.c -+++ b/arch/x86/kvm/vmx/nested.c -@@ -331,6 +331,7 @@ static void nested_put_vmcs12_pages(struct kvm_vcpu *vcpu) - static void free_nested(struct kvm_vcpu *vcpu) - { - struct vcpu_vmx *vmx = to_vmx(vcpu); -+ struct vmcs *shadow_vmcs; - - if (WARN_ON_ONCE(vmx->loaded_vmcs != &vmx->vmcs01)) - vmx_switch_vmcs(vcpu, &vmx->vmcs01); -@@ -348,9 +349,15 @@ static void free_nested(struct kvm_vcpu *vcpu) - vmx->nested.current_vmptr = INVALID_GPA; - if (enable_shadow_vmcs) { - vmx_disable_shadow_vmcs(vmx); -- vmcs_clear(vmx->vmcs01.shadow_vmcs); -- free_vmcs(vmx->vmcs01.shadow_vmcs); -+ -+ /* -+ * Keep the pointer visible until after VMCLEAR, so migration -+ * can clear an active shadow VMCS on the old CPU. -+ */ -+ shadow_vmcs = vmx->vmcs01.shadow_vmcs; -+ vmcs_clear(shadow_vmcs); - vmx->vmcs01.shadow_vmcs = NULL; -+ free_vmcs(shadow_vmcs); - } - kfree(vmx->nested.cached_vmcs12); - vmx->nested.cached_vmcs12 = NULL; diff --git a/1181-kvm-x86-mmu-ensure-hugepage-is-in-by-slot-before-checking-max-mapping-level.patch b/1181-kvm-x86-mmu-ensure-hugepage-is-in-by-slot-before-checking-max-mapping-level.patch deleted file mode 100644 index fa004dbdd..000000000 --- a/1181-kvm-x86-mmu-ensure-hugepage-is-in-by-slot-before-checking-max-mapping-level.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 25252dcdc03485bdfaaf4ff5bae084b5e6176ac0 Mon Sep 17 00:00:00 2001 -From: Aidan Wallace -Date: Wed, 22 Jul 2026 01:05:50 -0500 -Subject: [PATCH] KVM: x86/mmu: Ensure hugepage is in by slot before checking - max mapping level - -JIRA: https://redhat.atlassian.net/browse/RHEL-213327 -CVE: CVE-2026-63807 - -KVM: x86/mmu: Ensure hugepage is in by slot before checking max mapping level - -When recovering hugepages in the shadow MMU, verify that the base gfn of -the shadow page is actually contained within the target memslot, *before* -querying the max mapping level given the shadow page's gfn. Failure to -pre-check the validity of the gfn can lead to an out-of-bounds access to -the slot's lpage_info (which typically manifests as a host #PF because the -lpage_info is vmalloc'd) if the guest creates a hugepage mapping (in its -PTEs) that extends "below" the bounds of a memslot. - -When faulting in memory for a guest, and the size of the guest mapping is -greater than KVM's (current) max mapping, then KVM will create a "direct" -shadow page (direct in that there are no gPTEs to shadow, and so the target -gfn is a direct calculation given the base gfn of the shadow page). The -hugepage recovery flow looks for such direct shadow pages, as forcing 4KiB -mappings when dirty logging generates the guest > host mapping size case. -When the 4KiB restriction is lifted, then KVM can replace the shadow page -with a hugepage. - -But if KVM originally used a smaller mapping than the guest because the -range of memory covered by the guest hugepage exceeds the bounds of a -memslot, then KVM will link a direct shadow page with a gfn that is outside -the bounds of the memslot being used to fault in memory. The rmap entry -added for the leaf mapping is correct and within bounds, but the gfn of the -leaf SPTE's parent shadow page will be out of bounds. - - BUG: unable to handle page fault for address: ffffc90000806ffc - #PF: supervisor read access in kernel mode - #PF: error_code(0x0000) - not-present page - PGD 100000067 P4D 100000067 PUD 1002a7067 PMD 10612f067 PTE 0 - Oops: Oops: 0000 [#1] SMP - CPU: 13 UID: 1000 PID: 757 Comm: mmu_stress_test Not tainted 7.1.0-rc1-48ce1e26eace-x86_pir_to_irr_comments-vm #341 PREEMPT - Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 - RIP: 0010:kvm_mmu_max_mapping_level+0x79/0x2b0 [kvm] - Call Trace: - - kvm_mmu_recover_huge_pages+0x21b/0x320 [kvm] - kvm_set_memslot+0x1ee/0x590 [kvm] - kvm_set_memory_region.part.0+0x3a1/0x4d0 [kvm] - kvm_vm_ioctl+0x9bf/0x15d0 [kvm] - __x64_sys_ioctl+0x8a/0xd0 - do_syscall_64+0xb7/0xbb0 - entry_SYSCALL_64_after_hwframe+0x4b/0x53 - RIP: 0033:0x7f21c0f1a9bf - - -Don't bother pre-checking the bounds of the potential hugepage, i.e. don't -check that e.g. sp->gfn + KVM_PAGES_PER_HPAGE(sp->role.level + 1) is also -within the memslot, as the checks performed by kvm_mmu_max_mapping_level() -are a superset of the basic bounds checks. I.e. pre-checking the full -range would be a dubious micro-optimization. - -Fixes: 9eba50f8d7fc ("KVM: x86/mmu: Consult max mapping level when zapping collapsible SPTEs") -Cc: stable@vger.kernel.org -Cc: David Matlack -Cc: James Houghton -Cc: Alexander Bulekov -Cc: Fred Griffoul -Cc: Alexander Graf -Cc: David Woodhouse -Cc: Filippo Sironi -Cc: Ivan Orlov -Signed-off-by: Sean Christopherson -Signed-off-by: Paolo Bonzini -(cherry picked from commit ef057cbf825e03b63f6edf5980f96abf3c53089d) -Signed-off-by: Aidan Wallace - -diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index ce15356..04591cf 100644 ---- a/arch/x86/kvm/mmu/mmu.c -+++ b/arch/x86/kvm/mmu/mmu.c -@@ -7163,13 +7163,19 @@ static bool kvm_mmu_zap_collapsible_spte(struct kvm *kvm, - sp = sptep_to_sp(sptep); - - /* -- * We cannot do huge page mapping for indirect shadow pages, -- * which are found on the last rmap (level = 1) when not using -- * tdp; such shadow pages are synced with the page table in -- * the guest, and the guest page table is using 4K page size -- * mapping if the indirect sp has level = 1. -+ * Direct shadow page can be replaced by a hugepage if the host -+ * mapping level allows it and the memslot maps all of the host -+ * hugepage. Note! If the memslot maps only part of the -+ * hugepage, sp->gfn may be below slot->base_gfn, and querying -+ * the max mapping level would cause an out-of-bounds lpage_info -+ * access. So the gfn bounds check *must* be done first. -+ * -+ * Indirect shadow pages are created when the guest page tables -+ * are using 4K pages. Since the host mapping is always -+ * constrained by the page size in the guest, indirect shadow -+ * pages are never collapsible. - */ -- if (sp->role.direct && -+ if (sp->role.direct && is_gfn_in_memslot(slot, sp->gfn) && - sp->role.level < kvm_mmu_max_mapping_level(kvm, slot, sp->gfn)) { - kvm_zap_one_rmap_spte(kvm, rmap_head, sptep); - -diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index 83ed7a0..2790aed 100644 ---- a/include/linux/kvm_host.h -+++ b/include/linux/kvm_host.h -@@ -1768,6 +1768,11 @@ void kvm_unregister_irq_ack_notifier(struct kvm *kvm, - struct kvm_irq_ack_notifier *kian); - bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args); - -+static inline bool is_gfn_in_memslot(const struct kvm_memory_slot *slot, gfn_t gfn) -+{ -+ return gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages; -+} -+ - /* - * Returns a pointer to the memslot if it contains gfn. - * Otherwise returns NULL. -@@ -1778,7 +1783,7 @@ try_get_memslot(struct kvm_memory_slot *slot, gfn_t gfn) - if (!slot) - return NULL; - -- if (gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages) -+ if (is_gfn_in_memslot(slot, gfn)) - return slot; - else - return NULL; diff --git a/1182-kvm-x86-hyper-v-validate-all-gvas-during-pv-tlb-flush.patch b/1182-kvm-x86-hyper-v-validate-all-gvas-during-pv-tlb-flush.patch deleted file mode 100644 index 143bcf109..000000000 --- a/1182-kvm-x86-hyper-v-validate-all-gvas-during-pv-tlb-flush.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 8b624c005e6d08f4ee577aa8beb4852420d57c3f Mon Sep 17 00:00:00 2001 -From: Maxim Levitsky -Date: Fri, 24 Apr 2026 11:43:56 -0400 -Subject: [PATCH] KVM: x86: hyper-v: Validate all GVAs during PV TLB flush - -JIRA: https://issues.redhat.com/browse/RHEL-151869 - -commit a5264387c2ee42fca92ac792199008fc60ee82f1 -Author: Manuel Andreas -Date: Thu Feb 19 21:05:49 2026 +0100 - - KVM: x86: hyper-v: Validate all GVAs during PV TLB flush - - In KVM guests with Hyper-V hypercalls enabled, the hypercalls - HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST and HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX - allow a guest to request invalidation of portions of a virtual TLB. - For this, the hypercall parameter includes a list of GVAs that are supposed - to be invalidated. - - Currently, only the base GVA is checked to be canonical. In reality, this - check needs to be performed for the entire range of GVAs, as checking only - the base GVA enables guests running on Intel hardware to trigger a - WARN_ONCE in the host (see Fixes commit below). - - Move the check for non-canonical addresses to be performed for every GVA - of the supplied range to avoid the splat, and to be more in line with the - Hyper-V specification, since, although unlikely, a range starting with an - invalid GVA may still contain GVAs that are valid. - - Fixes: fa787ac07b3c ("KVM: x86/hyper-v: Skip non-canonical addresses during PV TLB flush") - Signed-off-by: Manuel Andreas - Reviewed-by: Vitaly Kuznetsov - Link: https://patch.msgid.link/00a7a31b-573b-4d92-91f8-7d7e2f88ea48@tum.de - [sean: massage changelog] - Signed-off-by: Sean Christopherson - Signed-off-by: Paolo Bonzini - -Signed-off-by: Maxim Levitsky - -diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c -index 75cd48d..4ea49a4 100644 ---- a/arch/x86/kvm/hyperv.c -+++ b/arch/x86/kvm/hyperv.c -@@ -1983,16 +1983,17 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu) - if (entries[i] == KVM_HV_TLB_FLUSHALL_ENTRY) - goto out_flush_all; - -- if (is_noncanonical_invlpg_address(entries[i], vcpu)) -- continue; -- - /* - * Lower 12 bits of 'address' encode the number of additional - * pages to flush. - */ - gva = entries[i] & PAGE_MASK; -- for (j = 0; j < (entries[i] & ~PAGE_MASK) + 1; j++) -+ for (j = 0; j < (entries[i] & ~PAGE_MASK) + 1; j++) { -+ if (is_noncanonical_invlpg_address(gva + j * PAGE_SIZE, vcpu)) -+ continue; -+ - kvm_x86_call(flush_tlb_gva)(vcpu, gva + j * PAGE_SIZE); -+ } - - ++vcpu->stat.tlb_flush; - } diff --git a/1183-kvm-svm-make-svm-flush-tlb-gva-do-a-full-asid-flush-if-npt-enabled.patch b/1183-kvm-svm-make-svm-flush-tlb-gva-do-a-full-asid-flush-if-npt-enabled.patch deleted file mode 100644 index 7602c88ca..000000000 --- a/1183-kvm-svm-make-svm-flush-tlb-gva-do-a-full-asid-flush-if-npt-enabled.patch +++ /dev/null @@ -1,217 +0,0 @@ -From 26505e1b5b546e2fa9a0296b951ca158460c72d8 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Thu, 23 Jul 2026 10:15:22 +0200 -Subject: [PATCH] KVM: SVM: make svm_flush_tlb_gva do a full asid flush if NPT - enabled - -Red Hat is seeing multiple reports of Windows memory corruptions -(and consequent BSODs) with hv-tlbflush=on, on AMD processors only. -The crashes, while extremely rare, happen even with a stock configuration, -but with Driver Verifier enabled they can be detected after approximately -200 VM hours. In particular, Alexander Lougovski measured the following: - -- on AMD Turin, 15 crashes in 3300 VM hours - -- on AMD Milan, 2 crashes in 500 VM hours (there are fewer hours - here due to the host being smaller) - -- on Intel Sapphire Rapids, 0 crashes in 8000 VM hours - -- on AMD Turin with full TLB flush (not exactly this patch but - similar), no crashes in ~2 weeks of run time which should also - be ~7000 VM hours - -For Turin, the microcode version was 0x0b002162, which (assuming -this is the same issue) should not be affected by the problem listed in -https://knowledge.broadcom.com/external/article/419026/bsod-on-virtual-machines-running-on-amd.html; -on the other hand that problem should not apply to earlier processors. -AMD has not provided any information or analysis yet, and when we asked -we didn't know yet that it reproduced on Milan as well. - -As to the workload, Alexander threw more or less everything at the same -time at the VM: - -- a full Windows Defender scan every 30 minutes - -- a disk I/O job - -- a loop doing repeated mmap of system files (mostly to hope that - it triggers some consistency check in the Windows memory manager) - -- SQL Express 2022 + StressDB (1.6M rows), with the host doing queries - (75% write/25% read) via sqlcmd - -Driver Verifier is able to detect BSODs more or less at the same time as -the pages are freed. They mostly happen in the Windows Defender filter -driver, but occasionally also in the networking stack (e.g., afd.sys) -or elsewhere in the filesystem stack (e.g., fltmgr.sys). - -The flush is issued from kvm_hv_vcpu_flush_tlb(), which receives the -cross-CPU requests from the Hyper-V TLB flush hypercalls via a kfifo -and is invoked by the KVM_REQ_HV_TLB_FLUSH request. The mechanism is -the same for both Intel and AMD, and the handler for both vendors is -a simple INVVPID(ADDR)/INVLPGA instruction. - -Because the request is handled on the destination CPU, there is a question -of what happens if the VM is migrated across physical CPUs. In that case, -the INVLPGA instruction would use a stale svm->vmcb->control.asid; but -if anything that might do an *unnecessary* flush (on an asid that's being -used for another VM) and then pre_svm_run() would force a full TLB rebuild. - -So, for lack of better ideas, this patch forces a full ASID bump in -svm_flush_tlb_gva(). To avoid paying the price on Intel and also to -avoid unnecessary loops on AMD, the flush_tlb_gva op now returns whether -it did a full flush or not; kvm_hv_vcpu_flush_tlb() takes note and exits -its loops immediately. While there is an obvious performance impact, -about half of the benefit from Hyper-V tlbflush is preserved (10% vs. 20% -on the SQL Server workload). - -kvm_mmu_invalidate_addr() is the only other caller of the flush_tlb_gva op. -The change would have a performance impact on every intercepted INVLPG and, -for nested SVM, on every L1 INVLPGA. For INVLPGA specifically, this covers -the same suspected issue but for nested hypervisors, so it is correct to -apply the workaround; for INVLPG on shadow paging, instead, the impact -would be stronger and, due to lack of data, for now the use of INVLPGA is -left in place in svm_flush_tlb_gva(). - -Analyzed-by: Vitaly Kuznetsov -Analyzed-by: Alexander Lougovski -Signed-off-by: Paolo Bonzini - -diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h -index 871c7ff..d378cdf 100644 ---- a/arch/x86/include/asm/kvm_host.h -+++ b/arch/x86/include/asm/kvm_host.h -@@ -1761,7 +1761,7 @@ struct kvm_x86_ops { - * Can potentially get non-canonical addresses through INVLPGs, which - * the implementation may choose to ignore if appropriate. - */ -- void (*flush_tlb_gva)(struct kvm_vcpu *vcpu, gva_t addr); -+ void (*flush_tlb_gva)(struct kvm_vcpu *vcpu, gva_t addr, bool *full); - - /* - * Flush any TLB entries created by the guest. Like tlb_flush_gva(), -diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c -index 4ea49a4..861a5d8 100644 ---- a/arch/x86/kvm/hyperv.c -+++ b/arch/x86/kvm/hyperv.c -@@ -1971,6 +1971,7 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu) - u64 entries[KVM_HV_TLB_FLUSH_FIFO_SIZE]; - int i, j, count; - gva_t gva; -+ bool full = false; - - if (!tdp_enabled || !hv_vcpu) - return -EINVAL; -@@ -1979,7 +1980,7 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu) - - count = kfifo_out(&tlb_flush_fifo->entries, entries, KVM_HV_TLB_FLUSH_FIFO_SIZE); - -- for (i = 0; i < count; i++) { -+ for (i = 0; i < count && !full; i++) { - if (entries[i] == KVM_HV_TLB_FLUSHALL_ENTRY) - goto out_flush_all; - -@@ -1988,11 +1989,11 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu) - * pages to flush. - */ - gva = entries[i] & PAGE_MASK; -- for (j = 0; j < (entries[i] & ~PAGE_MASK) + 1; j++) { -+ for (j = 0; j < (entries[i] & ~PAGE_MASK) + 1 && !full; j++) { - if (is_noncanonical_invlpg_address(gva + j * PAGE_SIZE, vcpu)) - continue; - -- kvm_x86_call(flush_tlb_gva)(vcpu, gva + j * PAGE_SIZE); -+ kvm_x86_call(flush_tlb_gva)(vcpu, gva + j * PAGE_SIZE, &full); - } - - ++vcpu->stat.tlb_flush; -diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index 04591cf..66bda34 100644 ---- a/arch/x86/kvm/mmu/mmu.c -+++ b/arch/x86/kvm/mmu/mmu.c -@@ -6434,7 +6434,7 @@ void kvm_mmu_invalidate_addr(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, - if (is_noncanonical_invlpg_address(addr, vcpu)) - return; - -- kvm_x86_call(flush_tlb_gva)(vcpu, addr); -+ kvm_x86_call(flush_tlb_gva)(vcpu, addr, NULL); - } - - if (!mmu->sync_spte) -diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c -index 23cb4be..4b80716 100644 ---- a/arch/x86/kvm/svm/svm.c -+++ b/arch/x86/kvm/svm/svm.c -@@ -4021,11 +4021,24 @@ static void svm_flush_tlb_all(struct kvm_vcpu *vcpu) - svm_flush_tlb_asid(vcpu); - } - --static void svm_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t gva) -+static void svm_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t gva, bool *full) - { - struct vcpu_svm *svm = to_svm(vcpu); - -- invlpga(gva, svm->vmcb->control.asid); -+ /* -+ * INVLPGA has had errata on Genoa and Turin, and even on older -+ * generations there were reports of Windows BSODs if INVLPGA -+ * was used for Hyper-V tlbflush. Use it only for shadow paging -+ * where it seems to be okay. -+ */ -+ if (!npt_enabled) { -+ invlpga(gva, svm->vmcb->control.asid); -+ return; -+ } -+ -+ svm_flush_tlb_asid(vcpu); -+ if (full) -+ *full = true; - } - - static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu) -diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c -index dbab1c1..f99cae0 100644 ---- a/arch/x86/kvm/vmx/main.c -+++ b/arch/x86/kvm/vmx/main.c -@@ -530,12 +530,12 @@ static void vt_flush_tlb_current(struct kvm_vcpu *vcpu) - vmx_flush_tlb_current(vcpu); - } - --static void vt_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr) -+static void vt_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr, bool *full) - { - if (is_td_vcpu(vcpu)) - return; - -- vmx_flush_tlb_gva(vcpu, addr); -+ vmx_flush_tlb_gva(vcpu, addr, full); - } - - static void vt_flush_tlb_guest(struct kvm_vcpu *vcpu) -diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c -index 2e68776..5fd9614 100644 ---- a/arch/x86/kvm/vmx/vmx.c -+++ b/arch/x86/kvm/vmx/vmx.c -@@ -3202,7 +3202,7 @@ void vmx_flush_tlb_current(struct kvm_vcpu *vcpu) - vpid_sync_context(vmx_get_current_vpid(vcpu)); - } - --void vmx_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr) -+void vmx_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr, bool *full) - { - /* - * vpid_sync_vcpu_addr() is a nop if vpid==0, see the comment in -diff --git a/arch/x86/kvm/vmx/x86_ops.h b/arch/x86/kvm/vmx/x86_ops.h -index 2b3424f..5fa4e7c 100644 ---- a/arch/x86/kvm/vmx/x86_ops.h -+++ b/arch/x86/kvm/vmx/x86_ops.h -@@ -82,7 +82,7 @@ void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags); - bool vmx_get_if_flag(struct kvm_vcpu *vcpu); - void vmx_flush_tlb_all(struct kvm_vcpu *vcpu); - void vmx_flush_tlb_current(struct kvm_vcpu *vcpu); --void vmx_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr); -+void vmx_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t addr, bool *full); - void vmx_flush_tlb_guest(struct kvm_vcpu *vcpu); - void vmx_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask); - u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu); diff --git a/1184-net-sched-act-api-use-rcu-with-deferred-freeing-for-action-lifecycle.patch b/1184-net-sched-act-api-use-rcu-with-deferred-freeing-for-action-lifecycle.patch deleted file mode 100644 index d637a5e80..000000000 --- a/1184-net-sched-act-api-use-rcu-with-deferred-freeing-for-action-lifecycle.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 5dd51e09020c65aa53cf128e5e3517cd53b3c113 Mon Sep 17 00:00:00 2001 -From: Jamal Hadi Salim -Date: Sun, 31 May 2026 12:08:12 -0400 -Subject: [PATCH] net/sched: act_api: use RCU with deferred freeing for action - lifecycle - -[ Upstream commit 5057e1aca011e51ef51498c940ef96f3d3e8a305 ] - -When NEWTFILTER and DELFILTER are run concurrently it is possible to create a -race with an associated action. - -Let's illustrate with CPU0 running NEWTFILTER and CPU1 running DELFILTER: - - 0: mutex_lock() <-- holds the idr lock - 0: rcu_read_lock() - 0: p = idr_find(idr, index) <-- action p is valid (RCU protects IDR) - 0: mutex_unlock() <-- releases the idr lock - 1: refcount_dec_and_mutex_lock() <-- refcnt 1->0, mutex held - 1: idr_remove(idr, index) <-- Action removed from IDR - 1: mutex_unlock() <-- mutex released allowing us to delete the action - 1: tcf_action_cleanup(p); kfree(p) <-- Kfrees p immediately, no deferral - 0: refcount_inc_not_zero(&p->tcfa_refcnt) <-- ouch, UAF p points to freed memory - -This patch fixes the race condition between NEWTFILTER and DELFILTER by -adding struct rcu_head to tc_action used in the deferral and introducing a -call_rcu() in the delete path to defer the final kfree(). - -Note: this is a revert of commit d7fb60b9cafb ("net_sched: get rid of tcfa_rcu") -but also modernization/simplification to directly use kfree_rcu(). - -Let's illustrate the new restored code path: - - 0: rcu_read_lock() - 1: refcount_dec_and_mutex_lock() <-- refcnt 1->0, mutex held - 1: idr_remove(idr, index) - 1: mutex_unlock() - 1: call_rcu(&p->tcfa_rcu, tcf_action_rcu_free) <-- defer kfree after grace period - 0: p = idr_find(idr, index) - 0: refcount_inc_not_zero(&p->tcfa_refcnt) <-- fails, refcnt already 0 - 1: rcu_read_unlock() <-- release so freeing can run after grace period - -After CPU1 calls idr_remove(), the object is no longer reachable through the IDR. -CPU0's subsequent idr_find() will return NULL, and even if it still held a -stale pointer, the immediate kfree() is now deferred until after the RCU grace -period, so no UAF can occur. - -Fixes: d7fb60b9cafb ("net_sched: get rid of tcfa_rcu") -Suggested-by: Jakub Kicinski -Reported-by: Kyle Zeng -Tested-by: Victor Nogueira -Tested-by: syzbot@syzkaller.appspotmail.com -Signed-off-by: Jamal Hadi Salim -Tested-by: Kyle Zeng -Reviewed-by: Pedro Tammela -Reviewed-by: Eric Dumazet -Reviewed-by: Victor Nogueira -Link: https://patch.msgid.link/20260531160812.68020-1-jhs@mojatatu.com -Signed-off-by: Jakub Kicinski -Signed-off-by: Sasha Levin - -diff --git a/net/sched/act_api.c b/net/sched/act_api.c -index 8397900..8b1402c 100644 ---- a/net/sched/act_api.c -+++ b/net/sched/act_api.c -@@ -112,11 +112,6 @@ struct tcf_chain *tcf_action_set_ctrlact(struct tc_action *a, int action, - } - EXPORT_SYMBOL(tcf_action_set_ctrlact); - --/* XXX: For standalone actions, we don't need a RCU grace period either, because -- * actions are always connected to filters and filters are already destroyed in -- * RCU callbacks, so after a RCU grace period actions are already disconnected -- * from filters. Readers later can not find us. -- */ - static void free_tcf(struct tc_action *p) - { - struct tcf_chain *chain = rcu_dereference_protected(p->goto_chain, 1); -@@ -129,7 +124,7 @@ static void free_tcf(struct tc_action *p) - if (chain) - tcf_chain_put_by_act(chain); - -- kfree(p); -+ kfree_rcu_mightsleep(p); - } - - static void offload_action_hw_count_set(struct tc_action *act, diff --git a/1185-perf-aux-fix-page-uaf-in-map-range.patch b/1185-perf-aux-fix-page-uaf-in-map-range.patch deleted file mode 100644 index 330aa2532..000000000 --- a/1185-perf-aux-fix-page-uaf-in-map-range.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 5948aaf64f81f217a25dcc2bf6c0779bca19566c Mon Sep 17 00:00:00 2001 -From: Lee Jia Jie -Date: Thu, 9 Jul 2026 21:56:19 +0800 -Subject: [PATCH] perf/aux: Fix page UAF in map_range() - -map_range() reads rb->aux_pages[], rb->aux_nr_pages and rb->aux_pgoff via -perf_mmap_to_page() while holding only event->mmap_mutex. Those fields are -serialized by rb->aux_mutex, and mmap_mutex is per event. - -Thus, two events sharing one rb via PERF_EVENT_IOC_SET_OUTPUT can race -rb_alloc_aux() with map_range(), leading to a page-UAF scenario as follows: - - CPU 0 CPU 1 - ===== ===== - rb_alloc_aux() map_range() - [1]: allocate rb->aux_pages[0] - [2]: rb->aux_nr_pages++ - [3]: perf_mmap_to_page() - returns rb->aux_pages[0] - [4]: map it as VM_PFNMAP - [5]: rb->aux_pgoff = 1 - - munmap the page - [6]: free rb->aux_pages[0] - -Pages mapped as VM_PFNMAP have no refcount protection, so CPU 1 holds a -mapping to a freed physical frame. - -Fix this by taking rb->aux_mutex across the page walk in map_range(). - -Fixes: b709eb872e19 ("perf: map pages in advance") -Signed-off-by: Lee Jia Jie -Signed-off-by: Ingo Molnar -Cc: stable@vger.kernel.org -Cc: Peter Zijlstra -Cc: Arnaldo Carvalho de Melo -Cc: Namhyung Kim - -diff --git a/kernel/events/core.c b/kernel/events/core.c -index 43cee52..e2e7bb8 100644 ---- a/kernel/events/core.c -+++ b/kernel/events/core.c -@@ -6896,6 +6896,8 @@ static int map_range(struct perf_buffer *rb, struct vm_area_struct *vma) - int err = 0; - unsigned long pagenum; - -+ guard(mutex)(&rb->aux_mutex); -+ - /* - * We map this as a VM_PFNMAP VMA. - * diff --git a/1186-scsi-target-iscsi-bound-iscsi-encode-text-output-appends-to-rsp-buf.patch b/1186-scsi-target-iscsi-bound-iscsi-encode-text-output-appends-to-rsp-buf.patch deleted file mode 100644 index 6c78d27f2..000000000 --- a/1186-scsi-target-iscsi-bound-iscsi-encode-text-output-appends-to-rsp-buf.patch +++ /dev/null @@ -1,200 +0,0 @@ -From cb0d8148eaca238c8ee3e3a1c3351503194ab167 Mon Sep 17 00:00:00 2001 -From: Maurizio Lombardi -Date: Tue, 9 Jun 2026 07:52:02 +0200 -Subject: [PATCH] scsi: target: iscsi: Bound iscsi_encode_text_output() appends - to rsp_buf - -JIRA: https://redhat.atlassian.net/browse/RHEL-163760 - -iscsi_encode_text_output() concatenates "key=value\0" records into -login->rsp_buf, an 8192-byte kzalloc(MAX_KEY_VALUE_PAIRS) buffer -allocated in iscsit_alloc_login_setup_buffer(). The three sprintf() call -sites in this function (lines 1398, 1411, 1424 in v7.1-rc2) never check -the remaining buffer capacity: - - *length += sprintf(output_buf, "%s=%s", er->key, er->value); - *length += 1; - output_buf = textbuf + *length; - -The 8192-byte ceiling at iscsi_target_check_login_request() bounds the -*input* Login PDU payload, but a single PDU can carry up to 2048 minimal -four-byte "a=b\0" pairs, each unknown key expanding to a 16-byte -"a=NotUnderstood\0" output record via iscsi_add_notunderstood_response(). -2048 * 16 = 32 KiB of output into an 8 KiB buffer, producing a ~24 KiB -heap overrun in the kmalloc-8k slab. - -The fix introduces a static iscsi_encode_text_record() helper that uses -snprintf() with a per-call bounds check against the remaining buffer, -and threads a u32 textbuf_size parameter through -iscsi_encode_text_output(). Both call sites in -iscsi_target_handle_csg_zero() (PHASE_SECURITY) and -iscsi_target_handle_csg_one() (PHASE_OPERATIONAL) pass -MAX_KEY_VALUE_PAIRS. On overflow the encoder logs the condition, calls -iscsi_release_extra_responses() to drop queued records, and returns -1; -both caller sites now emit ISCSI_STATUS_CLS_INITIATOR_ERR / -ISCSI_LOGIN_STATUS_INIT_ERR via iscsit_tx_login_rsp() before returning, -so the initiator sees an explicit failed-login response rather than a -silent connection drop. (Prior to this patch only the PHASE_OPERATIONAL -caller did that; the PHASE_SECURITY caller is converted to the same -shape.) - -Fixes: e48354ce078c ("iscsi-target: Add iSCSI fabric support for target v4.1") -Cc: stable@vger.kernel.org -Assisted-by: Claude:claude-opus-4-7 -Signed-off-by: Michael Bommarito -Tested-by: John Garry -Reviewed-by: John Garry -Signed-off-by: Martin K. Petersen -(cherry picked from commit bf33e01f88388c43e285492a63e539df6ffed64c) -Signed-off-by: Maurizio Lombardi - -diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c -index 108e253..a1fb869 100644 ---- a/drivers/target/iscsi/iscsi_target_nego.c -+++ b/drivers/target/iscsi/iscsi_target_nego.c -@@ -899,10 +899,14 @@ static int iscsi_target_handle_csg_zero( - SENDER_TARGET, - login->rsp_buf, - &login->rsp_length, -+ MAX_KEY_VALUE_PAIRS, - conn->param_list, - conn->tpg->tpg_attrib.login_keys_workaround); -- if (ret < 0) -+ if (ret < 0) { -+ iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, -+ ISCSI_LOGIN_STATUS_INIT_ERR); - return -1; -+ } - - if (!iscsi_check_negotiated_keys(conn->param_list)) { - bool auth_required = iscsi_conn_auth_required(conn); -@@ -986,6 +990,7 @@ static int iscsi_target_handle_csg_one(struct iscsit_conn *conn, struct iscsi_lo - SENDER_TARGET, - login->rsp_buf, - &login->rsp_length, -+ MAX_KEY_VALUE_PAIRS, - conn->param_list, - conn->tpg->tpg_attrib.login_keys_workaround); - if (ret < 0) { -diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c -index 1d4e178..14eef58 100644 ---- a/drivers/target/iscsi/iscsi_target_parameters.c -+++ b/drivers/target/iscsi/iscsi_target_parameters.c -@@ -1371,19 +1371,42 @@ int iscsi_decode_text_input( - return -1; - } - -+/* -+ * Append "key=value" plus a trailing NUL into @textbuf at *@length. -+ * Returns 0 on success and advances *@length, or -EMSGSIZE if the -+ * record (including the NUL) would not fit in the remaining buffer. -+ */ -+static int iscsi_encode_text_record(char *textbuf, u32 *length, -+ u32 textbuf_size, -+ const char *key, const char *value) -+{ -+ int n; -+ u32 avail; -+ -+ if (*length >= textbuf_size) -+ return -EMSGSIZE; -+ -+ avail = textbuf_size - *length; -+ n = snprintf(textbuf + *length, avail, "%s=%s", key, value); -+ if (n < 0 || (u32)n + 1 > avail) -+ return -EMSGSIZE; -+ -+ *length += n + 1; -+ return 0; -+} -+ - int iscsi_encode_text_output( - u8 phase, - u8 sender, - char *textbuf, - u32 *length, -+ u32 textbuf_size, - struct iscsi_param_list *param_list, - bool keys_workaround) - { -- char *output_buf = NULL; - struct iscsi_extra_response *er; - struct iscsi_param *param; -- -- output_buf = textbuf + *length; -+ int ret; - - if (iscsi_enforce_integrity_rules(phase, param_list) < 0) - return -1; -@@ -1395,10 +1418,12 @@ int iscsi_encode_text_output( - !IS_PSTATE_RESPONSE_SENT(param) && - !IS_PSTATE_REPLY_OPTIONAL(param) && - (param->phase & phase)) { -- *length += sprintf(output_buf, "%s=%s", -- param->name, param->value); -- *length += 1; -- output_buf = textbuf + *length; -+ ret = iscsi_encode_text_record(textbuf, length, -+ textbuf_size, -+ param->name, -+ param->value); -+ if (ret < 0) -+ goto err_overflow; - SET_PSTATE_RESPONSE_SENT(param); - pr_debug("Sending key: %s=%s\n", - param->name, param->value); -@@ -1408,10 +1433,12 @@ int iscsi_encode_text_output( - !IS_PSTATE_ACCEPTOR(param) && - !IS_PSTATE_PROPOSER(param) && - (param->phase & phase)) { -- *length += sprintf(output_buf, "%s=%s", -- param->name, param->value); -- *length += 1; -- output_buf = textbuf + *length; -+ ret = iscsi_encode_text_record(textbuf, length, -+ textbuf_size, -+ param->name, -+ param->value); -+ if (ret < 0) -+ goto err_overflow; - SET_PSTATE_PROPOSER(param); - iscsi_check_proposer_for_optional_reply(param, - keys_workaround); -@@ -1421,14 +1448,21 @@ int iscsi_encode_text_output( - } - - list_for_each_entry(er, ¶m_list->extra_response_list, er_list) { -- *length += sprintf(output_buf, "%s=%s", er->key, er->value); -- *length += 1; -- output_buf = textbuf + *length; -+ ret = iscsi_encode_text_record(textbuf, length, textbuf_size, -+ er->key, er->value); -+ if (ret < 0) -+ goto err_overflow; - pr_debug("Sending key: %s=%s\n", er->key, er->value); - } - iscsi_release_extra_responses(param_list); - - return 0; -+ -+err_overflow: -+ pr_err("iSCSI login response buffer (%u bytes) exhausted, dropping login.\n", -+ textbuf_size); -+ iscsi_release_extra_responses(param_list); -+ return -1; - } - - int iscsi_check_negotiated_keys(struct iscsi_param_list *param_list) -diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h -index c672a97..38d2238 100644 ---- a/drivers/target/iscsi/iscsi_target_parameters.h -+++ b/drivers/target/iscsi/iscsi_target_parameters.h -@@ -43,7 +43,7 @@ extern struct iscsi_param *iscsi_find_param_from_key(char *, struct iscsi_param_ - extern int iscsi_extract_key_value(char *, char **, char **); - extern int iscsi_update_param_value(struct iscsi_param *, char *); - extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsit_conn *); --extern int iscsi_encode_text_output(u8, u8, char *, u32 *, -+extern int iscsi_encode_text_output(u8, u8, char *, u32 *, u32, - struct iscsi_param_list *, bool); - extern int iscsi_check_negotiated_keys(struct iscsi_param_list *); - extern void iscsi_set_connection_parameters(struct iscsi_conn_ops *, diff --git a/Makefile.rhelver b/Makefile.rhelver index 3dd309dd8..0353508f7 100644 --- a/Makefile.rhelver +++ b/Makefile.rhelver @@ -12,7 +12,7 @@ RHEL_MINOR = 2 # # Use this spot to avoid future merge conflicts. # Do not trim this comment. -RHEL_RELEASE = 211.47.1 +RHEL_RELEASE = 211.49.1 # # RHEL_REBASE_NUM diff --git a/kernel.changelog b/kernel.changelog index e55e8dfdf..7095af653 100644 --- a/kernel.changelog +++ b/kernel.changelog @@ -1,3 +1,52 @@ +* Wed Aug 19 2026 CKI KWF Bot [6.12.0-211.49.1.el10_2] +- udf: fix partition descriptor append bookkeeping (CKI Backport Bot) [RHEL-179570] {CVE-2026-45991} +- cifs: fix time_last_write stamp placement in setattr/truncate paths (Paulo Alcantara) [RHEL-235459] +- cifs: consolidate time_last_write stamp into _cifsFileInfo_put() (Paulo Alcantara) [RHEL-235459] +- cifs: fix cifsFileInfo leak on kmalloc failure in deferred close drain paths (Paulo Alcantara) [RHEL-235459] +- cifs: prevent readdir from changing file size due to stale directory metadata (Paulo Alcantara) [RHEL-235459] +- smb: client: fix dir separator in SMB1 UNIX mounts (Paulo Alcantara) [RHEL-235459] +- smb: client: fix sbflags initialization (Paulo Alcantara) [RHEL-235459] +- smb: client: use atomic_t for mnt_cifs_flags (Paulo Alcantara) [RHEL-235459] +- smb: client: fix data corruption due to racy lease checks (Paulo Alcantara) [RHEL-235459] +- crypto: pcrypt - Fix handling of MAY_BACKLOG requests (Ricardo Robaina) [RHEL-226717] {CVE-2026-43493} +- smb: client: fix SMB1 TRANS2 multi-response truncation in SendReceive() (Paulo Alcantara) [RHEL-235812] +- smb/client: handle overlapping allocated ranges in fallocate (CKI Backport Bot) [RHEL-236210] {CVE-2026-68388} +- posix-cpu-timers: Prevent UAF caused by non-leader exec() race (Waiman Long) [RHEL-227850] {CVE-2026-64560} +- posix-cpu-timers: Fix pid refcount leak in do_cpu_nanosleep() error path (Waiman Long) [RHEL-227850] {CVE-2026-64370} +- exit: kill the pointless __exit_signal()->clear_tsk_thread_flag(TIF_SIGPENDING) (Waiman Long) [RHEL-227850] +- exit: change the release_task() paths to call flush_sigqueue() lockless (Waiman Long) [RHEL-227850] +- smb: client: fix double-free in SMB2_open() replay (CKI Backport Bot) [RHEL-234551] {CVE-2026-64382} +- smb: client: mask server-provided mode to 07777 in modefromsid (CKI Backport Bot) [RHEL-234530] {CVE-2026-64379} +- smb: client: fix query_info() replay double-free (CKI Backport Bot) [RHEL-234129] {CVE-2026-64386} +- smb/client: fix out-of-bounds read in symlink_data() (CKI Backport Bot) [RHEL-229066] {CVE-2026-46185} +- blk-mq: reinsert cached request to the list (CKI Backport Bot) [RHEL-213153] {CVE-2026-64017} +- blk-mq: pop cached request if it is usable (CKI Backport Bot) [RHEL-213153] {CVE-2026-64017} +Resolves: RHEL-179570, RHEL-213153, RHEL-226717, RHEL-227850, RHEL-229066, RHEL-234129, RHEL-234530, RHEL-234551, RHEL-235459, RHEL-235812, RHEL-236210 + +* Mon Aug 17 2026 CKI KWF Bot [6.12.0-211.48.1.el10_2] +- scsi: target: iscsi: Fix CRC overread and double-free in iscsit_handle_text_cmd() (Maurizio Lombardi) [RHEL-213217] {CVE-2026-63888} +- drm/i915: Fix potential UAF in TTM object purge (CKI Backport Bot) [RHEL-222740] {CVE-2026-63884} +- drm/amd/display: Validate payload length and link_index in dc_process_dmub_aux_transfer_async (CKI Backport Bot) [RHEL-222567] {CVE-2026-64219} +- drm/amd/display: Use krealloc_array() in dal_vector_reserve() (CKI Backport Bot) [RHEL-222667] {CVE-2026-53329} +- drm/amdgpu: fix amdgpu_hmm_range_get_pages (Mika Penttilä) [RHEL-222625] {CVE-2026-63879} +- drm/amdkfd: Fix out-of-bounds write in kfd_event_page_set() (CKI Backport Bot) [RHEL-221336] {CVE-2026-43206} +- drm/i915/gem: Fix phys BO pread/pwrite with offset (CKI Backport Bot) [RHEL-222753] {CVE-2026-53356} +- drm/amdkfd: Fix watch_id bounds checking in debug address watch v2 (CKI Backport Bot) [RHEL-222721] {CVE-2026-45878} +- drm/amdkfd: Fix buffer overflow in SDMA queue checkpoint/restore on GFX11 (CKI Backport Bot) [RHEL-222701] {CVE-2026-53143} +- drm/amd/display: Clamp VBIOS HDMI retimer register count to array size (CKI Backport Bot) [RHEL-222685] {CVE-2026-53136} +- drm/amdgpu: zero-initialize GART table on allocation (CKI Backport Bot) [RHEL-222646] {CVE-2026-53374} +- drm/amdgpu: Refactor amdgpu_gem_va_ioctl for Handling Last Fence Update and Timeline Management v7 (CKI Backport Bot) [RHEL-221380] {CVE-2026-43237} +- drm/amdgpu: Refactor amdgpu_gem_va_ioctl for Handling Last Fence Update and Timeline Management v4 (CKI Backport Bot) [RHEL-221380] {CVE-2026-43237} +- sched/psi: Create the psimon kthread outside of cgroup_mutex (CKI Backport Bot) [RHEL-232560] {CVE-2026-52991} +- sched/psi: fix race between file release and pressure write (CKI Backport Bot) [RHEL-232560] {CVE-2026-52991} +- scsi: target: Fix hexadecimal CHAP_I handling (CKI Backport Bot) [RHEL-231667] {CVE-2026-63886} +- scsi: target: iscsi: Validate CHAP_R length before base64 decode (CKI Backport Bot) [RHEL-231667] {CVE-2026-63886} +- memfd: deny writeable mappings when implying SEAL_WRITE (Luiz Capitulino) [RHEL-228531] {CVE-2026-63952} +- mm/memfd: fix spelling in memfd_add_seals() (Luiz Capitulino) [RHEL-228531] +- vhost: reset the vring metadata cache on vring reconfiguration (CKI Backport Bot) [RHEL-224545] +- xfs: fix exchange-range reflink flag clearing issue with INO1_WRITTEN (Lukas Herbolt) [RHEL-223954] +Resolves: RHEL-213217, RHEL-221336, RHEL-221380, RHEL-222567, RHEL-222625, RHEL-222646, RHEL-222667, RHEL-222685, RHEL-222701, RHEL-222721, RHEL-222740, RHEL-222753, RHEL-223954, RHEL-224545, RHEL-228531, RHEL-231667, RHEL-232560 + * Wed Aug 12 2026 CKI KWF Bot [6.12.0-211.47.1.el10_2] - scsi: target: iscsi: Bound iscsi_encode_text_output() appends to rsp_buf (Maurizio Lombardi) [RHEL-213198] {CVE-2026-63887} - perf/aux: Fix page UAF in map_range() (CKI Backport Bot) [RHEL-218475] {CVE-2026-64300} diff --git a/kernel.spec b/kernel.spec index a75f3e0b9..019b14bc3 100644 --- a/kernel.spec +++ b/kernel.spec @@ -176,15 +176,15 @@ Summary: The Linux kernel %define specrpmversion 6.12.0 %define specversion 6.12.0 %define patchversion 6.12 -%define pkgrelease 211.47.1 +%define pkgrelease 211.49.1 %define kversion 6 -%define tarfile_release 6.12.0-211.46.1.el10_2 +%define tarfile_release 6.12.0-211.49.1.el10_2 # This is needed to do merge window version magic %define patchlevel 12 # This allows pkg_release to have configurable %%{?dist} tag -%define specrelease 211.47.1%{?buildid}%{?dist} +%define specrelease 211.49.1%{?buildid}%{?dist} # This defines the kabi tarball version -%define kabiversion 6.12.0-211.46.1.el10_2 +%define kabiversion 6.12.0-211.49.1.el10_2 # If this variable is set to 1, a bpf selftests build failure will cause a # fatal kernel package build error @@ -1128,95 +1128,6 @@ Patch1: patch-%{patchversion}-redhat.patch # empty final patch to facilitate testing of kernel patches Patch999999: linux-kernel-test.patch -# Backports for 6.12.0-211.47.1.el10_2 -Patch1100: 1100-netfilter-nft-set-pipapo-split-gc-into-unlink-and-reclaim-phase.patch -Patch1101: 1101-netfilter-nf-tables-always-walk-all-pending-catchall-elements.patch -Patch1102: 1102-netfilter-nft-set-hash-fix-get-operation-on-big-endian.patch -Patch1103: 1103-netfilter-nf-conntrack-h323-fix-oob-read-in-decode-choice.patch -Patch1104: 1104-netfilter-nf-tables-unconditionally-bump-set-nelems-before-insertion.patch -Patch1105: 1105-netfilter-nft-set-pipapo-fix-stack-out-of-bounds-read-in-pipapo-drop.patch -Patch1106: 1106-netfilter-nfnetlink-queue-fix-entry-leak-in-bridge-verdict-error-path.patch -Patch1107: 1107-netfilter-ctnetlink-fix-use-after-free-in-ctnetlink-dump-exp-ct.patch -Patch1108: 1108-netfilter-conntrack-add-missing-netlink-policy-validations.patch -Patch1109: 1109-netfilter-nf-conntrack-sip-fix-content-length-u32-truncation-in-sip-help-tcp.patch -Patch1110: 1110-netfilter-nf-conntrack-h323-fix-oob-read-in-decode-int-cons-case.patch -Patch1111: 1111-nf-tables-nft-dynset-fix-possible-stateful-expression-memleak-in-error-path.patch -Patch1112: 1112-netfilter-nft-set-pipapo-avx2-don-t-return-non-matching-entry-on-expiry.patch -Patch1113: 1113-netfilter-nfnetlink-log-fix-uninitialized-padding-leak-in-nfula-payload.patch -Patch1114: 1114-netfilter-nf-conntrack-expect-honor-expectation-helper-field.patch -Patch1115: 1115-netfilter-nf-conntrack-expect-use-expect-helper.patch -Patch1116: 1116-netfilter-nf-conntrack-expect-store-netns-and-zone-in-expectation.patch -Patch1117: 1117-netfilter-ip6t-rt-reject-oversized-addrnr-in-rt-mt6-check.patch -Patch1118: 1118-netfilter-ctnetlink-use-netlink-policy-range-checks.patch -Patch1119: 1119-netfilter-nfnetlink-log-account-for-netlink-header-size.patch -Patch1120: 1120-netfilter-x-tables-ensure-names-are-nul-terminated.patch -Patch1121: 1121-netfilter-ipset-use-nla-strcmp-for-ipset-attr-name-attr.patch -Patch1122: 1122-netfilter-ctnetlink-zero-expect-nat-fields-when-cta-expect-nat-absent.patch -Patch1123: 1123-netfilter-ctnetlink-ignore-explicit-helper-on-new-expectations.patch -Patch1124: 1124-netfilter-x-tables-restrict-xt-check-match-xt-check-target-extensions-for-nfprot.patch -Patch1125: 1125-netfilter-nf-tables-reject-immediate-nf-queue-verdict.patch -Patch1126: 1126-netfilter-nfnetlink-log-initialize-nfgenmsg-in-nlmsg-done-terminator.patch -Patch1127: 1127-netfilter-xt-multiport-validate-range-encoding-in-checkentry.patch -Patch1128: 1128-netfilter-nft-ct-fix-use-after-free-in-timeout-object-destroy.patch -Patch1129: 1129-netfilter-nft-osf-restrict-it-to-ipv4.patch -Patch1130: 1130-nfnetlink-osf-validate-individual-option-lengths-in-fingerprints.patch -Patch1131: 1131-netfilter-nfnetlink-osf-fix-divide-by-zero-in-osf-wss-modulo.patch -Patch1132: 1132-netfilter-conntrack-remove-sprintf-usage.patch -Patch1133: 1133-netfilter-nat-use-kfree-rcu-to-release-ops.patch -Patch1134: 1134-netfilter-nfnetlink-osf-fix-out-of-bounds-read-on-option-matching.patch -Patch1135: 1135-netfilter-nfnetlink-osf-fix-potential-null-dereference-in-ttl-check.patch -Patch1136: 1136-netfilter-nf-tables-use-list-del-rcu-for-netlink-hooks.patch -Patch1137: 1137-rculist-add-list-splice-rcu-for-private-lists.patch -Patch1138: 1138-netfilter-nf-tables-join-hook-list-via-splice-list-rcu-in-commit-phase.patch -Patch1139: 1139-netfilter-nf-tables-add-hook-transactions-for-device-deletions.patch -Patch1140: 1140-netfilter-xt-policy-fix-strict-mode-inbound-policy-matching.patch -Patch1141: 1141-netfilter-nf-conntrack-sip-don-t-use-simple-strtoul.patch -Patch1142: 1142-netfilter-replace-skb-try-make-writable-by-skb-ensure-writable.patch -Patch1143: 1143-netfilter-nft-fwd-netdev-add-device-and-headroom-validate-with-neigh-forwarding.patch -Patch1144: 1144-netfilter-nft-fwd-netdev-use-recursion-counter-in-neigh-egress-path.patch -Patch1145: 1145-netfilter-xtables-restrict-several-matches-to-inet-family.patch -Patch1146: 1146-netfilter-x-tables-add-check-hooks-to-matches-and-targets.patch -Patch1147: 1147-netfilter-nft-compat-run-xt-check-hooks-match-target-from-validate.patch -Patch1148: 1148-netfilter-xt-ct-fix-usersize-for-v1-and-v2-revision.patch -Patch1149: 1149-netfilter-nf-tables-fix-netdev-hook-allocation-memleak-with-dormant-tables.patch -Patch1150: 1150-netfilter-nf-conntrack-expect-restore-helper-propagation-via-expectation.patch -Patch1151: 1151-netfilter-ctnetlink-check-tuple-and-mask-in-expectations-created-via-nfqueue.patch -Patch1152: 1152-netfilter-nf-conntrack-sip-get-helper-before-allocating-expectation.patch -Patch1153: 1153-netfilter-nft-ct-fix-missing-expect-put-in-obj-eval.patch -Patch1154: 1154-netfilter-nf-conntrack-helper-fix-possible-null-deref-during-error-log.patch -Patch1155: 1155-netfilter-ip6t-hbh-reject-oversized-option-lists.patch -Patch1156: 1156-netfilter-br-netfilter-reallocate-headroom-if-necessary-in-neigh-hh-bridge.patch -Patch1157: 1157-netfilter-nf-queue-hold-bridge-skb-dev-while-queued.patch -Patch1158: 1158-netfilter-conntrack-tcp-do-not-force-close-on-invalid-seq-rst-without-direction-.patch -Patch1159: 1159-netfilter-synproxy-refresh-tcphdr-after-skb-ensure-writable.patch -Patch1160: 1160-netfilter-nf-conntrack-gre-fix-gre-keymap-list-corruption.patch -Patch1161: 1161-netfilter-disable-payload-mangling-in-userns.patch -Patch1162: 1162-netfilter-synproxy-add-mutex-to-guard-hook-reference-counting.patch -Patch1163: 1163-netfilter-conntrack-irc-fix-possible-out-of-bounds-read.patch -Patch1164: 1164-netfilter-nft-tunnel-fix-use-after-free-on-object-destroy.patch -Patch1165: 1165-netfilter-nft-ct-bail-out-on-template-ct-in-get-eval.patch -Patch1166: 1166-netfilter-revalidate-bridge-ports.patch -Patch1167: 1167-netfilter-nf-conntrack-destroy-stale-expectfn-expectations-on-unregister.patch -Patch1168: 1168-netfilter-nf-log-validate-mac-header-was-set-before-dumping-it.patch -Patch1169: 1169-netfilter-nft-exthdr-fix-register-tracking-for-f-present-flag.patch -Patch1170: 1170-netfilter-nft-fib-fix-stale-stack-leak-via-the-oifname-register.patch -Patch1171: 1171-netfilter-nf-dup-netdev-add-nf-dev-xmit-recursion-helpers-and-use-them.patch -Patch1172: 1172-netfilter-ctnetlink-use-nf-ct-exp-net-in-expectation-dump.patch -Patch1173: 1173-selftests-netfilter-nft-concat-range-sh-add-check-for-double-create-bug.patch -Patch1174: 1174-selftests-netfilter-nft-concat-range-sh-add-check-for-overlap-detection-bug.patch -Patch1175: 1175-selftests-netfilter-nft-concat-range-sh-add-check-for-flush-reload-bug.patch -Patch1176: 1176-netfilter-nf-conntrack-expect-store-master-tuple-in-expectation.patch -Patch1177: 1177-accel-ivpu-fix-signed-integer-truncation-in-ipc-receive.patch -Patch1178: 1178-kvm-nvmx-put-vmcs12-pages-if-nested-vm-enter-fails-due-to-invalid-guest-state.patch -Patch1179: 1179-kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch -Patch1180: 1180-kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch -Patch1181: 1181-kvm-x86-mmu-ensure-hugepage-is-in-by-slot-before-checking-max-mapping-level.patch -Patch1182: 1182-kvm-x86-hyper-v-validate-all-gvas-during-pv-tlb-flush.patch -Patch1183: 1183-kvm-svm-make-svm-flush-tlb-gva-do-a-full-asid-flush-if-npt-enabled.patch -Patch1184: 1184-net-sched-act-api-use-rcu-with-deferred-freeing-for-action-lifecycle.patch -Patch1185: 1185-perf-aux-fix-page-uaf-in-map-range.patch -Patch1186: 1186-scsi-target-iscsi-bound-iscsi-encode-text-output-appends-to-rsp-buf.patch - # AlmaLinux Patch Patch2001: 0001-Enable-all-disabled-pci-devices-by-moving-to-unmaint.patch Patch2002: 0002-Bring-back-deprecated-pci-ids-to-mptsas-mptspi-drive.patch @@ -2080,95 +1991,6 @@ ApplyOptionalPatch patch-%{patchversion}-redhat.patch ApplyOptionalPatch linux-kernel-test.patch -# Applying backports for 6.12.0-211.47.1.el10_2 -ApplyPatch 1100-netfilter-nft-set-pipapo-split-gc-into-unlink-and-reclaim-phase.patch -ApplyPatch 1101-netfilter-nf-tables-always-walk-all-pending-catchall-elements.patch -ApplyPatch 1102-netfilter-nft-set-hash-fix-get-operation-on-big-endian.patch -ApplyPatch 1103-netfilter-nf-conntrack-h323-fix-oob-read-in-decode-choice.patch -ApplyPatch 1104-netfilter-nf-tables-unconditionally-bump-set-nelems-before-insertion.patch -ApplyPatch 1105-netfilter-nft-set-pipapo-fix-stack-out-of-bounds-read-in-pipapo-drop.patch -ApplyPatch 1106-netfilter-nfnetlink-queue-fix-entry-leak-in-bridge-verdict-error-path.patch -ApplyPatch 1107-netfilter-ctnetlink-fix-use-after-free-in-ctnetlink-dump-exp-ct.patch -ApplyPatch 1108-netfilter-conntrack-add-missing-netlink-policy-validations.patch -ApplyPatch 1109-netfilter-nf-conntrack-sip-fix-content-length-u32-truncation-in-sip-help-tcp.patch -ApplyPatch 1110-netfilter-nf-conntrack-h323-fix-oob-read-in-decode-int-cons-case.patch -ApplyPatch 1111-nf-tables-nft-dynset-fix-possible-stateful-expression-memleak-in-error-path.patch -ApplyPatch 1112-netfilter-nft-set-pipapo-avx2-don-t-return-non-matching-entry-on-expiry.patch -ApplyPatch 1113-netfilter-nfnetlink-log-fix-uninitialized-padding-leak-in-nfula-payload.patch -ApplyPatch 1114-netfilter-nf-conntrack-expect-honor-expectation-helper-field.patch -ApplyPatch 1115-netfilter-nf-conntrack-expect-use-expect-helper.patch -ApplyPatch 1116-netfilter-nf-conntrack-expect-store-netns-and-zone-in-expectation.patch -ApplyPatch 1117-netfilter-ip6t-rt-reject-oversized-addrnr-in-rt-mt6-check.patch -ApplyPatch 1118-netfilter-ctnetlink-use-netlink-policy-range-checks.patch -ApplyPatch 1119-netfilter-nfnetlink-log-account-for-netlink-header-size.patch -ApplyPatch 1120-netfilter-x-tables-ensure-names-are-nul-terminated.patch -ApplyPatch 1121-netfilter-ipset-use-nla-strcmp-for-ipset-attr-name-attr.patch -ApplyPatch 1122-netfilter-ctnetlink-zero-expect-nat-fields-when-cta-expect-nat-absent.patch -ApplyPatch 1123-netfilter-ctnetlink-ignore-explicit-helper-on-new-expectations.patch -ApplyPatch 1124-netfilter-x-tables-restrict-xt-check-match-xt-check-target-extensions-for-nfprot.patch -ApplyPatch 1125-netfilter-nf-tables-reject-immediate-nf-queue-verdict.patch -ApplyPatch 1126-netfilter-nfnetlink-log-initialize-nfgenmsg-in-nlmsg-done-terminator.patch -ApplyPatch 1127-netfilter-xt-multiport-validate-range-encoding-in-checkentry.patch -ApplyPatch 1128-netfilter-nft-ct-fix-use-after-free-in-timeout-object-destroy.patch -ApplyPatch 1129-netfilter-nft-osf-restrict-it-to-ipv4.patch -ApplyPatch 1130-nfnetlink-osf-validate-individual-option-lengths-in-fingerprints.patch -ApplyPatch 1131-netfilter-nfnetlink-osf-fix-divide-by-zero-in-osf-wss-modulo.patch -ApplyPatch 1132-netfilter-conntrack-remove-sprintf-usage.patch -ApplyPatch 1133-netfilter-nat-use-kfree-rcu-to-release-ops.patch -ApplyPatch 1134-netfilter-nfnetlink-osf-fix-out-of-bounds-read-on-option-matching.patch -ApplyPatch 1135-netfilter-nfnetlink-osf-fix-potential-null-dereference-in-ttl-check.patch -ApplyPatch 1136-netfilter-nf-tables-use-list-del-rcu-for-netlink-hooks.patch -ApplyPatch 1137-rculist-add-list-splice-rcu-for-private-lists.patch -ApplyPatch 1138-netfilter-nf-tables-join-hook-list-via-splice-list-rcu-in-commit-phase.patch -ApplyPatch 1139-netfilter-nf-tables-add-hook-transactions-for-device-deletions.patch -ApplyPatch 1140-netfilter-xt-policy-fix-strict-mode-inbound-policy-matching.patch -ApplyPatch 1141-netfilter-nf-conntrack-sip-don-t-use-simple-strtoul.patch -ApplyPatch 1142-netfilter-replace-skb-try-make-writable-by-skb-ensure-writable.patch -ApplyPatch 1143-netfilter-nft-fwd-netdev-add-device-and-headroom-validate-with-neigh-forwarding.patch -ApplyPatch 1144-netfilter-nft-fwd-netdev-use-recursion-counter-in-neigh-egress-path.patch -ApplyPatch 1145-netfilter-xtables-restrict-several-matches-to-inet-family.patch -ApplyPatch 1146-netfilter-x-tables-add-check-hooks-to-matches-and-targets.patch -ApplyPatch 1147-netfilter-nft-compat-run-xt-check-hooks-match-target-from-validate.patch -ApplyPatch 1148-netfilter-xt-ct-fix-usersize-for-v1-and-v2-revision.patch -ApplyPatch 1149-netfilter-nf-tables-fix-netdev-hook-allocation-memleak-with-dormant-tables.patch -ApplyPatch 1150-netfilter-nf-conntrack-expect-restore-helper-propagation-via-expectation.patch -ApplyPatch 1151-netfilter-ctnetlink-check-tuple-and-mask-in-expectations-created-via-nfqueue.patch -ApplyPatch 1152-netfilter-nf-conntrack-sip-get-helper-before-allocating-expectation.patch -ApplyPatch 1153-netfilter-nft-ct-fix-missing-expect-put-in-obj-eval.patch -ApplyPatch 1154-netfilter-nf-conntrack-helper-fix-possible-null-deref-during-error-log.patch -ApplyPatch 1155-netfilter-ip6t-hbh-reject-oversized-option-lists.patch -ApplyPatch 1156-netfilter-br-netfilter-reallocate-headroom-if-necessary-in-neigh-hh-bridge.patch -ApplyPatch 1157-netfilter-nf-queue-hold-bridge-skb-dev-while-queued.patch -ApplyPatch 1158-netfilter-conntrack-tcp-do-not-force-close-on-invalid-seq-rst-without-direction-.patch -ApplyPatch 1159-netfilter-synproxy-refresh-tcphdr-after-skb-ensure-writable.patch -ApplyPatch 1160-netfilter-nf-conntrack-gre-fix-gre-keymap-list-corruption.patch -ApplyPatch 1161-netfilter-disable-payload-mangling-in-userns.patch -ApplyPatch 1162-netfilter-synproxy-add-mutex-to-guard-hook-reference-counting.patch -ApplyPatch 1163-netfilter-conntrack-irc-fix-possible-out-of-bounds-read.patch -ApplyPatch 1164-netfilter-nft-tunnel-fix-use-after-free-on-object-destroy.patch -ApplyPatch 1165-netfilter-nft-ct-bail-out-on-template-ct-in-get-eval.patch -ApplyPatch 1166-netfilter-revalidate-bridge-ports.patch -ApplyPatch 1167-netfilter-nf-conntrack-destroy-stale-expectfn-expectations-on-unregister.patch -ApplyPatch 1168-netfilter-nf-log-validate-mac-header-was-set-before-dumping-it.patch -ApplyPatch 1169-netfilter-nft-exthdr-fix-register-tracking-for-f-present-flag.patch -ApplyPatch 1170-netfilter-nft-fib-fix-stale-stack-leak-via-the-oifname-register.patch -ApplyPatch 1171-netfilter-nf-dup-netdev-add-nf-dev-xmit-recursion-helpers-and-use-them.patch -ApplyPatch 1172-netfilter-ctnetlink-use-nf-ct-exp-net-in-expectation-dump.patch -ApplyPatch 1173-selftests-netfilter-nft-concat-range-sh-add-check-for-double-create-bug.patch -ApplyPatch 1174-selftests-netfilter-nft-concat-range-sh-add-check-for-overlap-detection-bug.patch -ApplyPatch 1175-selftests-netfilter-nft-concat-range-sh-add-check-for-flush-reload-bug.patch -ApplyPatch 1176-netfilter-nf-conntrack-expect-store-master-tuple-in-expectation.patch -ApplyPatch 1177-accel-ivpu-fix-signed-integer-truncation-in-ipc-receive.patch -ApplyPatch 1178-kvm-nvmx-put-vmcs12-pages-if-nested-vm-enter-fails-due-to-invalid-guest-state.patch -ApplyPatch 1179-kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch -ApplyPatch 1180-kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch -ApplyPatch 1181-kvm-x86-mmu-ensure-hugepage-is-in-by-slot-before-checking-max-mapping-level.patch -ApplyPatch 1182-kvm-x86-hyper-v-validate-all-gvas-during-pv-tlb-flush.patch -ApplyPatch 1183-kvm-svm-make-svm-flush-tlb-gva-do-a-full-asid-flush-if-npt-enabled.patch -ApplyPatch 1184-net-sched-act-api-use-rcu-with-deferred-freeing-for-action-lifecycle.patch -ApplyPatch 1185-perf-aux-fix-page-uaf-in-map-range.patch -ApplyPatch 1186-scsi-target-iscsi-bound-iscsi-encode-text-output-appends-to-rsp-buf.patch - # Applying AlmaLinux Patch ApplyPatch 0001-Enable-all-disabled-pci-devices-by-moving-to-unmaint.patch ApplyPatch 0002-Bring-back-deprecated-pci-ids-to-mptsas-mptspi-drive.patch @@ -4695,14 +4517,14 @@ fi\ # # %changelog -* Thu Aug 13 2026 Eduard Abdullin - 6.12.0-211.47.1 +* Fri Aug 21 2026 Eduard Abdullin - 6.12.0-211.49.1 - Debrand for AlmaLinux OS - Use AlmaLinux OS secure boot cert -* Thu Aug 13 2026 Neal Gompa - 6.12.0-211.47.1 +* Fri Aug 21 2026 Neal Gompa - 6.12.0-211.49.1 - Enable Btrfs support for all kernel variants -* Thu Aug 13 2026 Andrew Lukoshko - 6.12.0-211.47.1 +* Fri Aug 21 2026 Andrew Lukoshko - 6.12.0-211.49.1 - af_unix: set gc_in_progress to true in unix_gc() {CVE-2026-53361} - hpsa: bring back deprecated PCI ids #CFHack #CFHack2024 - mptsas: bring back deprecated PCI ids #CFHack #CFHack2024 @@ -4717,6 +4539,53 @@ fi\ - gve: enable reading max ring size from the device in DQO-QPL mode (backport from upstream) +* Wed Aug 19 2026 CKI KWF Bot [6.12.0-211.49.1.el10_2] +- udf: fix partition descriptor append bookkeeping (CKI Backport Bot) [RHEL-179570] {CVE-2026-45991} +- cifs: fix time_last_write stamp placement in setattr/truncate paths (Paulo Alcantara) [RHEL-235459] +- cifs: consolidate time_last_write stamp into _cifsFileInfo_put() (Paulo Alcantara) [RHEL-235459] +- cifs: fix cifsFileInfo leak on kmalloc failure in deferred close drain paths (Paulo Alcantara) [RHEL-235459] +- cifs: prevent readdir from changing file size due to stale directory metadata (Paulo Alcantara) [RHEL-235459] +- smb: client: fix dir separator in SMB1 UNIX mounts (Paulo Alcantara) [RHEL-235459] +- smb: client: fix sbflags initialization (Paulo Alcantara) [RHEL-235459] +- smb: client: use atomic_t for mnt_cifs_flags (Paulo Alcantara) [RHEL-235459] +- smb: client: fix data corruption due to racy lease checks (Paulo Alcantara) [RHEL-235459] +- crypto: pcrypt - Fix handling of MAY_BACKLOG requests (Ricardo Robaina) [RHEL-226717] {CVE-2026-43493} +- smb: client: fix SMB1 TRANS2 multi-response truncation in SendReceive() (Paulo Alcantara) [RHEL-235812] +- smb/client: handle overlapping allocated ranges in fallocate (CKI Backport Bot) [RHEL-236210] {CVE-2026-68388} +- posix-cpu-timers: Prevent UAF caused by non-leader exec() race (Waiman Long) [RHEL-227850] {CVE-2026-64560} +- posix-cpu-timers: Fix pid refcount leak in do_cpu_nanosleep() error path (Waiman Long) [RHEL-227850] {CVE-2026-64370} +- exit: kill the pointless __exit_signal()->clear_tsk_thread_flag(TIF_SIGPENDING) (Waiman Long) [RHEL-227850] +- exit: change the release_task() paths to call flush_sigqueue() lockless (Waiman Long) [RHEL-227850] +- smb: client: fix double-free in SMB2_open() replay (CKI Backport Bot) [RHEL-234551] {CVE-2026-64382} +- smb: client: mask server-provided mode to 07777 in modefromsid (CKI Backport Bot) [RHEL-234530] {CVE-2026-64379} +- smb: client: fix query_info() replay double-free (CKI Backport Bot) [RHEL-234129] {CVE-2026-64386} +- smb/client: fix out-of-bounds read in symlink_data() (CKI Backport Bot) [RHEL-229066] {CVE-2026-46185} +- blk-mq: reinsert cached request to the list (CKI Backport Bot) [RHEL-213153] {CVE-2026-64017} +- blk-mq: pop cached request if it is usable (CKI Backport Bot) [RHEL-213153] {CVE-2026-64017} + +* Mon Aug 17 2026 CKI KWF Bot [6.12.0-211.48.1.el10_2] +- scsi: target: iscsi: Fix CRC overread and double-free in iscsit_handle_text_cmd() (Maurizio Lombardi) [RHEL-213217] {CVE-2026-63888} +- drm/i915: Fix potential UAF in TTM object purge (CKI Backport Bot) [RHEL-222740] {CVE-2026-63884} +- drm/amd/display: Validate payload length and link_index in dc_process_dmub_aux_transfer_async (CKI Backport Bot) [RHEL-222567] {CVE-2026-64219} +- drm/amd/display: Use krealloc_array() in dal_vector_reserve() (CKI Backport Bot) [RHEL-222667] {CVE-2026-53329} +- drm/amdgpu: fix amdgpu_hmm_range_get_pages (Mika Penttilä) [RHEL-222625] {CVE-2026-63879} +- drm/amdkfd: Fix out-of-bounds write in kfd_event_page_set() (CKI Backport Bot) [RHEL-221336] {CVE-2026-43206} +- drm/i915/gem: Fix phys BO pread/pwrite with offset (CKI Backport Bot) [RHEL-222753] {CVE-2026-53356} +- drm/amdkfd: Fix watch_id bounds checking in debug address watch v2 (CKI Backport Bot) [RHEL-222721] {CVE-2026-45878} +- drm/amdkfd: Fix buffer overflow in SDMA queue checkpoint/restore on GFX11 (CKI Backport Bot) [RHEL-222701] {CVE-2026-53143} +- drm/amd/display: Clamp VBIOS HDMI retimer register count to array size (CKI Backport Bot) [RHEL-222685] {CVE-2026-53136} +- drm/amdgpu: zero-initialize GART table on allocation (CKI Backport Bot) [RHEL-222646] {CVE-2026-53374} +- drm/amdgpu: Refactor amdgpu_gem_va_ioctl for Handling Last Fence Update and Timeline Management v7 (CKI Backport Bot) [RHEL-221380] {CVE-2026-43237} +- drm/amdgpu: Refactor amdgpu_gem_va_ioctl for Handling Last Fence Update and Timeline Management v4 (CKI Backport Bot) [RHEL-221380] {CVE-2026-43237} +- sched/psi: Create the psimon kthread outside of cgroup_mutex (CKI Backport Bot) [RHEL-232560] {CVE-2026-52991} +- sched/psi: fix race between file release and pressure write (CKI Backport Bot) [RHEL-232560] {CVE-2026-52991} +- scsi: target: Fix hexadecimal CHAP_I handling (CKI Backport Bot) [RHEL-231667] {CVE-2026-63886} +- scsi: target: iscsi: Validate CHAP_R length before base64 decode (CKI Backport Bot) [RHEL-231667] {CVE-2026-63886} +- memfd: deny writeable mappings when implying SEAL_WRITE (Luiz Capitulino) [RHEL-228531] {CVE-2026-63952} +- mm/memfd: fix spelling in memfd_add_seals() (Luiz Capitulino) [RHEL-228531] +- vhost: reset the vring metadata cache on vring reconfiguration (CKI Backport Bot) [RHEL-224545] +- xfs: fix exchange-range reflink flag clearing issue with INO1_WRITTEN (Lukas Herbolt) [RHEL-223954] + * Wed Aug 12 2026 CKI KWF Bot [6.12.0-211.47.1.el10_2] - scsi: target: iscsi: Bound iscsi_encode_text_output() appends to rsp_buf (Maurizio Lombardi) [RHEL-213198] {CVE-2026-63887} - perf/aux: Fix page UAF in map_range() (CKI Backport Bot) [RHEL-218475] {CVE-2026-64300} diff --git a/sources b/sources index 8418a81af..7afb7f011 100644 --- a/sources +++ b/sources @@ -1,7 +1,7 @@ SHA512 (fedoraimaca.x509) = e04809394f4472c17e86d7024dee34f03fb68e82a85502fd5b00535202c72e57626a8376b2cf991b7e1e46404aa5ab8d189ebf320e0dd37d49e7efbc925c7a2e -SHA512 (kernel-abi-stablelists-6.12.0-211.46.1.el10_2.tar.xz) = d66d6513e4a66f9bbd0bd3d9767342d4cda231f4e6038677f620d6f0dca62234273248d940eecd29f8eff88f0567025df9054c3d1b99941c7ce6ffe74d4fd90c -SHA512 (kernel-kabi-dw-6.12.0-211.46.1.el10_2.tar.xz) = 176ef20ea5ea7018dfd4ced50fb9ff53abb2d3d4df574c2a2bc4e088cecc52a61ec62eac70b45236496cd766b0958dd926df5e26628afb88c6a2c95a931a2432 -SHA512 (linux-6.12.0-211.46.1.el10_2.tar.xz) = 0dabec33a1f34a5b0ddfd5b26946591f835d195874b07bf159b827a08d1ca5f2203295e3dd914a492bc01f94aa01e1173b4bba81ec4fa7c694090523c9ec296e +SHA512 (kernel-abi-stablelists-6.12.0-211.49.1.el10_2.tar.xz) = 416bb692773630104eb67024328eb3d1e41eeadff29b2031c321f7245e49ba0c0a65ee8f97196d4d56c876dc7bc286de0f6c2821aa0027a9c7a5cfcfdd8bd8ff +SHA512 (kernel-kabi-dw-6.12.0-211.49.1.el10_2.tar.xz) = f25397dc77084036d57a36a0402aeb486de9612112bf41ebb12583982cd5e47e3b29c3143de62089e1cddb1e2579412f99e56497fdfdb933571a007b55923c0b +SHA512 (linux-6.12.0-211.49.1.el10_2.tar.xz) = 8863a27bb39734d3d50554b0382ae2f3d83babfbba45cd5c5e86cb05670e4d6c5918e60207fca15a60c719c74f831ce45683d4f4208892d44ac903e96d3ca126 SHA512 (nvidiabfdpu.x509) = d9f4fbafcec66803c5944df1f97d4348968141c968e6537252c9854c89dca8ea3be225a9c40abbbf2b7d4d3cfd8c5012cd2d34d90443fbc0277b7a018622ac4f SHA512 (nvidiagpuoot001.x509) = b42f836e1cfa07890cb6ca13de9c3950e306c9ec7686c4c09f050bb68869f5d82962b2cd5f3aa0eb7a0f3a3ae54e9c480eafbac5df53aa92c295ff511a8c59fe SHA512 (nvidiajetsonsoc.x509) = 3c6d4f0800b3fae3c3cc3e5361de31df233e230ea96f0fdd3dcc713e6a71e27309f60e7a98d1a4a90d470f336ce311f22fcc88f219429272e96339717fe001dd