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 -----
  • October
  • September
  • August
  • 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

  • 14 participants
  • 25103 discussions
[PATCH openEuler-1.0-LTS] netfilter: nf_conntrack_sip: widen NAT rewrite delta to s32 in sip_help_tcp()
by superdcc97@163.com 09 Oct '26

09 Oct '26
From: Xiang Mei <xmei5(a)asu.edu> mainline inclusion from mainline-v7.2-rc6 commit db3d0e0e5d4bc5ab4fe445b9f413d1b486508ca5 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/17349 CVE: CVE-2026-74569 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- sip_help_tcp() stores the size change of each NAT-rewritten SIP message in s16 diff and accumulates it in s16 tdiff, but a single message can grow by more than S16_MAX while the packet stays under the 65535 enlarge_skb() limit: nf_nat_sip() rewrites every matching URI, and a long Contact list expands the message by tens of kilobytes. diff then wraps, and "datalen = datalen + diff - msglen" yields a huge unsigned datalen, so the next iteration's ct_sip_get_header() reads past the linearized skb tail. Widen diff, tdiff and the seq_adjust hook to s32. Both are bounded by the 65535 byte packet limit, and the seqadj core is already s32 (nf_ct_seqadj_set() takes s32), so no previously accepted input is rejected. BUG: KASAN: use-after-free in ct_sip_get_header (net/netfilter/nf_conntrack_sip.c:464) Read of size 1 at addr ffff888010800000 by task ksoftirqd/1/25 ct_sip_get_header (net/netfilter/nf_conntrack_sip.c:464) sip_help_tcp (net/netfilter/nf_conntrack_sip.c:1694) nf_confirm (net/netfilter/nf_conntrack_proto.c:183) nf_hook_slow (net/netfilter/core.c:619) ip6_output (net/ipv6/ip6_output.c:246) ip6_forward (net/ipv6/ip6_output.c:690) ipv6_rcv (net/ipv6/ip6_input.c:351) __netif_receive_skb_one_core (net/core/dev.c:6212) process_backlog (net/core/dev.c:6676) __napi_poll (net/core/dev.c:7735) net_rx_action (net/core/dev.c:7955) handle_softirqs (kernel/softirq.c:622) run_ksoftirqd (kernel/softirq.c:1076) ... Fixes: f5b321bd37fb ("netfilter: nf_conntrack_sip: add TCP support") Reported-by: Weiming Shi <bestswngs(a)gmail.com> Link: https://patch.msgid.link/netfilter-devel/20260712234201.3213635-1-xmei5@asu… Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Xiang Mei <xmei5(a)asu.edu> Signed-off-by: Pablo Neira Ayuso <pablo(a)netfilter.org> Conflicts: net/netfilter/nf_conntrack_sip.c [context conflicts] Signed-off-by: Dong Chenchen <dongchenchen2(a)huawei.com> --- include/linux/netfilter/nf_conntrack_sip.h | 2 +- net/netfilter/nf_conntrack_sip.c | 2 +- net/netfilter/nf_nat_sip.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h index c7fc38807a33..833054fd491c 100644 --- a/include/linux/netfilter/nf_conntrack_sip.h +++ b/include/linux/netfilter/nf_conntrack_sip.h @@ -116,7 +116,7 @@ struct nf_nat_sip_hooks { unsigned int *datalen); void (*seq_adjust)(struct sk_buff *skb, - unsigned int protoff, s16 off); + unsigned int protoff, s32 off); unsigned int (*expect)(struct sk_buff *skb, unsigned int protoff, diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index c5817df62d79..e08ffc759e7d 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -1576,7 +1576,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, unsigned int matchoff, matchlen, clen; unsigned int msglen, origlen; const char *dptr, *end; - s16 diff, tdiff = 0; + s32 diff, tdiff = 0; int ret = NF_ACCEPT; bool term; diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c index 41dbf9726796..3ff5663e1b97 100644 --- a/net/netfilter/nf_nat_sip.c +++ b/net/netfilter/nf_nat_sip.c @@ -314,7 +314,7 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff, } static void nf_nat_sip_seq_adjust(struct sk_buff *skb, unsigned int protoff, - s16 off) + s32 off) { enum ip_conntrack_info ctinfo; struct nf_conn *ct = nf_ct_get(skb, &ctinfo); -- 2.43.0
2 1
0 0
[PATCH OLK-5.10] tracing: Set the trace clock before registering the histogram trigger
by Tengda Wu 09 Oct '26

