mailweb.openeuler.org
Manage this list

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

Kernel

Threads by month
  • ----- 2026 -----
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2025 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
kernel@openeuler.org

  • 36 participants
  • 24194 discussions
[PATCH OLK-6.6] sctp: disable BH before calling udp_tunnel_xmit_skb()
by Wupeng Ma 27 Jul '26

27 Jul '26
From: Xin Long <lucien.xin(a)gmail.com> stable inclusion from stable-v6.12.95 commit be3bfcb34bda04f6a350710db471d4133f950f2c category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/15772 CVE: CVE-2026-53070 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- commit 2cd7e6971fc2787408ceef17906ea152791448cf upstream. udp_tunnel_xmit_skb() / udp_tunnel6_xmit_skb() are expected to run with BH disabled. After commit 6f1a9140ecda ("add xmit recursion limit to tunnel xmit functions"), on the path: udp(6)_tunnel_xmit_skb() -> ip(6)tunnel_xmit() dev_xmit_recursion_inc()/dec() must stay balanced on the same CPU. Without local_bh_disable(), the context may move between CPUs, which can break the inc/dec pairing. This may lead to incorrect recursion level detection and cause packets to be dropped in ip(6)_tunnel_xmit() or __dev_queue_xmit(). Fix it by disabling BH around both IPv4 and IPv6 SCTP UDP xmit paths. In my testing, after enabling the SCTP over UDP: # ip net exec ha sysctl -w net.sctp.udp_port=9899 # ip net exec ha sysctl -w net.sctp.encap_port=9899 # ip net exec hb sysctl -w net.sctp.udp_port=9899 # ip net exec hb sysctl -w net.sctp.encap_port=9899 # ip net exec ha iperf3 -s - without this patch: # ip net exec hb iperf3 -c 192.168.0.1 --sctp [ 5] 0.00-10.00 sec 37.2 MBytes 31.2 Mbits/sec sender [ 5] 0.00-10.00 sec 37.1 MBytes 31.1 Mbits/sec receiver - with this patch: # ip net exec hb iperf3 -c 192.168.0.1 --sctp [ 5] 0.00-10.00 sec 3.14 GBytes 2.69 Gbits/sec sender [ 5] 0.00-10.00 sec 3.14 GBytes 2.69 Gbits/sec receiver Fixes: 6f1a9140ecda ("net: add xmit recursion limit to tunnel xmit functions") Fixes: 046c052b475e ("sctp: enable udp tunneling socks") Signed-off-by: Xin Long <lucien.xin(a)gmail.com> Acked-by: Marcelo Ricardo Leitner <marcelo.leitner(a)gmail.com> Link: https://patch.msgid.link/c874a8548221dcd56ff03c65ba75a74e6cf99119.177601772… Signed-off-by: Jakub Kicinski <kuba(a)kernel.org> Signed-off-by: Alexander Martyniuk <alexevgmart(a)gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Conflicts: net/sctp/ipv6.c net/sctp/protocol.c [Wupeng Ma: conflicts due commit 05d6d492097c & 6a7d88ca15f7, cleanup only, no function changed] Signed-off-by: Wupeng Ma <mawupeng1(a)huawei.com> --- net/sctp/ipv6.c | 6 +++++- net/sctp/protocol.c | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 0673857cb3d8b..93d9d32b186cc 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -227,6 +227,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t) struct ipv6_pinfo *np = inet6_sk(sk); __u8 tclass = np->tclass; __be32 label; + int ret; pr_debug("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", __func__, skb, skb->len, &fl6->saddr, &fl6->daddr); @@ -263,9 +264,12 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t) skb_set_inner_ipproto(skb, IPPROTO_SCTP); label = ip6_make_flowlabel(sock_net(sk), skb, fl6->flowlabel, true, fl6); - return udp_tunnel6_xmit_skb(dst, sk, skb, NULL, &fl6->saddr, + local_bh_disable(); + ret = udp_tunnel6_xmit_skb(dst, sk, skb, NULL, &fl6->saddr, &fl6->daddr, tclass, ip6_dst_hoplimit(dst), label, sctp_sk(sk)->udp_port, t->encap_port, false); + local_bh_enable(); + return ret; } /* Returns the dst cache entry for the given source and destination ip diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 94c6dd53cd62d..824c3f38554f7 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1085,9 +1085,11 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, struct sctp_transport *t) skb_reset_inner_mac_header(skb); skb_reset_inner_transport_header(skb); skb_set_inner_ipproto(skb, IPPROTO_SCTP); + local_bh_disable(); udp_tunnel_xmit_skb((struct rtable *)dst, sk, skb, fl4->saddr, fl4->daddr, dscp, ip4_dst_hoplimit(dst), df, sctp_sk(sk)->udp_port, t->encap_port, false, false); + local_bh_enable(); return 0; } -- 2.43.0
2 1
0 0
[PATCH OLK-6.6] [OLK-6.6] scsi: scsi_transport_fc: Widen FPIN pname walker counter to u32
by Lu Chentao 27 Jul '26