09 Oct '26
From: Donggeun Yoo <donggeunyoo.kernel(a)gmail.com> mainline inclusion from mainline-v7.3-rc3 commit 6ede78d0563a2a3ae3e46f9c07cedb5d79645429 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/20176 CVE: CVE-2026-97935 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- hist_register_trigger() puts the trigger on the global named_triggers list in cmd_ops->init(), and only then sets the trace clock: if (data->cmd_ops->init) { ret = data->cmd_ops->init(data); if (ret < 0) goto out; } if (hist_data->enable_timestamps) { ret = tracing_set_clock(file->tr, hist_data->attrs->clock); if (ret) { hist_err(tr, HIST_ERR_SET_CLOCK_FAIL, errpos(clock)); goto out; } The clock string is not checked anywhere before that call, so a named trigger using common_timestamp with an unknown clock fails after it has already become findable. event_hist_trigger_parse() then frees it without taking it off the list, and the next lookup by name reads the freed object: ~# cd /sys/kernel/tracing/events/sched/sched_switch ~# echo 'hist:name=foo:keys=common_pid:ts=common_timestamp:clock=bogus' > trigger bash: echo: write error: Invalid argument ~# echo 'hist:name=foo:keys=common_pid' > trigger BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0 Read of size 8 at addr ffff88800915d760 by task init/1 find_named_trigger+0xac/0xc0 hist_register_trigger+0xc1/0x900 event_hist_trigger_parse+0x3146/0x6af0 event_trigger_write+0xce/0x160 Freed by task 63: kfree+0x154/0x420 trigger_kthread_fn+0xfd/0x160 Set the clock before the trigger is registered, so that nothing which can fail runs after it is published, the way commit 6f86bdeab633 ("tracing: Fix bad hist from corrupting named_triggers list") moved the registration below the rest of the setup. tracing_set_filter_buffering() is reference counted, so the init failure path has to drop the reference that the clock block now takes first. Cc: stable(a)vger.kernel.org Fixes: a4072fe85ba3 ("tracing: Add a clock attribute for hist triggers") Link: https://patch.msgid.link/20260907091415.554535-1-donggeunyoo.kernel@gmail.c… Signed-off-by: Donggeun Yoo <donggeunyoo.kernel(a)gmail.com> Signed-off-by: Steven Rostedt <rostedt(a)goodmis.org> Conflicts: kernel/trace/trace_events_hist.c [Two minimal adaptations are needed: 1) Replace cmd_ops with ops; 2) Replace tracing_set_filter_buffering with tracing_set_time_stamp_abs.] Signed-off-by: Tengda Wu <wutengda2(a)huawei.com> --- kernel/trace/trace_events_hist.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 557b8c28faf4..0fc7c59af276 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -5577,12 +5577,6 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops, data->ops = &event_hist_trigger_named_ops; } - if (data->ops->init) { - ret = data->ops->init(data->ops, data); - if (ret < 0) - goto out; - } - if (hist_data->enable_timestamps) { char *clock = hist_data->attrs->clock; @@ -5595,6 +5589,15 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops, tracing_set_time_stamp_abs(file->tr, true); } + if (data->ops->init) { + ret = data->ops->init(data->ops, data); + if (ret < 0) { + if (hist_data->enable_timestamps) + tracing_set_time_stamp_abs(file->tr, false); + goto out; + } + } + if (named_data) destroy_hist_data(hist_data); -- 2.34.1
2 1
0 0
[PATCH OLK-6.6] nfsd: fix UAF in async copy cancel and shutdown
by Lu Jialin 09 Oct '26

09 Oct '26
From: Jeff Layton <jlayton(a)kernel.org> mainline inclusion from mainline-v7.3-rc1 commit62c0f6eaf050bb9284c1f9cac6ed1770092e6b95 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/18938 CVE: CVE-2026-89675 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- An async copy could be freed or used after free while a teardown caller (OFFLOAD_CANCEL, nfsd4_shutdown_copy, nfsd4_cancel_copy_by_sb) raced the copy kthread: - find_async_copy() bumped copy->refcount but left the copy on clp->async_copies, so the reaper's cleanup_async_copy() could run release_copy_files() concurrently with a cancel/shutdown caller. Both put and NULL nf_src/nf_dst without a common lock, double-putting the nfsd_file and freeing it early. - nfsd4_do_async_copy() set NFSD4_COPY_F_STOPPED before its final uses of the copy (nfsd_update_cmtime_attr() on copy->nf_dst, nfsd4_send_cb_offload()). nfsd4_stop_copy() treats a set STOPPED bit as "kthread done, skip kthread_stop()", so a teardown caller ran release_copy_files() -- which puts and NULLs nf_dst -- while the kthread still dereferenced it (NULL/UAF). - copy->copy_task was never pinned. The one-shot kthread self-reaps on return, so kthread_stop()'s get_task_struct() could touch a freed task_struct. - co_cb is embedded in the copy, but nfsd4_send_cb_offload() held a reference only on the client, so a concurrent teardown could free the copy while the CB_OFFLOAD callback was in flight. Fix the teardown lifetime as a whole: - find_async_copy() unlinks the copy (clear cp_clp, list_del_init) under async_lock; the cancel, shutdown, and sb-cancel paths drop the list-membership reference via nfs4_put_copy() after nfsd4_stop_copy(). Drop the now-redundant list_del fixup from cleanup_async_copy(). - Because unlinking hides the copy from the reaper, its cleanup_async_copy() can no longer remove the copy's s2s_cp_stateids entry; the cancel/shutdown/sb-cancel paths now call nfs4_free_copy_state() themselves (while cp_clp is still valid) so the entry does not dangle at freed memory for the laundromat and manage_cpntf_state() to dereference. - Give the kthread its own reference, taken in nfsd4_copy() before wake_up_process() and dropped at the end of nfsd4_do_async_copy(); call wake_up_process() before list_add(). - Pin the task_struct with get_task_struct() in nfsd4_copy(), released in nfs4_put_copy(), so kthread_stop() is safe whenever the kthread exits. Set NFSD4_COPY_F_STOPPED only in nfsd4_stop_copy(), which now always kthread_stop()s before release_copy_files(); completion is still reported via NFSD4_COPY_F_COMPLETED, so nfsd4_has_active_async_copies() is unaffected. Each teardown caller removes the copy from clp->async_copies first, so kthread_stop() runs exactly once. - Take a copy reference in nfsd4_send_cb_offload(), dropped in nfsd4_cb_offload_release(). The kthread still holds its own reference there, so the refcount_inc() cannot race the final free. - Read cp_clp with smp_load_acquire() to pair with the unordered set_bit()/clear_bit() writers (Documentation/atomic_bitops.rst). Fixes: e0639dc5805a ("NFSD introduce async copy feature") Cc: stable(a)vger.kernel.org Fixes: ac0514f4d198 ("NFSD: Add a laundromat reaper for async copy state") Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Jeff Layton <jlayton(a)kernel.org> Link: https://patch.msgid.link/20260710-nfsd-testing-v3-2-a0ff7db6aa3e@kernel.org Signed-off-by: Chuck Lever <cel(a)kernel.org> Conflicts: fs/nfsd/nfs4proc.c [partial backport of 62c0f6eaf050; adapted so copy_task is assigned only after the kthread_create() IS_ERR() check passes] Signed-off-by: Lu Jialin <lujialin4(a)huawei.com> --- fs/nfsd/nfs4proc.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 546d2a0900ab..d103858a67f6 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1279,6 +1279,9 @@ static void nfs4_put_copy(struct nfsd4_copy *copy) if (!refcount_dec_and_test(&copy->refcount)) return; atomic_dec(&copy->cp_nn->pending_async_copies); + /* Drop the task_struct pinned in nfsd4_copy(); NULL on error paths. */ + if (copy->copy_task) + put_task_struct(copy->copy_task); kfree(copy->cp_src); kfree(copy); } @@ -1820,6 +1823,8 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, memcpy(&copy->fh, &cstate->current_fh.fh_handle, sizeof(struct knfsd_fh)); if (nfsd4_copy_is_async(copy)) { + struct task_struct *task; + async_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); if (!async_copy) goto out_err; @@ -1839,10 +1844,16 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out_err; memcpy(&result->cb_stateid, &async_copy->cp_stateid.cs_stid, sizeof(result->cb_stateid)); - async_copy->copy_task = kthread_create(nfsd4_do_async_copy, - async_copy, "%s", "copy thread"); - if (IS_ERR(async_copy->copy_task)) + task = kthread_create(nfsd4_do_async_copy, async_copy, + "%s", "copy thread"); + if (IS_ERR(task)) goto out_err; + /* + * Pin the task_struct so kthread_stop() is safe even after + * this one-shot kthread exits. Released by nfs4_put_copy(). + */ + get_task_struct(task); + async_copy->copy_task = task; spin_lock(&async_copy->cp_clp->async_lock); list_add(&async_copy->copies, &async_copy->cp_clp->async_copies); -- 2.34.1
2 1
0 0
[PATCH OLK-6.6 0/3] arm64: Fix NMI/DAIF handling in hibernate, suspend and kprobes
by Qinxin Xia 09 Oct '26

09 Oct '26
From: Hongye Lin <linhongye(a)h-partners.com> driver inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/10041 ---------------------------------------------------------------------- arm64: Fix NMI/DAIF handling in hibernate, suspend and kprobes Ada Couprie Diaz (1): arm64: hibernate: mask DAIF before restoring hibernated kernel Vladimir Murzin (2): arm64: suspend: Always initialise PSTATE.ALLINT arm64: kprobes: Disable NMIs arch/arm64/include/asm/daifflags.h | 1 + arch/arm64/include/asm/ptrace.h | 2 +- arch/arm64/kernel/hibernate.c | 12 ++++++++++++ arch/arm64/kernel/probes/kprobes.c | 8 +++++--- 4 files changed, 19 insertions(+), 4 deletions(-) -- 2.33.0
2 4
0 0
[PATCH 0/3] sched/numa: Keep communicating task pairs local on multi-level NUMA
by Zhang Qiao 09 Oct '26

09 Oct '26
On topologies where sched_groups inside a NUMA domain have different weights (e.g. a 4-node Arm system with 3 NUMA domain levels), the NUMA load balancer tears a pair of communicating tasks (lmbench bw_pipe -P 1) apart even on an otherwise idle system: ~760 MB/s when split vs ~1500 MB/s when the pair stays on one node. The unequal weights are a property of the distance matrix: with a non-uniform "diameter 3" NUMA topology, e.g. node 0 1 2 3 0: 10 12 35 37 1: 12 10 37 40 2: 35 37 10 12 3: 37 40 12 10 the kernel builds several NUMA sched_domain levels, and inside a level the groups are built by build_overlap_sched_groups() from the spans of the lower-level domains. Because each distance level covers a different set of nodes, some groups end up spanning two nodes while others span only one, so group_weight differs within a single domain (this is the diameter-3 case already documented in the comment above build_overlap_sched_groups()). Two defects are involved: 1. The imbalance is measured in idle-CPU differences. Between groups of different weight this counts capacity, not load, so an idle system computes a large phantom imbalance that actively splits the pair. Patches 1 and 2 fix the periodic and wake paths by comparing busy CPUs instead (no-op when weights are equal). 2. The floating imbalance tolerance is a fixed 2, which is below the busy-CPU difference the scheduler actually observes for a bare pair (2) plus kernel-thread noise (1-2): 3-4 in any balance snapshot. The split is executed by active balance, since the pair is always running and cannot be passively detached. Patch 3 caps the allowance at 4 (pair + noise) instead of scaling it with imb_numa_nr, whose uncapped use regressed large machines in 0-day testing (unixbench fstime -6.8% / fsdisk-w -26.7%) by letting independent throughput tasks accumulate. Measured on a 4-node Arm server (`lmbench bw_pipe -P 1`). The bandwidth is ~1500 MB/s when the reader/writer pair stays on one NUMA node, but drops to ~700 MB/s if split across nodes. * Upstream: Split in 8/10 runs (~760 MB/s). * Patches 1+2: Split in 4/10 runs (~1170 MB/s). However, running completely alone still resulted in 23/23 splits due to the kernel-thread noise mentioned above. * Patches 1+2+3: Zero splits (0/10 with noise, 0/12 alone). Bandwidth stabilized at ~1484 MB/s. All combinations of numa_balancing on/off and background system load present/removed were covered. On an equal-weight-group topology (2-socket x86 server) patches 1-2 are bit-identical no-ops, and patch 3 only raises the tolerance from 2 to at most 4 (versus 6-12 for the uncapped version rejected by 0-day). This is a reworked version of [1]: - the measurement fix is retained (patch 1, hunk 2 of [1]), and extended to the wake path (patch 2, new); - the threshold change (hunk 1 of [1]) is replaced by a capped allowance in patch 3: the uncapped version let large groups of independent throughput tasks accumulate, which 0-day measured as unixbench fstime -6.8% and fsdisk-w -26.7% [2]; - the dst_running change (hunk 3 of [1]) was dropped; no scenario was observed that requires it. [1] https://lore.kernel.org/all/20240524035438.2701479-1-zhangqiao22@huawei.com/ [2] https://lore.kernel.org/all/202406031516.a1956bdc-oliver.sang@intel.com/ Zhang Qiao (3): sched/numa: Use busy CPUs for imbalance with unequal group weights sched/numa: Use busy CPUs for wake-path imbalance with unequal group weights sched/numa: Cap the floating imbalance allowance at pair size kernel/sched/fair.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) -- 2.18.0
1 3
0 0
[PATCH OLK-6.6] tracing: Fix memory corruption from the histogram stacktrace modifier
by Tengda Wu 09 Oct '26

09 Oct '26
From: Donggeun Yoo <donggeunyoo.kernel(a)gmail.com> stable inclusion from stable-v6.6.158 commit 98da3379cdee343f671dac89b9afbd8b071f2591 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/20177 CVE: CVE-2026-97936 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- commit a5e70ba87ca8ebc79b4e63de302d03b0625fe153 upstream. parse_field() sets HIST_FIELD_FL_STACKTRACE from the ".stacktrace" modifier before it looks the field name up, and nothing afterwards checks that the name resolved to a field which holds a stacktrace. create_hist_field() picks HIST_FIELD_FN_STACK on the strength of the field pointer alone, which reads a __data_loc word from the record and follows its low 16 bits as an offset into the same record. event_hist_trigger() takes the first word there as an entry count and copies that many longs into a 31 entry array: n_entries = *stack; memcpy(entries, ++stack, n_entries * sizeof(unsigned long)); Neither end of that copy is bounded, and the count is whatever the event holds at the offset, so any field will do: # cd /sys/kernel/tracing/events/sched/sched_process_fork # echo 'hist:keys=parent_pid.stacktrace' > trigger # (true) BUG: kernel NULL pointer dereference, address: 0000000000000008 RIP: 0010:rb_insert_color+0x18/0x130 timerqueue_linked_add+0x7e/0xd0 enqueue_hrtimer+0x39/0xb0 __hrtimer_run_queues+0x10f/0x1f0 </IRQ> RIP: 0010:memcpy+0xc/0x30 event_hist_trigger+0x165/0x690 The timer interrupt landed on the rbtree the copy had already run over. No debug options are needed for this; KASAN reports the same write as an out-of-bounds read of 13835058055416381440 bytes. Documentation/trace/histogram.rst already states the rule, "must be a long[] type", so enforce it once the name has been resolved. Names which resolve to no field at all, "hitcount.stacktrace" and the common_* pseudo-fields, are refused for the same reason: they hold no stacktrace to read. Cc: stable(a)vger.kernel.org Fixes: cc5fc8bfc961 ("tracing/histogram: Add stacktrace type") Link: https://patch.msgid.link/20260907155045.692664-2-donggeunyoo.kernel@gmail.c… Signed-off-by: Donggeun Yoo <donggeunyoo.kernel(a)gmail.com> Signed-off-by: Steven Rostedt <rostedt(a)goodmis.org> Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Signed-off-by: Tengda Wu <wutengda2(a)huawei.com> --- kernel/trace/trace_events_hist.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 856d75942581..5d448e5aedfe 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -2318,6 +2318,7 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, struct ftrace_event_field *field = NULL; char *field_name, *modifier, *str; struct trace_array *tr = file->tr; + bool stack_modifier = false; modifier = str = kstrdup(field_str, GFP_KERNEL); if (!modifier) @@ -2340,9 +2341,10 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, *flags |= HIST_FIELD_FL_EXECNAME; else if (strcmp(modifier, "syscall") == 0) *flags |= HIST_FIELD_FL_SYSCALL; - else if (strcmp(modifier, "stacktrace") == 0) + else if (strcmp(modifier, "stacktrace") == 0) { *flags |= HIST_FIELD_FL_STACKTRACE; - else if (strcmp(modifier, "log2") == 0) + stack_modifier = true; + } else if (strcmp(modifier, "log2") == 0) *flags |= HIST_FIELD_FL_LOG2; else if (strcmp(modifier, "usecs") == 0) *flags |= HIST_FIELD_FL_TIMESTAMP_USECS; @@ -2410,6 +2412,12 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, } } } + + if (stack_modifier && + (!field || field->filter_type != FILTER_STACKTRACE)) { + hist_err(tr, HIST_ERR_BAD_FIELD_MODIFIER, errpos(field_str)); + field = ERR_PTR(-EINVAL); + } out: kfree(str); -- 2.34.1
2 1
0 0
[PATCH OLK-6.6] dma-buf: dma-heap: don't publish fd before copy_to_user() succeeds
by Jiacheng Yu 09 Oct '26

09 Oct '26
From: Baineng Shou <shoubaineng(a)gmail.com> mainline inclusion from mainline-v7.3-rc2 commit 30d0aff2c65a277135cfd8ea28fa1ee75e0ea4e0 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/19111 CVE: CVE-2026-89996 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- DMA_HEAP_IOCTL_ALLOC allocates a dma-buf and installs an fd into the caller's fd table via dma_buf_fd() -> fd_install() before dma_heap_ioctl() copies the result back to userspace. If the trailing copy_to_user() fails, userspace never learns the fd number, but the fd (and the underlying dma-buf reference) are already visible to other threads in the same process and are leaked for the lifetime of the process. The obvious "close it on the failure path" fix is unsafe: once fd_install() has run, another thread can already dup() the fd, send it via SCM_RIGHTS, or close() it and let its number be reused, so a subsequent close_fd() from the ioctl path can operate on an unrelated file. This was pointed out by Christian König on v1 [1]. Restructure the allocation path so that fd_install() is the last, unfailable step of a successful ioctl: 1. heap->ops->allocate() creates the dma_buf. 2. get_unused_fd_flags() reserves an fd number in the caller's fd table without publishing it, so no other thread can observe it. 3. copy_to_user() delivers the fd number to userspace; on failure the fd is returned with put_unused_fd() and the dma_buf reference is dropped with dma_buf_put(), leaving no user- visible state behind. 4. dma_buf_fd_install() publishes the fd and emits the trace_dma_buf_fd tracepoint -- from here on the ioctl cannot fail. A new dma_buf_fd_install() helper is introduced in dma-buf.c to wrap fd_install() together with the DMA_BUF_TRACE() call, preserving the export tracing that dma_buf_fd() provides. dma_heap_ioctl_allocate() is refactored to return the struct dma_buf * directly (returning ERR_PTR on failure) so the caller holds the dmabuf reference across steps 3 and 4. The failure at step 3 is easily reachable from userspace: pass a struct dma_heap_allocation_data that lives in a page whose protection is flipped to PROT_READ between copy_from_user() and copy_to_user() (e.g. via mprotect()). Before this change each such ioctl leaks one dmabuf fd; after it, the fd table is unchanged on failure and only /dev/dma_heap/<name> remains open. No UAPI or heap-driver interface change. [1] https://lore.kernel.org/dri-devel/175e98de-f414-47d7-81c1-c0fe0a8f7f62@amd.… Fixes: c02a81fba74f ("dma-buf: Add dma-buf heaps framework") Cc: stable(a)vger.kernel.org Reviewed-by: T.J. Mercier <tjmercier(a)google.com> Acked-by: Christian König <christian.koenig(a)amd.com> Acked-by: Sumit Semwal <sumit.semwal(a)linaro.org> Signed-off-by: Baineng Shou <shoubaineng(a)gmail.com> Link: https://lore.kernel.org/r/20260817050457.1005285-2-shoubaineng@gmail.com Signed-off-by: Christian König <christian.koenig(a)amd.com> Conflicts: drivers/dma-buf/dma-buf.c drivers/dma-buf/dma-heap.c [1. Context conflicts. 2. This tree predates the trace_dma_buf_fd tracepoint, so the new helper drops the DMA_BUF_TRACE() call and only wraps fd_install().] Signed-off-by: Jiacheng Yu <yujiacheng3(a)huawei.com> --- drivers/dma-buf/dma-buf.c | 15 ++++++++ drivers/dma-buf/dma-heap.c | 78 +++++++++++++++++++------------------- include/linux/dma-buf.h | 1 + 3 files changed, 54 insertions(+), 40 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 21916bba77d5..47783225ed02 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -714,6 +714,21 @@ int dma_buf_fd(struct dma_buf *dmabuf, int flags) } EXPORT_SYMBOL_NS_GPL(dma_buf_fd, DMA_BUF); +/** + * dma_buf_fd_install - install a reserved fd for a dma-buf + * @dmabuf: [in] pointer to dma_buf + * @fd: [in] fd reserved with get_unused_fd_flags() + * + * Publishes a previously reserved fd into the caller's fd table. + * Must only be called after all fallible work (e.g. copy_to_user) + * has succeeded, as it cannot be undone safely once called. + */ +void dma_buf_fd_install(struct dma_buf *dmabuf, int fd) +{ + fd_install(fd, dmabuf->file); +} +EXPORT_SYMBOL_NS_GPL(dma_buf_fd_install, DMA_BUF); + /** * dma_buf_get - returns the struct dma_buf related to an fd * @fd: [in] fd associated with the struct dma_buf to be returned diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c index 84ae708fafe7..6acf8aa5c2e8 100644 --- a/drivers/dma-buf/dma-heap.c +++ b/drivers/dma-buf/dma-heap.c @@ -49,33 +49,6 @@ static dev_t dma_heap_devt; static struct class *dma_heap_class; static DEFINE_XARRAY_ALLOC(dma_heap_minors); -static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len, - unsigned int fd_flags, - unsigned int heap_flags) -{ - struct dma_buf *dmabuf; - int fd; - - /* - * Allocations from all heaps have to begin - * and end on page boundaries. - */ - len = PAGE_ALIGN(len); - if (!len) - return -EINVAL; - - dmabuf = heap->ops->allocate(heap, len, fd_flags, heap_flags); - if (IS_ERR(dmabuf)) - return PTR_ERR(dmabuf); - - fd = dma_buf_fd(dmabuf, fd_flags); - if (fd < 0) { - dma_buf_put(dmabuf); - /* just return, as put will call release and that will free */ - } - return fd; -} - static int dma_heap_open(struct inode *inode, struct file *file) { struct dma_heap *heap; @@ -93,30 +66,41 @@ static int dma_heap_open(struct inode *inode, struct file *file) return 0; } -static long dma_heap_ioctl_allocate(struct file *file, void *data) +static struct dma_buf *dma_heap_ioctl_allocate(struct file *file, void *data) { struct dma_heap_allocation_data *heap_allocation = data; struct dma_heap *heap = file->private_data; + struct dma_buf *dmabuf; int fd; + size_t len; if (heap_allocation->fd) - return -EINVAL; + return ERR_PTR(-EINVAL); if (heap_allocation->fd_flags & ~DMA_HEAP_VALID_FD_FLAGS) - return -EINVAL; + return ERR_PTR(-EINVAL); if (heap_allocation->heap_flags & ~DMA_HEAP_VALID_HEAP_FLAGS) - return -EINVAL; + return ERR_PTR(-EINVAL); + + len = PAGE_ALIGN(heap_allocation->len); + if (!len) + return ERR_PTR(-EINVAL); - fd = dma_heap_buffer_alloc(heap, heap_allocation->len, - heap_allocation->fd_flags, - heap_allocation->heap_flags); - if (fd < 0) - return fd; + dmabuf = heap->ops->allocate(heap, len, heap_allocation->fd_flags, + heap_allocation->heap_flags); + if (IS_ERR(dmabuf)) + return dmabuf; + + fd = get_unused_fd_flags(heap_allocation->fd_flags); + if (fd < 0) { + dma_buf_put(dmabuf); + return ERR_PTR(fd); + } heap_allocation->fd = fd; - return 0; + return dmabuf; } static unsigned int dma_heap_ioctl_cmds[] = { @@ -132,6 +116,8 @@ static long dma_heap_ioctl(struct file *file, unsigned int ucmd, unsigned int in_size, out_size, drv_size, ksize; int nr = _IOC_NR(ucmd); int ret = 0; + int fd; + struct dma_buf *dmabuf; if (nr >= ARRAY_SIZE(dma_heap_ioctl_cmds)) return -EINVAL; @@ -168,15 +154,27 @@ static long dma_heap_ioctl(struct file *file, unsigned int ucmd, switch (kcmd) { case DMA_HEAP_IOCTL_ALLOC: - ret = dma_heap_ioctl_allocate(file, kdata); + dmabuf = dma_heap_ioctl_allocate(file, kdata); + if (IS_ERR(dmabuf)) { + ret = PTR_ERR(dmabuf); + break; + } + + fd = ((struct dma_heap_allocation_data *)kdata)->fd; + if (copy_to_user((void __user *)arg, kdata, out_size) != 0) { + put_unused_fd(fd); + dma_buf_put(dmabuf); + ret = -EFAULT; + } else { + dma_buf_fd_install(dmabuf, fd); + } + break; default: ret = -ENOTTY; goto err; } - if (copy_to_user((void __user *)arg, kdata, out_size) != 0) - ret = -EFAULT; err: if (kdata != stack_kdata) kfree(kdata); diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 3f31baa3293f..e29dcab1d2d1 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -606,6 +606,7 @@ void dma_buf_unpin(struct dma_buf_attachment *attach); struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info); int dma_buf_fd(struct dma_buf *dmabuf, int flags); +void dma_buf_fd_install(struct dma_buf *dmabuf, int fd); struct dma_buf *dma_buf_get(int fd); void dma_buf_put(struct dma_buf *dmabuf); -- 2.34.1
2 1
0 0
[PATCH OLK-6.6] virtio-net: Ensure that TCP packets don't overflow gso_segs
by Jiacheng Yu 09 Oct '26

09 Oct '26
From: Alice Mikityanska <alice(a)isovalent.com> stable inclusion from stable-v6.6.157 commit 339f47ae04dcc6b5a730dd6bc70dddc8937c3260 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/19380 CVE: CVE-2026-90063 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit c27c449d455aafd9018a3cbab150f1c42c87923f ] The user can specify any gso_size in a packet crafted with an AF_PACKET PACKET_VNET_HDR socket, even smaller than TCP_MIN_GSO_SIZE = 8. At the same time, GSO_MAX_SIZE = 8 * GSO_MAX_SEGS = 8 * 65535. When the user crafts a packet with gso_size < 8, there is a risk for partial GSO to overflow the 16-bit gso_segs field when dividing the SKB length by gso_size. Adjust gso_size of TCP packets to be at least TCP_MIN_GSO_SIZE = 8. Keep gso_size of UDP GSO packets, as gso_size=1 is valid and explicitly tested at tools/testing/selftests/net/tun.c:649. Fixes: 7c6d2ecbda83 ("net: be more gentle about silly gso requests coming from user") Signed-off-by: Alice Mikityanska <alice(a)isovalent.com> Suggested-by: Eric Dumazet <edumazet(a)google.com> Link: https://patch.msgid.link/20260822120117.1163423-2-alice.kernel@fastmail.im Signed-off-by: Paolo Abeni <pabeni(a)redhat.com> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Signed-off-by: Jiacheng Yu <yujiacheng3(a)huawei.com> --- include/linux/virtio_net.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index 02a9f4dc594d0..d2cab10569644 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -6,6 +6,7 @@ #include <linux/ip.h> #include <linux/ipv6.h> #include <linux/udp.h> +#include <net/tcp.h> #include <uapi/linux/tcp.h> #include <uapi/linux/virtio_net.h> @@ -178,6 +179,9 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, if (skb->ip_summed == CHECKSUM_PARTIAL && skb->csum_offset != offsetof(struct tcphdr, check)) return -EINVAL; + + BUILD_BUG_ON(TCP_MIN_GSO_SIZE * GSO_MAX_SEGS < GSO_MAX_SIZE); + gso_size = max(gso_size, TCP_MIN_GSO_SIZE); break; } -- 2.34.1
2 1
0 0
[PATCH OLK-6.6] drm/amd/display: Resize MST HDCP per-connector arrays to 32
by Jiacheng Yu 09 Oct '26