27 Jul '26
From: Michael Bommarito <michael.bommarito(a)gmail.com> mainline inclusion from mainline-v7.1-rc6 commit a9a39233ec1fc9f97ea1340a4d09bb7ec2be5153 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16217 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… ---------------------------------------------------------------------- An adjacent Fibre Channel fabric actor that can deliver an FPIN ELS frame to an lpfc or qla2xxx Linux initiator can trigger a non-return in the generic FC transport. This is not a local userspace or IP network path; the attacker must be able to inject fabric traffic, for example as a compromised switch or fabric controller, or as a same-zone N_Port on a fabric that permits source spoofing. The Link-Integrity and Peer-Congestion FPIN walkers used a u8 loop counter against the 32-bit on-wire pname_count field, and did not bound pname_count by the descriptor body already validated by the TLV walker. A pname_count of 256 therefore wraps the counter and keeps the loop condition true indefinitely. Factor the shared pname_list[] walk into one helper, widen the counter to u32, and clamp pname_count against the entries that fit in the descriptor body before iterating. Fixes: 3dcfe0de5a97 ("scsi: fc: Parse FPIN packets and update statistics") Cc: stable(a)vger.kernel.org Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Michael Bommarito <michael.bommarito(a)gmail.com> Reviewed-by: Christoph Hellwig <hch(a)lst.de> Reviewed-by: John Garry <john.g.garry(a)oracle.com> Link: https://patch.msgid.link/20260520133015.1018937-1-michael.bommarito@gmail.c… Signed-off-by: Martin K. Petersen <martin.petersen(a)oracle.com> Signed-off-by: Lu Chentao <luchentao1(a)huawei.com> --- drivers/scsi/scsi_transport_fc.c | 77 +++++++++++++++++--------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 96002966ca56..fd827e30556b 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -745,53 +745,71 @@ fc_cn_stats_update(u16 event_type, struct fc_fpin_stats *stats) case FPIN_CONGN_DEVICE_SPEC: stats->cn_device_specific++; } } +static void +fc_fpin_pname_stats_update(struct Scsi_Host *shost, + struct fc_rport *attach_rport, u16 event_type, + u32 desc_len, u32 fixed_len, u32 pname_count, + __be64 *pname_list, + void (*stats_update)(u16 event_type, + struct fc_fpin_stats *stats)) +{ + u32 i; + struct fc_rport *rport; + u64 wwpn; + + if (desc_len < fixed_len) + pname_count = 0; + else + pname_count = min(pname_count, (desc_len - fixed_len) / + sizeof(pname_list[0])); + + for (i = 0; i < pname_count; i++) { + wwpn = be64_to_cpu(pname_list[i]); + rport = fc_find_rport_by_wwpn(shost, wwpn); + if (rport && + (rport->roles & FC_PORT_ROLE_FCP_TARGET || + rport->roles & FC_PORT_ROLE_NVME_TARGET)) { + if (rport == attach_rport) + continue; + stats_update(event_type, &rport->fpin_stats); + } + } +} + /* * fc_fpin_li_stats_update - routine to update Link Integrity * event statistics. * @shost: host the FPIN was received on * @tlv: pointer to link integrity descriptor * */ static void fc_fpin_li_stats_update(struct Scsi_Host *shost, struct fc_tlv_desc *tlv) { - u8 i; struct fc_rport *rport = NULL; struct fc_rport *attach_rport = NULL; struct fc_host_attrs *fc_host = shost_to_fc_host(shost); struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv; u16 event_type = be16_to_cpu(li_desc->event_type); - u64 wwpn; rport = fc_find_rport_by_wwpn(shost, be64_to_cpu(li_desc->attached_wwpn)); if (rport && (rport->roles & FC_PORT_ROLE_FCP_TARGET || rport->roles & FC_PORT_ROLE_NVME_TARGET)) { attach_rport = rport; fc_li_stats_update(event_type, &attach_rport->fpin_stats); } - if (be32_to_cpu(li_desc->pname_count) > 0) { - for (i = 0; - i < be32_to_cpu(li_desc->pname_count); - i++) { - wwpn = be64_to_cpu(li_desc->pname_list[i]); - rport = fc_find_rport_by_wwpn(shost, wwpn); - if (rport && - (rport->roles & FC_PORT_ROLE_FCP_TARGET || - rport->roles & FC_PORT_ROLE_NVME_TARGET)) { - if (rport == attach_rport) - continue; - fc_li_stats_update(event_type, - &rport->fpin_stats); - } - } - } + fc_fpin_pname_stats_update(shost, attach_rport, event_type, + be32_to_cpu(li_desc->desc_len), + FC_TLV_DESC_LENGTH_FROM_SZ(*li_desc), + be32_to_cpu(li_desc->pname_count), + li_desc->pname_list, fc_li_stats_update); if (fc_host->port_name == be64_to_cpu(li_desc->attached_wwpn)) fc_li_stats_update(event_type, &fc_host->fpin_stats); } @@ -835,43 +853,30 @@ fc_fpin_delivery_stats_update(struct Scsi_Host *shost, */ static void fc_fpin_peer_congn_stats_update(struct Scsi_Host *shost, struct fc_tlv_desc *tlv) { - u8 i; struct fc_rport *rport = NULL; struct fc_rport *attach_rport = NULL; struct fc_fn_peer_congn_desc *pc_desc = (struct fc_fn_peer_congn_desc *)tlv; u16 event_type = be16_to_cpu(pc_desc->event_type); - u64 wwpn; rport = fc_find_rport_by_wwpn(shost, be64_to_cpu(pc_desc->attached_wwpn)); if (rport && (rport->roles & FC_PORT_ROLE_FCP_TARGET || rport->roles & FC_PORT_ROLE_NVME_TARGET)) { attach_rport = rport; fc_cn_stats_update(event_type, &attach_rport->fpin_stats); } - if (be32_to_cpu(pc_desc->pname_count) > 0) { - for (i = 0; - i < be32_to_cpu(pc_desc->pname_count); - i++) { - wwpn = be64_to_cpu(pc_desc->pname_list[i]); - rport = fc_find_rport_by_wwpn(shost, wwpn); - if (rport && - (rport->roles & FC_PORT_ROLE_FCP_TARGET || - rport->roles & FC_PORT_ROLE_NVME_TARGET)) { - if (rport == attach_rport) - continue; - fc_cn_stats_update(event_type, - &rport->fpin_stats); - } - } - } + fc_fpin_pname_stats_update(shost, attach_rport, event_type, + be32_to_cpu(pc_desc->desc_len), + FC_TLV_DESC_LENGTH_FROM_SZ(*pc_desc), + be32_to_cpu(pc_desc->pname_count), + pc_desc->pname_list, fc_cn_stats_update); } /* * fc_fpin_congn_stats_update - routine to update Congestion * event statistics. -- 2.52.0
2 7
0 0
[PATCH OLK-5.10 1/1] bpf, skmsg: fix verdict sk_data_ready racing with ktls rx
by superdcc97@163.com 26 Jul '26