09 Oct '26
From: Harry Wentland <harry.wentland(a)amd.com> mainline inclusion from mainline-v7.3-rc1 commit 261e0fe4e2c99f687114b64b10b98db964b475f4 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/19462 CVE: CVE-2026-90289 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- AMDGPU_DM_MAX_DISPLAY_INDEX is 31. It suggest a maximum number of 32 connectors. But the way it's used is like MAX_DISPLAY_COUNT. Hence we're off by one with DRM core, which supports a max of 32 connectors. Rename AMDGPU_DM_MAX_DISPLAY_INDEX to AMDGPU_DM_MAX_DISPLAY_COUNT to match its actual use, and increase the size to 32 to match the originally intended size. Fixes: 82986fd631fa ("drm/amd/display: save restore hdcp state when display is unplugged from mst hub") Assisted-by: Copilot:claude-opus-4.8 Reviewed-by: Alex Hung <alex.hung(a)amd.com> Signed-off-by: Harry Wentland <harry.wentland(a)amd.com> Signed-off-by: Roman Li <roman.li(a)amd.com> Tested-by: Dan Wheeler <daniel.wheeler(a)amd.com> Signed-off-by: Alex Deucher <alexander.deucher(a)amd.com> Conflicts: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h [This tree still defines AMDGPU_DM_MAX_DISPLAY_INDEX in amdgpu_dm.h and amdgpu_dm_hdcp.h includes amdgpu.h instead of carrying the minimal self-contained declarations added upstream, so rename the macro in amdgpu_dm.h and keep the original include block in amdgpu_dm_hdcp.h.] Signed-off-by: Jiacheng Yu <yujiacheng3(a)huawei.com> --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 2 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 10 +++++----- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 8d4f2cadb915..6fc5b1e4be46 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -43,7 +43,7 @@ * in amdgpu_dm_kms.h file */ -#define AMDGPU_DM_MAX_DISPLAY_INDEX 31 +#define AMDGPU_DM_MAX_DISPLAY_COUNT 32 #define AMDGPU_DM_MAX_CRTC 6 diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index 9aa247e4b5be..56a348b65f06 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -258,7 +258,7 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_inde cancel_delayed_work(&hdcp_w->property_validate_dwork); - for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX; conn_index++) { + for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_COUNT; conn_index++) { hdcp_w->encryption_status[conn_index] = MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF; if (hdcp_w->aconnector[conn_index]) { @@ -309,7 +309,7 @@ static void event_property_update(struct work_struct *work) struct drm_connector *connector; struct drm_connector_state *conn_state; - for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX; conn_index++) { + for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_COUNT; conn_index++) { aconnector = hdcp_work->aconnector[conn_index]; if (!aconnector) @@ -379,7 +379,7 @@ static void event_property_validate(struct work_struct *work) mutex_lock(&hdcp_work->mutex); - for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX; + for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_COUNT; conn_index++) { aconnector = hdcp_work->aconnector[conn_index]; @@ -764,10 +764,10 @@ struct hdcp_workqueue *hdcp_create_workqueue(struct amdgpu_device *adev, memset(hdcp_work[i].aconnector, 0, sizeof(struct amdgpu_dm_connector *) * - AMDGPU_DM_MAX_DISPLAY_INDEX); + AMDGPU_DM_MAX_DISPLAY_COUNT); memset(hdcp_work[i].encryption_status, 0, sizeof(enum mod_hdcp_encryption_status) * - AMDGPU_DM_MAX_DISPLAY_INDEX); + AMDGPU_DM_MAX_DISPLAY_COUNT); } cp_psp->funcs.update_stream_config = update_config; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h index 69b445b011c8..d18c4cc7d69f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h @@ -43,7 +43,7 @@ struct hdcp_workqueue { struct delayed_work callback_dwork; struct delayed_work watchdog_timer_dwork; struct delayed_work property_validate_dwork; - struct amdgpu_dm_connector *aconnector[AMDGPU_DM_MAX_DISPLAY_INDEX]; + struct amdgpu_dm_connector *aconnector[AMDGPU_DM_MAX_DISPLAY_COUNT]; struct mutex mutex; struct mod_hdcp hdcp; @@ -51,7 +51,7 @@ struct hdcp_workqueue { struct mod_hdcp_display display; struct mod_hdcp_link link; - enum mod_hdcp_encryption_status encryption_status[AMDGPU_DM_MAX_DISPLAY_INDEX]; + enum mod_hdcp_encryption_status encryption_status[AMDGPU_DM_MAX_DISPLAY_COUNT]; /* when display is unplugged from mst hub, connctor will be * destroyed within dm_dp_mst_connector_destroy. connector * hdcp perperties, like type, undesired, desired, enabled, @@ -61,9 +61,9 @@ struct hdcp_workqueue { * will be retrieved from hdcp_work within dm_dp_mst_get_modes */ /* un-desired, desired, enabled */ - unsigned int content_protection[AMDGPU_DM_MAX_DISPLAY_INDEX]; + unsigned int content_protection[AMDGPU_DM_MAX_DISPLAY_COUNT]; /* hdcp1.x, hdcp2.x */ - unsigned int hdcp_content_type[AMDGPU_DM_MAX_DISPLAY_INDEX]; + unsigned int hdcp_content_type[AMDGPU_DM_MAX_DISPLAY_COUNT]; uint8_t max_link; -- 2.34.1
2 1
0 0
[PATCH OLK-5.10] software node: Fix software_node_get_reference_args() with index -1
by Jiacheng Yu 09 Oct '26