26 Jul '26
From: Xingwang Xiang <v3rdant.xiang(a)gmail.com> mainline inclusion from mainline-v7.1-rc5 commit ddf8029623a1 ("bpf, skmsg: fix verdict sk_data_ready racing with ktls rx") category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16350 CVE: CVE-2026-64025 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- sk_psock_strp_data_ready() already checks tls_sw_has_ctx_rx() and defers to psock->saved_data_ready when a TLS RX context is present, avoiding a conflict with the TLS strparser's ownership of the receive queue (commit e91de6afa81c ("bpf: Fix running sk_skb program types with ktls")). sk_psock_verdict_data_ready() has no equivalent guard. When a socket is inserted into a sockmap (BPF_SK_SKB_VERDICT) before TLS RX is configured, tls_sw_strparser_arm() saves sk_psock_verdict_data_ready as rx_ctx->saved_data_ready. On data arrival: tls_data_ready -> tls_strp_data_ready -> tls_rx_msg_ready -> saved_data_ready() = sk_psock_verdict_data_ready() -> tcp_read_skb() drains sk_receive_queue via __skb_unlink() without calling tcp_eat_skb(), so copied_seq is not advanced. tls_strp_msg_load() then finds tcp_inq() >= full_len (stale), calls tcp_recv_skb() on the now-empty queue, hits WARN_ON_ONCE(!first), and returns with rx_ctx->strp.anchor.frag_list pointing at a psock-owned (potentially freed) skb. tls_decrypt_sg() subsequently walks that frag_list: use-after-free. Apply the same fix as sk_psock_strp_data_ready(): if a TLS RX context is present, call psock->saved_data_ready (sock_def_readable) to wake recv() waiters and return immediately, leaving the receive queue untouched. TLS retains sole ownership of the queue and decrypts the record normally through tls_sw_recvmsg(). Fixes: ef5659280eb1 ("bpf, sockmap: Allow skipping sk_skb parser program") Signed-off-by: Xingwang Xiang <v3rdant.xiang(a)gmail.com> Link: https://patch.msgid.link/20260517145630.20521-2-v3rdant.xiang@gmail.com Signed-off-by: Jakub Kicinski <kuba(a)kernel.org> Conflicts: net/core/skmsg.c [commit ddf8029623a is not backport, which lead to conflicts Adaptation notes: - The upstream mainline function uses rcu_read_lock(), sk_psock(), READ_ONCE(sk->sk_socket) and ops->read_skb. The OLK-5.10 version of sk_psock_verdict_data_ready() uses the legacy sock->ops->read_sock path without RCU protection. - Transplanted the TLS RX guard by taking rcu_read_lock(), obtaining struct sk_psock *psock, and calling psock->parser.saved_data_ready(sk) (in 5.10 saved_data_ready lives inside struct sk_psock_parser) before returning, leaving the receive queue untouched for ktls. - This preserves the same logic as sk_psock_strp_data_ready() which already performs tls_sw_has_ctx_rx() detection in this tree.] Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com> --- net/core/skmsg.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/core/skmsg.c b/net/core/skmsg.c index 5150fc93dd9b..b979a4cba4d2 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -1056,11 +1056,21 @@ static int sk_psock_verdict_recv(read_descriptor_t *desc, struct sk_buff *skb, static void sk_psock_verdict_data_ready(struct sock *sk) { struct socket *sock = sk->sk_socket; + struct sk_psock *psock; read_descriptor_t desc; if (unlikely(!sock || !sock->ops || !sock->ops->read_sock)) return; + rcu_read_lock(); + psock = sk_psock(sk); + if (psock && tls_sw_has_ctx_rx(sk)) { + psock->parser.saved_data_ready(sk); + rcu_read_unlock(); + return; + } + rcu_read_unlock(); + desc.arg.data = sk; desc.error = 0; desc.count = 1; -- 2.43.0
2 1
0 0
[PATCH OLK-5.10] net: tls: fix off-by-one in sg_chain entry count for wrapped sk_msg ring
by superdcc97@163.com 26 Jul '26

26 Jul '26
From: Jakub Kicinski <kuba(a)kernel.org> stable inclusion from stable-v5.10.258 commit 73963a375885d5ccb7def39fd0b4f542e0f343dd category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16485 CVE: CVE-2026-64047 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit 285943c6e7ca309bbea84b253745154241d9788a ] When an sk_msg scatterlist ring wraps (sg.end < sg.start), tls_push_record() chains the tail portion of the ring to the head using sg_chain(). An extra entry in the sg array is reserved for this: struct sk_msg_sg { [...] /* The extra two elements: * 1) used for chaining the front and sections when the list becomes * partitioned (e.g. end < start). The crypto APIs require the * chaining; * 2) to chain tailer SG entries after the message. */ struct scatterlist data[MAX_MSG_FRAGS + 2]; The current code uses MAX_SKB_FRAGS + 1 as the ring size: sg_chain(&msg_pl->sg.data[msg_pl->sg.start], MAX_SKB_FRAGS - msg_pl->sg.start + 1, msg_pl->sg.data); This places the chain pointer at sg_chain(data[start], (MAX_SKB_FRAGS - msg_start + 1) .. = &data[start] + (MAX_SKB_FRAGS - msg_start + 1) - 1 = data[start + (MAX_SKB_FRAGS - start + 1) - 1] = data[MAX_SKB_FRAGS] instead of the true last entry. This is likely due to a "race" of the commit under Fixes landing close to commit 031097d9e079 ("bpf: sk_msg, zap ingress queue on psock down") Convert to ARRAY_SIZE and drop the data[start] / - start (as suggested by Sabrina). Reported-by: 钱一铭 <yimingqian591(a)gmail.com> Fixes: 9aaaa56845a0 ("bpf: Sockmap/tls, skmsg can have wrapped skmsg that needs extra chaining") Signed-off-by: Jakub Kicinski <kuba(a)kernel.org> Reviewed-by: Sabrina Dubroca <sd(a)queasysnail.net> Link: https://patch.msgid.link/20260511174920.433155-2-kuba@kernel.org Signed-off-by: Paolo Abeni <pabeni(a)redhat.com> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com> --- net/tls/tls_sw.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index de3303baef70..e5e9cf56f99e 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -751,11 +751,9 @@ static int tls_push_record(struct sock *sk, int flags, sg_mark_end(sk_msg_elem(msg_pl, i)); } - if (msg_pl->sg.end < msg_pl->sg.start) { - sg_chain(&msg_pl->sg.data[msg_pl->sg.start], - MAX_SKB_FRAGS - msg_pl->sg.start + 1, + if (msg_pl->sg.end < msg_pl->sg.start) + sg_chain(msg_pl->sg.data, ARRAY_SIZE(msg_pl->sg.data), msg_pl->sg.data); - } i = msg_pl->sg.start; sg_chain(rec->sg_aead_in, 2, &msg_pl->sg.data[i]); -- 2.43.0
2 2
0 0
[PATCH OLK-6.6] netfilter: ebtables: move to two-stage removal scheme
by superdcc97@163.com 26 Jul '26

26 Jul '26
From: Florian Westphal <fw(a)strlen.de> mainline inclusion from mainline-v7.1-rc4 commit b7f0544d86d439cb946515d2ef6a0a75e8626710 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16471 CVE: CVE-2026-64077 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- Like previous patches for x_tables, follow same pattern in ebtables. We can't reuse xt helpers: ebt_table struct layout is incompatible. table->ops assignment is now done while still holding the ebt mutex to make sure we never expose partially-filled table struct. Fixes: 87663c39f898 ("netfilter: ebtables: do not hook tables by default") Reviewed-by: Tristan Madani <tristan(a)talencesecurity.com> Signed-off-by: Florian Westphal <fw(a)strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo(a)netfilter.org> Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com> --- net/bridge/netfilter/ebtable_broute.c | 2 +- net/bridge/netfilter/ebtable_filter.c | 2 +- net/bridge/netfilter/ebtable_nat.c | 2 +- net/bridge/netfilter/ebtables.c | 60 +++++++++++++++++---------- 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c index 8f19253024b0..33d8640d21ac 100644 --- a/net/bridge/netfilter/ebtable_broute.c +++ b/net/bridge/netfilter/ebtable_broute.c @@ -128,8 +128,8 @@ static int __init ebtable_broute_init(void) static void __exit ebtable_broute_fini(void) { - unregister_pernet_subsys(&broute_net_ops); ebt_unregister_template(&broute_table); + unregister_pernet_subsys(&broute_net_ops); } module_init(ebtable_broute_init); diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c index 278f324e6752..fdb988c24916 100644 --- a/net/bridge/netfilter/ebtable_filter.c +++ b/net/bridge/netfilter/ebtable_filter.c @@ -109,8 +109,8 @@ static int __init ebtable_filter_init(void) static void __exit ebtable_filter_fini(void) { - unregister_pernet_subsys(&frame_filter_net_ops); ebt_unregister_template(&frame_filter); + unregister_pernet_subsys(&frame_filter_net_ops); } module_init(ebtable_filter_init); diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c index 9066f7f376d5..8b981b2041b5 100644 --- a/net/bridge/netfilter/ebtable_nat.c +++ b/net/bridge/netfilter/ebtable_nat.c @@ -109,8 +109,8 @@ static int __init ebtable_nat_init(void) static void __exit ebtable_nat_fini(void) { - unregister_pernet_subsys(&frame_nat_net_ops); ebt_unregister_template(&frame_nat); + unregister_pernet_subsys(&frame_nat_net_ops); } module_init(ebtable_nat_init); diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index bc69406d103d..33686a0a1492 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -42,6 +42,7 @@ struct ebt_pernet { struct list_head tables; + struct list_head dead_tables; }; struct ebt_template { @@ -1162,11 +1163,6 @@ static int do_replace(struct net *net, sockptr_t arg, unsigned int len) static void __ebt_unregister_table(struct net *net, struct ebt_table *table) { - mutex_lock(&ebt_mutex); - list_del(&table->list); - mutex_unlock(&ebt_mutex); - audit_log_nfcfg(table->name, AF_BRIDGE, table->private->nentries, - AUDIT_XT_OP_UNREGISTER, GFP_KERNEL); EBT_ENTRY_ITERATE(table->private->entries, table->private->entries_size, ebt_cleanup_entry, net, NULL); if (table->private->nentries) @@ -1267,13 +1263,15 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table, for (i = 0; i < num_ops; i++) ops[i].priv = table; - list_add(&table->list, &ebt_net->tables); - mutex_unlock(&ebt_mutex); - table->ops = ops; ret = nf_register_net_hooks(net, ops, num_ops); - if (ret) + if (ret) { + synchronize_rcu(); __ebt_unregister_table(net, table); + } else { + list_add(&table->list, &ebt_net->tables); + } + mutex_unlock(&ebt_mutex); audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries, AUDIT_XT_OP_REGISTER, GFP_KERNEL); @@ -1339,7 +1337,7 @@ void ebt_unregister_template(const struct ebt_table *t) } EXPORT_SYMBOL(ebt_unregister_template); -static struct ebt_table *__ebt_find_table(struct net *net, const char *name) +void ebt_unregister_table_pre_exit(struct net *net, const char *name) { struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id); struct ebt_table *t; @@ -1348,30 +1346,36 @@ static struct ebt_table *__ebt_find_table(struct net *net, const char *name) list_for_each_entry(t, &ebt_net->tables, list) { if (strcmp(t->name, name) == 0) { + list_move(&t->list, &ebt_net->dead_tables); mutex_unlock(&ebt_mutex); - return t; + nf_unregister_net_hooks(net, t->ops, hweight32(t->valid_hooks)); + return; } } mutex_unlock(&ebt_mutex); - return NULL; -} - -void ebt_unregister_table_pre_exit(struct net *net, const char *name) -{ - struct ebt_table *table = __ebt_find_table(net, name); - - if (table) - nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks)); } EXPORT_SYMBOL(ebt_unregister_table_pre_exit); void ebt_unregister_table(struct net *net, const char *name) { - struct ebt_table *table = __ebt_find_table(net, name); + struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id); + struct ebt_table *t; - if (table) - __ebt_unregister_table(net, table); + mutex_lock(&ebt_mutex); + + list_for_each_entry(t, &ebt_net->dead_tables, list) { + if (strcmp(t->name, name) == 0) { + list_del(&t->list); + audit_log_nfcfg(t->name, AF_BRIDGE, t->private->nentries, + AUDIT_XT_OP_UNREGISTER, GFP_KERNEL); + __ebt_unregister_table(net, t); + mutex_unlock(&ebt_mutex); + return; + } + } + + mutex_unlock(&ebt_mutex); } /* userspace just supplied us with counters */ @@ -2586,11 +2590,21 @@ static int __net_init ebt_pernet_init(struct net *net) struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id); INIT_LIST_HEAD(&ebt_net->tables); + INIT_LIST_HEAD(&ebt_net->dead_tables); return 0; } +static void __net_exit ebt_pernet_exit(struct net *net) +{ + struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id); + + WARN_ON_ONCE(!list_empty(&ebt_net->tables)); + WARN_ON_ONCE(!list_empty(&ebt_net->dead_tables)); +} + static struct pernet_operations ebt_net_ops = { .init = ebt_pernet_init, + .exit = ebt_pernet_exit, .id = &ebt_pernet_id, .size = sizeof(struct ebt_pernet), }; -- 2.43.0
2 1
0 0
[PATCH OLK-6.6 0/2] CVE-2026-63983: netem: fix packet loop on duplicate
by superdcc97@163.com 26 Jul '26

26 Jul '26
From: Dong Chenchen <dongchenchen2(a)huawei.com> This series adapts the upstream fix for CVE-2026-63983 to OLK-6.6. The CVE addresses a packet loop/recursion issue in netem when packet duplication is enabled. The upstream fix uses the skb tc_depth field, which is not present in OLK-6.6, so a prerequisite patch is included to add that field. The prerequisite patch backports the upstream commit that introduced skb->tc_depth (mainline 98b34f3e8c34), adapted to the OLK-6.6 sk_buff layout. The second patch applies the CVE fix itself (mainline 9552b11e3edabc97cfcd9f29103d5afbce7ae183) without further changes. Jamal Hadi Salim (2): net: Introduce skb tc depth field to track packet loops net/sched: fix packet loop on netem when duplicate is on include/linux/skbuff.h | 2 ++ net/sched/sch_netem.c | 7 +++---- 2 files changed, 5 insertions(+), 4 deletions(-) -- 2.43.0
2 3
0 0
[PATCH OLK-6.6] RDMA/umem: Fix truncation for block sizes >= 4G
by Xia Fukun 25 Jul '26

25 Jul '26
From: Jason Gunthorpe <jgg(a)nvidia.com> stable inclusion from stable-v6.6.143 commit 8fe0231adebe086c8a459c790944ac026cd99c6e category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/15827 CVE: CVE-2026-53133 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit 15fe76e23615f502d051ef0768f86babaf08746c ] When the iommu is used the linearization of the mapping can give a single block that is very large split across multiple SG entries. When __rdma_block_iter_next() reassembles the split SG entries it is overflowing the 32 bit stack values and computed the wrong DMA addresses for blocks after the truncation. Use the right types to hold DMA addresses. Link: https://patch.msgid.link/r/1-v1-88303e9e509f+f7-ib_umem_types_jgg@nvidia.com Cc: stable(a)vger.kernel.org Fixes: a808273a495c ("RDMA/verbs: Add a DMA iterator to return aligned contiguous memory blocks") Signed-off-by: Jason Gunthorpe <jgg(a)nvidia.com> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Conflicts: drivers/infiniband/core/iter.c drivers/infiniband/core/verbs.c [Newer versions moved this function to iter.c, this version adapts the changes in verbs.c.] Signed-off-by: Xia Fukun <xiafukun(a)huawei.com> --- drivers/infiniband/core/verbs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index d7eb65988a46..7082fc7899a8 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -3025,8 +3025,8 @@ EXPORT_SYMBOL(__rdma_block_iter_start); bool __rdma_block_iter_next(struct ib_block_iter *biter) { - unsigned int block_offset; - unsigned int delta; + dma_addr_t block_offset; + dma_addr_t delta; if (!biter->__sg_nents || !biter->__sg) return false; -- 2.34.1
2 1
0 0
[patch OLK-6.6] selinux: fix incorrect execmem checks on overlayfs
by Cai Xinchen 25 Jul '26

25 Jul '26
From: Ondrej Mosnacek <omosnace(a)redhat.com> mainline inclusion from mainline-v7.2-rc4 commit 9fe595fad54d4ac6a402edb3f60bec859d52cea6 category: bugfix bugzilla: https://gitcode.com/openeuler/kernel/issues/9112 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- The commit fixing the overlayfs mmap() and mprotect() access checks failed to skip the execmem check in __file_map_prot_check() for the case where the "mounter check" is being performed. This check should be performed only against the credentials of the task that is calling mmap()/mprotect(), since it doesn't pertain to the file itself, but rather just gates the ability of the calling task to get an executable memory mapping in general. The purpose of the "mounter check" is to guard against using an overlayfs mount to gain file access that would otherwise be denied to the mounter. For execmem this is not relevant, as there is no further file access granted based on it (notice that the file's context is not used as the target in the check), so checking it also against the mounter credentials would be incorrect. Fix this by passing a boolean to [__]file_map_prot_check() and selinux_mmap_file_common() that indicates if we are doing the "mounter check" and skiping the execmem check in that case. Since this boolean also indicates if we use current_cred() or the mounter cred as the subject, also remove the "cred" argument from these functions and determine it based on the boolean and the file struct. Cc: stable(a)vger.kernel.org Fixes: 82544d36b172 ("selinux: fix overlayfs mmap() and mprotect() access checks") Signed-off-by: Ondrej Mosnacek <omosnace(a)redhat.com> Reviewed-by: Stephen Smalley <stephen.smalley.work(a)gmail.com> Signed-off-by: Paul Moore <paul(a)paul-moore.com> Signed-off-by: Cai Xinchen <caixinchen1(a)huawei.com> --- security/selinux/hooks.c | 42 +++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 2d9f365022cb..b3d93234a4c3 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3794,9 +3794,9 @@ static int selinux_file_ioctl_compat(struct file *file, unsigned int cmd, static int default_noexec __ro_after_init; -static int __file_map_prot_check(const struct cred *cred, - const struct file *file, unsigned long prot, - bool shared, bool bf_user_file) +static int __file_map_prot_check(const struct file *file, unsigned long prot, + bool shared, bool mounter_check, + bool bf_user_file) { struct inode *inode = NULL; bool prot_exec = prot & PROT_EXEC; @@ -3809,10 +3809,10 @@ static int __file_map_prot_check(const struct cred *cred, inode = file_inode(file); } - if (default_noexec && prot_exec && + if (!mounter_check && default_noexec && prot_exec && (!file || IS_PRIVATE(inode) || (!shared && prot_write))) { int rc; - u32 sid = cred_sid(cred); + u32 sid = current_sid(); /* * We are making executable an anonymous mapping or a private @@ -3825,6 +3825,8 @@ static int __file_map_prot_check(const struct cred *cred, } if (file) { + const struct cred *cred = mounter_check ? + file->f_cred : current_cred(); /* "read" always possible, "write" only if shared */ u32 av = FILE__READ; if (shared && prot_write) @@ -3838,11 +3840,11 @@ static int __file_map_prot_check(const struct cred *cred, return 0; } -static inline int file_map_prot_check(const struct cred *cred, - const struct file *file, - unsigned long prot, bool shared) +static inline int file_map_prot_check(const struct file *file, + unsigned long prot, bool shared, + bool mounter_check) { - return __file_map_prot_check(cred, file, prot, shared, false); + return __file_map_prot_check(file, prot, shared, mounter_check, false); } static int selinux_mmap_addr(unsigned long addr) @@ -3858,12 +3860,14 @@ static int selinux_mmap_addr(unsigned long addr) return rc; } -static int selinux_mmap_file_common(const struct cred *cred, struct file *file, - unsigned long prot, bool shared) +static int selinux_mmap_file_common(struct file *file, unsigned long prot, + bool shared, bool mounter_check) { if (file) { int rc; struct common_audit_data ad; + const struct cred *cred = mounter_check ? + file->f_cred : current_cred(); ad.type = LSM_AUDIT_DATA_FILE; ad.u.file = file; @@ -3872,15 +3876,16 @@ static int selinux_mmap_file_common(const struct cred *cred, struct file *file, return rc; } - return file_map_prot_check(cred, file, prot, shared); + return file_map_prot_check(file, prot, shared, mounter_check); } static int selinux_mmap_file(struct file *file, unsigned long reqprot __always_unused, unsigned long prot, unsigned long flags) { - return selinux_mmap_file_common(current_cred(), file, prot, - (flags & MAP_TYPE) == MAP_SHARED); + return selinux_mmap_file_common(file, prot, + (flags & MAP_TYPE) == MAP_SHARED, + false); } /** @@ -3912,8 +3917,9 @@ static int selinux_mmap_backing_file(struct vm_area_struct *vma, if (vma->vm_flags & VM_EXEC) prot |= PROT_EXEC; - return selinux_mmap_file_common(backing_file->f_cred, backing_file, - prot, vma->vm_flags & VM_SHARED); + return selinux_mmap_file_common(backing_file, prot, + vma->vm_flags & VM_SHARED, + true); } static int selinux_file_mprotect(struct vm_area_struct *vma, @@ -3974,11 +3980,11 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, } } - rc = __file_map_prot_check(cred, file, prot, shared, backing_file); + rc = __file_map_prot_check(file, prot, shared, false, backing_file); if (rc) return rc; if (backing_file) { - rc = file_map_prot_check(file->f_cred, file, prot, shared); + rc = file_map_prot_check(file, prot, shared, true); if (rc) return rc; } -- 2.18.0.huawei.25
1 0
0 0
[PATCH OLK-5.10] bpf: Reject BPF_MAP_TYPE_INODE_STORAGE creation if BPF LSM is uninitialized
by Pu Lehui 25 Jul '26

25 Jul '26
From: Matt Bobrowski <mattbobrowski(a)google.com> mainline inclusion from mainline-v7.2-rc2 commit a6f0643e4f63cfaa0d5d4a69de4f132eac4b8fe4 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16515 CVE: CVE-2026-64192 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- When CONFIG_BPF_LSM=y is set, BPF inode storage maps (BPF_MAP_TYPE_INODE_STORAGE) are compiled into the kernel. However, if the BPF LSM is not explicitly enabled at boot time (e.g. omitted from the "lsm=" boot parameter), lsm_prepare() is never executed for the BPF LSM. Consequently, the BPF inode security blob offset (bpf_lsm_blob_sizes.lbs_inode) is never initialized and remains at its default compiled size of 8 bytes instead of being updated to a valid offset past the reserved struct rcu_head (typically 16 bytes or more). When a privileged user creates and updates a BPF_MAP_TYPE_INODE_STORAGE map, bpf_inode() evaluates inode->i_security + 8. This erroneously aliases the struct rcu_head.func callback pointer at the beginning of the inode->i_security blob. During subsequent map element cleanup or inode destruction, writing NULL to owner_storage clears the queued RCU callback pointer. When rcu_do_batch() later executes the queued callback, it attempts an instruction fetch at address 0x0, triggering an immediate kernel panic. Fix this by introducing a global bpf_lsm_initialized boolean flag marked with __ro_after_init. Set this flag to true inside bpf_lsm_init() when the LSM framework successfully registers the BPF LSM. Gate map allocation in inode_storage_map_alloc() on this flag, returning -EOPNOTSUPP if the BPF LSM is in turn uninitialized. This fail-fast approach prevents userspace from allocating inode storage maps when the supporting BPF LSM infrastructure is absent, avoiding zombie map states. Fixes: 8ea636848aca ("bpf: Implement bpf_local_storage for inodes") Reported-by: oxsignal <awo(a)kakao.com> Signed-off-by: Matt Bobrowski <mattbobrowski(a)google.com> Signed-off-by: Daniel Borkmann <daniel(a)iogearbox.net> Reviewed-by: Emil Tsalapatis <emil(a)etsalapatis.com> Reviewed-by: Amery Hung <ameryhung(a)gmail.com> Link: https://lore.kernel.org/bpf/20260628201103.3624525-1-mattbobrowski@google.c… Conflicts: include/linux/bpf_lsm.h kernel/bpf/bpf_inode_storage.c security/bpf/hooks.c [ctx conflicts] Signed-off-by: Pu Lehui <pulehui(a)huawei.com> --- include/linux/bpf_lsm.h | 4 ++++ kernel/bpf/bpf_inode_storage.c | 10 ++++++++++ security/bpf/hooks.c | 3 +++ 3 files changed, 17 insertions(+) diff --git a/include/linux/bpf_lsm.h b/include/linux/bpf_lsm.h index 272655378f94..4947fc758de8 100644 --- a/include/linux/bpf_lsm.h +++ b/include/linux/bpf_lsm.h @@ -13,6 +13,8 @@ #ifdef CONFIG_BPF_LSM +extern bool bpf_lsm_initialized __ro_after_init; + #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ RET bpf_lsm_##NAME(__VA_ARGS__); #include <linux/lsm_hook_defs.h> @@ -44,6 +46,8 @@ int bpf_lsm_get_retval_range(const struct bpf_prog *prog, struct bpf_retval_range *range); #else /* !CONFIG_BPF_LSM */ +#define bpf_lsm_initialized false + static inline int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog, const struct bpf_prog *prog) { diff --git a/kernel/bpf/bpf_inode_storage.c b/kernel/bpf/bpf_inode_storage.c index a4ac48c7dada..4fd82425feba 100644 --- a/kernel/bpf/bpf_inode_storage.c +++ b/kernel/bpf/bpf_inode_storage.c @@ -223,6 +223,16 @@ static struct bpf_map *inode_storage_map_alloc(union bpf_attr *attr) { struct bpf_local_storage_map *smap; + /* + * Do not allow allocation of BPF_MAP_TYPE_INODE_STORAGE if the BPF LSM + * was not initialized by the LSM framework at boot. Without proper + * initialization, the BPF inode security blob offset remains unprepared, + * causing bpf_inode() to calculate an invalid memory offset and corrupt + * inode->i_security. + */ + if (!bpf_lsm_initialized) + return ERR_PTR(-EOPNOTSUPP); + smap = bpf_local_storage_map_alloc(attr); if (IS_ERR(smap)) return ERR_CAST(smap); diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c index 788667d582ae..bdda0ca174a9 100644 --- a/security/bpf/hooks.c +++ b/security/bpf/hooks.c @@ -6,6 +6,8 @@ #include <linux/lsm_hooks.h> #include <linux/bpf_lsm.h> +bool bpf_lsm_initialized __ro_after_init + static struct security_hook_list bpf_lsm_hooks[] __lsm_ro_after_init = { #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ LSM_HOOK_INIT(NAME, bpf_lsm_##NAME), @@ -17,6 +19,7 @@ static struct security_hook_list bpf_lsm_hooks[] __lsm_ro_after_init = { static int __init bpf_lsm_init(void) { security_add_hooks(bpf_lsm_hooks, ARRAY_SIZE(bpf_lsm_hooks), "bpf"); + bpf_lsm_initialized = true; pr_info("LSM support for eBPF active\n"); return 0; } -- 2.34.1
2 1
0 0
[PATCH OLK-6.6] bpf: Reject BPF_MAP_TYPE_INODE_STORAGE creation if BPF LSM is uninitialized
by Pu Lehui 25 Jul '26

25 Jul '26
From: Matt Bobrowski <mattbobrowski(a)google.com> mainline inclusion from mainline-v7.2-rc2 commit a6f0643e4f63cfaa0d5d4a69de4f132eac4b8fe4 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16515 CVE: CVE-2026-64192 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- When CONFIG_BPF_LSM=y is set, BPF inode storage maps (BPF_MAP_TYPE_INODE_STORAGE) are compiled into the kernel. However, if the BPF LSM is not explicitly enabled at boot time (e.g. omitted from the "lsm=" boot parameter), lsm_prepare() is never executed for the BPF LSM. Consequently, the BPF inode security blob offset (bpf_lsm_blob_sizes.lbs_inode) is never initialized and remains at its default compiled size of 8 bytes instead of being updated to a valid offset past the reserved struct rcu_head (typically 16 bytes or more). When a privileged user creates and updates a BPF_MAP_TYPE_INODE_STORAGE map, bpf_inode() evaluates inode->i_security + 8. This erroneously aliases the struct rcu_head.func callback pointer at the beginning of the inode->i_security blob. During subsequent map element cleanup or inode destruction, writing NULL to owner_storage clears the queued RCU callback pointer. When rcu_do_batch() later executes the queued callback, it attempts an instruction fetch at address 0x0, triggering an immediate kernel panic. Fix this by introducing a global bpf_lsm_initialized boolean flag marked with __ro_after_init. Set this flag to true inside bpf_lsm_init() when the LSM framework successfully registers the BPF LSM. Gate map allocation in inode_storage_map_alloc() on this flag, returning -EOPNOTSUPP if the BPF LSM is in turn uninitialized. This fail-fast approach prevents userspace from allocating inode storage maps when the supporting BPF LSM infrastructure is absent, avoiding zombie map states. Fixes: 8ea636848aca ("bpf: Implement bpf_local_storage for inodes") Reported-by: oxsignal <awo(a)kakao.com> Signed-off-by: Matt Bobrowski <mattbobrowski(a)google.com> Signed-off-by: Daniel Borkmann <daniel(a)iogearbox.net> Reviewed-by: Emil Tsalapatis <emil(a)etsalapatis.com> Reviewed-by: Amery Hung <ameryhung(a)gmail.com> Link: https://lore.kernel.org/bpf/20260628201103.3624525-1-mattbobrowski@google.c… Conflicts: include/linux/bpf_lsm.h kernel/bpf/bpf_inode_storage.c security/bpf/hooks.c [ctx conflicts] Signed-off-by: Pu Lehui <pulehui(a)huawei.com> --- include/linux/bpf_lsm.h | 4 ++++ kernel/bpf/bpf_inode_storage.c | 9 +++++++++ security/bpf/hooks.c | 3 +++ 3 files changed, 16 insertions(+) diff --git a/include/linux/bpf_lsm.h b/include/linux/bpf_lsm.h index aefcd6564251..625f4926da53 100644 --- a/include/linux/bpf_lsm.h +++ b/include/linux/bpf_lsm.h @@ -14,6 +14,8 @@ #ifdef CONFIG_BPF_LSM +extern bool bpf_lsm_initialized __ro_after_init; + #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ RET bpf_lsm_##NAME(__VA_ARGS__); #include <linux/lsm_hook_defs.h> @@ -50,6 +52,8 @@ int bpf_lsm_get_retval_range(const struct bpf_prog *prog, struct bpf_retval_range *range); #else /* !CONFIG_BPF_LSM */ +#define bpf_lsm_initialized false + static inline bool bpf_lsm_is_sleepable_hook(u32 btf_id) { return false; diff --git a/kernel/bpf/bpf_inode_storage.c b/kernel/bpf/bpf_inode_storage.c index 44e8082b88dd..d18bee3eb990 100644 --- a/kernel/bpf/bpf_inode_storage.c +++ b/kernel/bpf/bpf_inode_storage.c @@ -189,6 +189,15 @@ static int notsupp_get_next_key(struct bpf_map *map, void *key, static struct bpf_map *inode_storage_map_alloc(union bpf_attr *attr) { + /* + * Do not allow allocation of BPF_MAP_TYPE_INODE_STORAGE if the BPF LSM + * was not initialized by the LSM framework at boot. Without proper + * initialization, the BPF inode security blob offset remains unprepared, + * causing bpf_inode() to calculate an invalid memory offset and corrupt + * inode->i_security. + */ + if (!bpf_lsm_initialized) + return ERR_PTR(-EOPNOTSUPP); return bpf_local_storage_map_alloc(attr, &inode_cache, false); } diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c index 35933ae53b92..2e9c247c3a63 100644 --- a/security/bpf/hooks.c +++ b/security/bpf/hooks.c @@ -6,6 +6,8 @@ #include <linux/lsm_hooks.h> #include <linux/bpf_lsm.h> +bool bpf_lsm_initialized __ro_after_init; + static struct security_hook_list bpf_lsm_hooks[] __ro_after_init = { #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ LSM_HOOK_INIT(NAME, bpf_lsm_##NAME), @@ -18,6 +20,7 @@ static struct security_hook_list bpf_lsm_hooks[] __ro_after_init = { static int __init bpf_lsm_init(void) { security_add_hooks(bpf_lsm_hooks, ARRAY_SIZE(bpf_lsm_hooks), "bpf"); + bpf_lsm_initialized = true; pr_info("LSM support for eBPF active\n"); return 0; } -- 2.34.1
2 1
0 0
  • ← Newer
  • 1
  • 2
  • 3
  • 4
  • ...
  • 2420
  • Older →

HyperKitty Powered by HyperKitty