09 Oct '26
From: Alban Bedel <alban.bedel(a)lht.dlh.de> stable inclusion from stable-v5.10.270 commit 6cde06887487b4febd14658c9a246616abcc0097 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/19187 CVE: CVE-2026-93046 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit ba3dedcf3bd47017307595a7e54924198f018246 ] The bounds check for the index passed to software_node_get_reference_args() was failing when passed UINT_MAX, this in turn would lead to an out of bound access in the property array. Fix the bound check to also cover the UINT_MAX case. Fixes: 31e4e12e0e960 ("software node: Correct a OOB check in software_node_get_reference_args()") Reported-by: Sashiko <sashiko-bot(a)kernel.org> Closes: https://lore.kernel.org/linux-devicetree/20260611103904.7CB131F00893@smtp.k… Signed-off-by: Alban Bedel <alban.bedel(a)lht.dlh.de> Link: https://patch.msgid.link/20260611164005.2930205-1-alban.bedel@lht.dlh.de Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Signed-off-by: Jiacheng Yu <yujiacheng3(a)huawei.com> --- drivers/base/swnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index 89b53ca086d6..e11e71532019 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -508,7 +508,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode, if (prop->is_inline) return -EINVAL; - if ((index + 1) * sizeof(*ref) > prop->length) + if (index >= prop->length / sizeof(*ref)) return -ENOENT; ref_array = prop->pointer; -- 2.34.1
2 1
0 0
  • ← Newer
  • 1
  • 2
  • 3
  • 4
  • ...
  • 2511
  • Older →

HyperKitty Powered by HyperKitty