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
  • ----- 2025 -----
  • 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

  • 52 participants
  • 18282 discussions
[PATCH openEuler-1.0-LTS] tracing: Make sure trace_printk() can output as soon as it can be used
by Tengda Wu 29 Mar '25

29 Mar '25
From: "Steven Rostedt (Google)" <rostedt(a)goodmis.org> stable inclusion from stable-v4.19.272 commit b94d7c7654356860dd7719120c7d15ba38b6162a category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBWVXX CVE: CVE-2023-53007 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- commit 3bb06eb6e9acf7c4a3e1b5bc87aed398ff8e2253 upstream. Currently trace_printk() can be used as soon as early_trace_init() is called from start_kernel(). But if a crash happens, and "ftrace_dump_on_oops" is set on the kernel command line, all you get will be: [ 0.456075] <idle>-0 0dN.2. 347519us : Unknown type 6 [ 0.456075] <idle>-0 0dN.2. 353141us : Unknown type 6 [ 0.456075] <idle>-0 0dN.2. 358684us : Unknown type 6 This is because the trace_printk() event (type 6) hasn't been registered yet. That gets done via an early_initcall(), which may be early, but not early enough. Instead of registering the trace_printk() event (and other ftrace events, which are not trace events) via an early_initcall(), have them registered at the same time that trace_printk() can be used. This way, if there is a crash before early_initcall(), then the trace_printk()s will actually be useful. Link: https://lkml.kernel.org/r/20230104161412.019f6c55@gandalf.local.home Cc: stable(a)vger.kernel.org Cc: Masami Hiramatsu <mhiramat(a)kernel.org> Fixes: e725c731e3bb1 ("tracing: Split tracing initialization into two for early initialization") Reported-by: "Joel Fernandes (Google)" <joel(a)joelfernandes.org> Tested-by: Joel Fernandes (Google) <joel(a)joelfernandes.org> Signed-off-by: Steven Rostedt (Google) <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.c | 2 ++ kernel/trace/trace.h | 1 + kernel/trace/trace_output.c | 3 +-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 64fd3c3f84f2..161cd058662c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -8648,6 +8648,8 @@ void __init early_trace_init(void) static_key_enable(&tracepoint_printk_key.key); } tracer_alloc_buffers(); + + init_events(); } void __init trace_init(void) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index d05230d21cf5..00e73361c65c 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -1509,6 +1509,7 @@ extern void trace_event_enable_cmd_record(bool enable); extern void trace_event_enable_tgid_record(bool enable); extern int event_trace_init(void); +extern int init_events(void); extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr); extern int event_trace_del_tracer(struct trace_array *tr); diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 6e6cc64faa38..62015d62dd6f 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -1395,7 +1395,7 @@ static struct trace_event *events[] __initdata = { NULL }; -__init static int init_events(void) +__init int init_events(void) { struct trace_event *event; int i, ret; @@ -1413,4 +1413,3 @@ __init static int init_events(void) return 0; } -early_initcall(init_events); -- 2.34.1
2 1
0 0
[PATCH openEuler-1.0-LTS] trace_events_hist: add check for return value of 'create_hist_field'
by Tengda Wu 29 Mar '25

29 Mar '25
From: Natalia Petrova <n.petrova(a)fintech.ru> stable inclusion from stable-v4.19.272 commit d2d1ada58e7cc100b8d7d6b082d19321ba4a700a category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBWVXP CVE: CVE-2023-53005 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- commit 8b152e9150d07a885f95e1fd401fc81af202d9a4 upstream. Function 'create_hist_field' is called recursively at trace_events_hist.c:1954 and can return NULL-value that's why we have to check it to avoid null pointer dereference. Found by Linux Verification Center (linuxtesting.org) with SVACE. Link: https://lkml.kernel.org/r/20230111120409.4111-1-n.petrova@fintech.ru Cc: stable(a)vger.kernel.org Fixes: 30350d65ac56 ("tracing: Add variable support to hist triggers") Signed-off-by: Natalia Petrova <n.petrova(a)fintech.ru> Signed-off-by: Steven Rostedt (Google) <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 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 2f57eb241ac9..af376cf4ba9a 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -2234,6 +2234,8 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, unsigned long fl = flags & ~HIST_FIELD_FL_LOG2; hist_field->fn = hist_field_log2; hist_field->operands[0] = create_hist_field(hist_data, field, fl, NULL); + if (!hist_field->operands[0]) + goto free; hist_field->size = hist_field->operands[0]->size; hist_field->type = kstrdup(hist_field->operands[0]->type, GFP_KERNEL); if (!hist_field->type) -- 2.34.1
2 1
0 0
[PATCH OLK-5.10] usb: gadget: f_tcm: Don't free command immediately
by Xiongfeng Wang 29 Mar '25

29 Mar '25
From: Thinh Nguyen <Thinh.Nguyen(a)synopsys.com> stable inclusion from stable-v5.10.235 commit 38229c35a6d7875697dfb293356407330cfcd23e category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBREC7 CVE: CVE-2025-21816 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- commit c225d006a31949d673e646d585d9569bc28feeb9 upstream. Don't prematurely free the command. Wait for the status completion of the sense status. It can be freed then. Otherwise we will double-free the command. Fixes: cff834c16d23 ("usb-gadget/tcm: Convert to TARGET_SCF_ACK_KREF I/O krefs") Cc: stable(a)vger.kernel.org Signed-off-by: Thinh Nguyen <Thinh.Nguyen(a)synopsys.com> Link: https://lore.kernel.org/r/ae919ac431f16275e05ec819bdffb3ac5f44cbe1.17338765… Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Signed-off-by: Wang Hai <wanghai38(a)huawei.com> Signed-off-by: Xiongfeng Wang <wangxiongfeng2(a)huawei.com> --- drivers/usb/gadget/function/f_tcm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index 5a2e9ce2bc352..caa23265fae4c 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -1068,7 +1068,6 @@ static void usbg_cmd_work(struct work_struct *work) out: transport_send_check_condition_and_sense(se_cmd, TCM_UNSUPPORTED_SCSI_OPCODE, 1); - transport_generic_free_cmd(&cmd->se_cmd, 0); } static struct usbg_cmd *usbg_get_cmd(struct f_uas *fu, @@ -1199,7 +1198,6 @@ static void bot_cmd_work(struct work_struct *work) out: transport_send_check_condition_and_sense(se_cmd, TCM_UNSUPPORTED_SCSI_OPCODE, 1); - transport_generic_free_cmd(&cmd->se_cmd, 0); } static int bot_submit_command(struct f_uas *fu, -- 2.20.1
2 1
0 0
[PATCH openEuler-1.0-LTS] drbd: Fix five use after free bugs in get_initial_state
by Xiaomeng Zhang 29 Mar '25

29 Mar '25
From: Lv Yunlong <lyl2019(a)mail.ustc.edu.cn> stable inclusion from stable-v5.10.111 commit 594205b4936771a250f9d141e7e0fff21c3dd2d9 bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBX1EN Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit aadb22ba2f656581b2f733deb3a467c48cc618f6 ] In get_initial_state, it calls notify_initial_state_done(skb,..) if cb->args[5]==1. If genlmsg_put() failed in notify_initial_state_done(), the skb will be freed by nlmsg_free(skb). Then get_initial_state will goto out and the freed skb will be used by return value skb->len, which is a uaf bug. What's worse, the same problem goes even further: skb can also be freed in the notify_*_state_change -> notify_*_state calls below. Thus 4 additional uaf bugs happened. My patch lets the problem callee functions: notify_initial_state_done and notify_*_state_change return an error code if errors happen. So that the error codes could be propagated and the uaf bugs can be avoid. v2 reports a compilation warning. This v3 fixed this warning and built successfully in my local environment with no additional warnings. v2: https://lore.kernel.org/patchwork/patch/1435218/ Fixes: a29728463b254 ("drbd: Backport the "events2" command") Signed-off-by: Lv Yunlong <lyl2019(a)mail.ustc.edu.cn> Reviewed-by: Christoph Böhmwalder <christoph.boehmwalder(a)linbit.com> Signed-off-by: Jens Axboe <axboe(a)kernel.dk> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Signed-off-by: Wang Hai <wanghai38(a)huawei.com> Signed-off-by: Xiaomeng Zhang <zhangxiaomeng13(a)huawei.com> --- drivers/block/drbd/drbd_int.h | 8 ++--- drivers/block/drbd/drbd_nl.c | 41 ++++++++++++++++---------- drivers/block/drbd/drbd_state.c | 18 +++++------ drivers/block/drbd/drbd_state_change.h | 8 ++--- 4 files changed, 42 insertions(+), 33 deletions(-) diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index e35a234b0a8f..4f66cf6879fd 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1688,22 +1688,22 @@ struct sib_info { }; void drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib); -extern void notify_resource_state(struct sk_buff *, +extern int notify_resource_state(struct sk_buff *, unsigned int, struct drbd_resource *, struct resource_info *, enum drbd_notification_type); -extern void notify_device_state(struct sk_buff *, +extern int notify_device_state(struct sk_buff *, unsigned int, struct drbd_device *, struct device_info *, enum drbd_notification_type); -extern void notify_connection_state(struct sk_buff *, +extern int notify_connection_state(struct sk_buff *, unsigned int, struct drbd_connection *, struct connection_info *, enum drbd_notification_type); -extern void notify_peer_device_state(struct sk_buff *, +extern int notify_peer_device_state(struct sk_buff *, unsigned int, struct drbd_peer_device *, struct peer_device_info *, diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 5b15ffd0c7f5..5a80453be553 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -4598,7 +4598,7 @@ static int nla_put_notification_header(struct sk_buff *msg, return drbd_notification_header_to_skb(msg, &nh, true); } -void notify_resource_state(struct sk_buff *skb, +int notify_resource_state(struct sk_buff *skb, unsigned int seq, struct drbd_resource *resource, struct resource_info *resource_info, @@ -4640,16 +4640,17 @@ void notify_resource_state(struct sk_buff *skb, if (err && err != -ESRCH) goto failed; } - return; + return 0; nla_put_failure: nlmsg_free(skb); failed: drbd_err(resource, "Error %d while broadcasting event. Event seq:%u\n", err, seq); + return err; } -void notify_device_state(struct sk_buff *skb, +int notify_device_state(struct sk_buff *skb, unsigned int seq, struct drbd_device *device, struct device_info *device_info, @@ -4689,16 +4690,17 @@ void notify_device_state(struct sk_buff *skb, if (err && err != -ESRCH) goto failed; } - return; + return 0; nla_put_failure: nlmsg_free(skb); failed: drbd_err(device, "Error %d while broadcasting event. Event seq:%u\n", err, seq); + return err; } -void notify_connection_state(struct sk_buff *skb, +int notify_connection_state(struct sk_buff *skb, unsigned int seq, struct drbd_connection *connection, struct connection_info *connection_info, @@ -4738,16 +4740,17 @@ void notify_connection_state(struct sk_buff *skb, if (err && err != -ESRCH) goto failed; } - return; + return 0; nla_put_failure: nlmsg_free(skb); failed: drbd_err(connection, "Error %d while broadcasting event. Event seq:%u\n", err, seq); + return err; } -void notify_peer_device_state(struct sk_buff *skb, +int notify_peer_device_state(struct sk_buff *skb, unsigned int seq, struct drbd_peer_device *peer_device, struct peer_device_info *peer_device_info, @@ -4788,13 +4791,14 @@ void notify_peer_device_state(struct sk_buff *skb, if (err && err != -ESRCH) goto failed; } - return; + return 0; nla_put_failure: nlmsg_free(skb); failed: drbd_err(peer_device, "Error %d while broadcasting event. Event seq:%u\n", err, seq); + return err; } void notify_helper(enum drbd_notification_type type, @@ -4845,7 +4849,7 @@ void notify_helper(enum drbd_notification_type type, err, seq); } -static void notify_initial_state_done(struct sk_buff *skb, unsigned int seq) +static int notify_initial_state_done(struct sk_buff *skb, unsigned int seq) { struct drbd_genlmsghdr *dh; int err; @@ -4859,11 +4863,12 @@ static void notify_initial_state_done(struct sk_buff *skb, unsigned int seq) if (nla_put_notification_header(skb, NOTIFY_EXISTS)) goto nla_put_failure; genlmsg_end(skb, dh); - return; + return 0; nla_put_failure: nlmsg_free(skb); pr_err("Error %d sending event. Event seq:%u\n", err, seq); + return err; } static void free_state_changes(struct list_head *list) @@ -4890,6 +4895,7 @@ static int get_initial_state(struct sk_buff *skb, struct netlink_callback *cb) unsigned int seq = cb->args[2]; unsigned int n; enum drbd_notification_type flags = 0; + int err = 0; /* There is no need for taking notification_mutex here: it doesn't matter if the initial state events mix with later state chage @@ -4898,32 +4904,32 @@ static int get_initial_state(struct sk_buff *skb, struct netlink_callback *cb) cb->args[5]--; if (cb->args[5] == 1) { - notify_initial_state_done(skb, seq); + err = notify_initial_state_done(skb, seq); goto out; } n = cb->args[4]++; if (cb->args[4] < cb->args[3]) flags |= NOTIFY_CONTINUES; if (n < 1) { - notify_resource_state_change(skb, seq, state_change->resource, + err = notify_resource_state_change(skb, seq, state_change->resource, NOTIFY_EXISTS | flags); goto next; } n--; if (n < state_change->n_connections) { - notify_connection_state_change(skb, seq, &state_change->connections[n], + err = notify_connection_state_change(skb, seq, &state_change->connections[n], NOTIFY_EXISTS | flags); goto next; } n -= state_change->n_connections; if (n < state_change->n_devices) { - notify_device_state_change(skb, seq, &state_change->devices[n], + err = notify_device_state_change(skb, seq, &state_change->devices[n], NOTIFY_EXISTS | flags); goto next; } n -= state_change->n_devices; if (n < state_change->n_devices * state_change->n_connections) { - notify_peer_device_state_change(skb, seq, &state_change->peer_devices[n], + err = notify_peer_device_state_change(skb, seq, &state_change->peer_devices[n], NOTIFY_EXISTS | flags); goto next; } @@ -4938,7 +4944,10 @@ static int get_initial_state(struct sk_buff *skb, struct netlink_callback *cb) cb->args[4] = 0; } out: - return skb->len; + if (err) + return err; + else + return skb->len; } int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb) diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index b452359b6aae..1474250f9440 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c @@ -1549,7 +1549,7 @@ int drbd_bitmap_io_from_worker(struct drbd_device *device, return rv; } -void notify_resource_state_change(struct sk_buff *skb, +int notify_resource_state_change(struct sk_buff *skb, unsigned int seq, struct drbd_resource_state_change *resource_state_change, enum drbd_notification_type type) @@ -1562,10 +1562,10 @@ void notify_resource_state_change(struct sk_buff *skb, .res_susp_fen = resource_state_change->susp_fen[NEW], }; - notify_resource_state(skb, seq, resource, &resource_info, type); + return notify_resource_state(skb, seq, resource, &resource_info, type); } -void notify_connection_state_change(struct sk_buff *skb, +int notify_connection_state_change(struct sk_buff *skb, unsigned int seq, struct drbd_connection_state_change *connection_state_change, enum drbd_notification_type type) @@ -1576,10 +1576,10 @@ void notify_connection_state_change(struct sk_buff *skb, .conn_role = connection_state_change->peer_role[NEW], }; - notify_connection_state(skb, seq, connection, &connection_info, type); + return notify_connection_state(skb, seq, connection, &connection_info, type); } -void notify_device_state_change(struct sk_buff *skb, +int notify_device_state_change(struct sk_buff *skb, unsigned int seq, struct drbd_device_state_change *device_state_change, enum drbd_notification_type type) @@ -1589,10 +1589,10 @@ void notify_device_state_change(struct sk_buff *skb, .dev_disk_state = device_state_change->disk_state[NEW], }; - notify_device_state(skb, seq, device, &device_info, type); + return notify_device_state(skb, seq, device, &device_info, type); } -void notify_peer_device_state_change(struct sk_buff *skb, +int notify_peer_device_state_change(struct sk_buff *skb, unsigned int seq, struct drbd_peer_device_state_change *p, enum drbd_notification_type type) @@ -1606,7 +1606,7 @@ void notify_peer_device_state_change(struct sk_buff *skb, .peer_resync_susp_dependency = p->resync_susp_dependency[NEW], }; - notify_peer_device_state(skb, seq, peer_device, &peer_device_info, type); + return notify_peer_device_state(skb, seq, peer_device, &peer_device_info, type); } static void broadcast_state_change(struct drbd_state_change *state_change) @@ -1614,7 +1614,7 @@ static void broadcast_state_change(struct drbd_state_change *state_change) struct drbd_resource_state_change *resource_state_change = &state_change->resource[0]; bool resource_state_has_changed; unsigned int n_device, n_connection, n_peer_device, n_peer_devices; - void (*last_func)(struct sk_buff *, unsigned int, void *, + int (*last_func)(struct sk_buff *, unsigned int, void *, enum drbd_notification_type) = NULL; void *uninitialized_var(last_arg); diff --git a/drivers/block/drbd/drbd_state_change.h b/drivers/block/drbd/drbd_state_change.h index ba80f612d6ab..d5b0479bc9a6 100644 --- a/drivers/block/drbd/drbd_state_change.h +++ b/drivers/block/drbd/drbd_state_change.h @@ -44,19 +44,19 @@ extern struct drbd_state_change *remember_old_state(struct drbd_resource *, gfp_ extern void copy_old_to_new_state_change(struct drbd_state_change *); extern void forget_state_change(struct drbd_state_change *); -extern void notify_resource_state_change(struct sk_buff *, +extern int notify_resource_state_change(struct sk_buff *, unsigned int, struct drbd_resource_state_change *, enum drbd_notification_type type); -extern void notify_connection_state_change(struct sk_buff *, +extern int notify_connection_state_change(struct sk_buff *, unsigned int, struct drbd_connection_state_change *, enum drbd_notification_type type); -extern void notify_device_state_change(struct sk_buff *, +extern int notify_device_state_change(struct sk_buff *, unsigned int, struct drbd_device_state_change *, enum drbd_notification_type type); -extern void notify_peer_device_state_change(struct sk_buff *, +extern int notify_peer_device_state_change(struct sk_buff *, unsigned int, struct drbd_peer_device_state_change *, enum drbd_notification_type type); -- 2.34.1
2 1
0 0
[PATCH OLK-5.10 0/2] Push 2 self-developed patches to OLK-5.10
by Xiaomeng Zhang 29 Mar '25

29 Mar '25
*** BLURB HERE *** Xiaomeng Zhang (2): x86: reboot: Initialize the printk locks to avoid deadlock printk: Skip log flush in NMI context when logbuf_lock is held arch/x86/kernel/reboot.c | 1 + kernel/printk/printk_safe.c | 4 ++++ 2 files changed, 5 insertions(+) -- 2.34.1
2 3
0 0
[PATCH OLK-5.10 0/2] Push 2 self-developed patches to OLK-5.10
by Xiaomeng Zhang 29 Mar '25

29 Mar '25
*** BLURB HERE *** Xiaomeng Zhang (2): x86: reboot: Initialize the printk locks to avoid deadlock printk: Skip log flush in NMI context when logbuf_lock is held arch/x86/kernel/reboot.c | 1 + kernel/printk/printk_safe.c | 4 ++++ 2 files changed, 5 insertions(+) -- 2.34.1
2 3
0 0
[PATCH OLK-6.6] fs/dcache: fix bad unlock balance in shrink_dentry_list()
by Baokun Li 29 Mar '25

29 Mar '25
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IBW902 -------------------------------- Inside shrink_lock_dentry(), if we can't lock the parent, we unlock the dentry and wait for the parent lock. Once we get the parent lock, we lock the dentry again. After locking the dentry a second time, we only check d_lockref.count and don't see if d_inode changed. But during that lock gap, d_inode may be modified. If the inode changes, the inode in the dentry isn't locked. However, in dentry_unlink_inode(), we unlock the inode no matter what. Then, we will get the following Oops: ------------[ cut here ]------------ pvqspinlock: lock 0xff438c8e84836be0 has corrupted value 0x0! WARNING: CPU: 1 PID: 370 at kernel/locking/qspinlock_paravirt.h:498 CPU: 1 PID: 370 Comm: bash Not tainted 5.10.0 #2008 RIP: 0010:__pv_queued_spin_unlock_slowpath+0xbf/0xd0 Call Trace: __raw_callee_save___pv_queued_spin_unlock_slowpath+0x11/0x24 .slowpath+0x9/0x16 dentry_unlink_inode+0x91/0x120 __dentry_kill+0xf3/0x1c0 shrink_dentry_list+0x4b/0xe0 prune_dcache_sb+0x52/0x80 super_cache_scan+0x133/0x1f0 do_shrink_slab+0x14a/0x2f0 Here's how concurrency might trigger this issue: P1 | P2 --------------------------------------------- prune_dcache_sb shrink_dentry_list spin_lock(&dentry->d_lock) shrink_lock_dentry /* Negative dentry, therefore no inode to lock. ref 0 */ spin_trylock(&parent->d_lock) / try lock failed / spin_unlock(&dentry->d_lock) lookup_open __d_lookup spin_lock(&dentry->d_lock) dentry->d_lockref.count++ /* ref 1 */ spin_unlock(&dentry->d_lock) /* Negative dentry, just create the file */ xfs_generic_create d_instantiate spin_lock(&inode->i_lock) __d_instantiate spin_lock(&dentry->d_lock) __d_set_inode_and_type dentry->d_inode = inode spin_unlock(&dentry->d_lock) spin_unlock(&inode->i_lock) syscall_exit_to_user_mode /* Task exit. */ __fput dput fast_dput spin_lock(&dentry->d_lock) retain_dentry dentry->d_lockref.count-- /* ref 0 */ spin_unlock(&dentry->d_lock) spin_lock(&parent->d_lock) spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED) /* d_inode has been changed but is not locked. */ __dentry_kill dentry_unlink_inode spin_unlock(&dentry->d_lock) spin_unlock(&inode->i_lock) /* Attempt to unlock an unlocked inode. */ /* WARNING: bad unlock balance in dentry_unlink_inode */ Therefore, add the missing d_inode check to avoid this issue. Fixes: 3b3f09f48ba7 ("get rid of trylock loop in locking dentries on shrink list") Signed-off-by: Baokun Li <libaokun1(a)huawei.com> --- fs/dcache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/dcache.c b/fs/dcache.c index 3e0b9abbf4d8..fe9140b0d0eb 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1238,7 +1238,7 @@ static bool shrink_lock_dentry(struct dentry *dentry) goto out; } spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); - if (likely(!dentry->d_lockref.count)) + if (likely(!dentry->d_lockref.count && inode == dentry->d_inode)) return true; spin_unlock(&parent->d_lock); out: -- 2.46.1
2 1
0 0
[PATCH OLK-5.10] fs/dcache: fix bad unlock balance in shrink_dentry_list()
by Baokun Li 29 Mar '25

29 Mar '25
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IBW902 -------------------------------- Inside shrink_lock_dentry(), if we can't lock the parent, we unlock the dentry and wait for the parent lock. Once we get the parent lock, we lock the dentry again. After locking the dentry a second time, we only check d_lockref.count and don't see if d_inode changed. But during that lock gap, d_inode may be modified. If the inode changes, the inode in the dentry isn't locked. However, in dentry_unlink_inode(), we unlock the inode no matter what. Then, we will get the following Oops: ------------[ cut here ]------------ pvqspinlock: lock 0xff438c8e84836be0 has corrupted value 0x0! WARNING: CPU: 1 PID: 370 at kernel/locking/qspinlock_paravirt.h:498 CPU: 1 PID: 370 Comm: bash Not tainted 5.10.0 #2008 RIP: 0010:__pv_queued_spin_unlock_slowpath+0xbf/0xd0 Call Trace: __raw_callee_save___pv_queued_spin_unlock_slowpath+0x11/0x24 .slowpath+0x9/0x16 dentry_unlink_inode+0x91/0x120 __dentry_kill+0xf3/0x1c0 shrink_dentry_list+0x4b/0xe0 prune_dcache_sb+0x52/0x80 super_cache_scan+0x133/0x1f0 do_shrink_slab+0x14a/0x2f0 Here's how concurrency might trigger this issue: P1 | P2 --------------------------------------------- prune_dcache_sb shrink_dentry_list spin_lock(&dentry->d_lock) shrink_lock_dentry /* Negative dentry, therefore no inode to lock. ref 0 */ spin_trylock(&parent->d_lock) / try lock failed / spin_unlock(&dentry->d_lock) lookup_open __d_lookup spin_lock(&dentry->d_lock) dentry->d_lockref.count++ /* ref 1 */ spin_unlock(&dentry->d_lock) /* Negative dentry, just create the file */ xfs_generic_create d_instantiate spin_lock(&inode->i_lock) __d_instantiate spin_lock(&dentry->d_lock) __d_set_inode_and_type dentry->d_inode = inode spin_unlock(&dentry->d_lock) spin_unlock(&inode->i_lock) syscall_exit_to_user_mode /* Task exit. */ __fput dput fast_dput spin_lock(&dentry->d_lock) retain_dentry dentry->d_lockref.count-- /* ref 0 */ spin_unlock(&dentry->d_lock) spin_lock(&parent->d_lock) spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED) /* d_inode has been changed but is not locked. */ __dentry_kill dentry_unlink_inode spin_unlock(&dentry->d_lock) spin_unlock(&inode->i_lock) /* Attempt to unlock an unlocked inode. */ /* WARNING: bad unlock balance in dentry_unlink_inode */ Therefore, add the missing d_inode check to avoid this issue. Fixes: 3b3f09f48ba7 ("get rid of trylock loop in locking dentries on shrink list") Signed-off-by: Baokun Li <libaokun1(a)huawei.com> --- fs/dcache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/dcache.c b/fs/dcache.c index 5dccce5bc8c1..d36bb8fc2c41 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1174,7 +1174,7 @@ static bool shrink_lock_dentry(struct dentry *dentry) goto out; } spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); - if (likely(!dentry->d_lockref.count)) + if (likely(!dentry->d_lockref.count && inode == dentry->d_inode)) return true; spin_unlock(&parent->d_lock); out: -- 2.46.1
2 1
0 0
[PATCH openEuler-1.0-LTS] fs/dcache: fix bad unlock balance in shrink_dentry_list()
by Baokun Li 29 Mar '25

29 Mar '25
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IBW902 CVE: NA -------------------------------- Inside shrink_lock_dentry(), if we can't lock the parent, we unlock the dentry and wait for the parent lock. Once we get the parent lock, we lock the dentry again. After locking the dentry a second time, we only check d_lockref.count and don't see if d_inode changed. But during that lock gap, d_inode may be modified. If the inode changes, the inode in the dentry isn't locked. However, in dentry_unlink_inode(), we unlock the inode no matter what. Then, we will get the following Oops: ------------[ cut here ]------------ pvqspinlock: lock 0xff438c8e84836be0 has corrupted value 0x0! WARNING: CPU: 1 PID: 370 at kernel/locking/qspinlock_paravirt.h:498 CPU: 1 PID: 370 Comm: bash Not tainted 5.10.0 #2008 RIP: 0010:__pv_queued_spin_unlock_slowpath+0xbf/0xd0 Call Trace: __raw_callee_save___pv_queued_spin_unlock_slowpath+0x11/0x24 .slowpath+0x9/0x16 dentry_unlink_inode+0x91/0x120 __dentry_kill+0xf3/0x1c0 shrink_dentry_list+0x4b/0xe0 prune_dcache_sb+0x52/0x80 super_cache_scan+0x133/0x1f0 do_shrink_slab+0x14a/0x2f0 Here's how concurrency might trigger this issue: P1 | P2 --------------------------------------------- prune_dcache_sb shrink_dentry_list spin_lock(&dentry->d_lock) shrink_lock_dentry /* Negative dentry, therefore no inode to lock. ref 0 */ spin_trylock(&parent->d_lock) / try lock failed / spin_unlock(&dentry->d_lock) lookup_open __d_lookup spin_lock(&dentry->d_lock) dentry->d_lockref.count++ /* ref 1 */ spin_unlock(&dentry->d_lock) /* Negative dentry, just create the file */ xfs_generic_create d_instantiate spin_lock(&inode->i_lock) __d_instantiate spin_lock(&dentry->d_lock) __d_set_inode_and_type dentry->d_inode = inode spin_unlock(&dentry->d_lock) spin_unlock(&inode->i_lock) syscall_exit_to_user_mode /* Task exit. */ __fput dput fast_dput spin_lock(&dentry->d_lock) retain_dentry dentry->d_lockref.count-- /* ref 0 */ spin_unlock(&dentry->d_lock) spin_lock(&parent->d_lock) spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED) /* d_inode has been changed but is not locked. */ __dentry_kill dentry_unlink_inode spin_unlock(&dentry->d_lock) spin_unlock(&inode->i_lock) /* Attempt to unlock an unlocked inode. */ /* WARNING: bad unlock balance in dentry_unlink_inode */ Therefore, add the missing d_inode check to avoid this issue. Fixes: 3b3f09f48ba7 ("get rid of trylock loop in locking dentries on shrink list") Signed-off-by: Baokun Li <libaokun1(a)huawei.com> --- fs/dcache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/dcache.c b/fs/dcache.c index 926df08eeb0c..35f82d69d2b9 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1118,7 +1118,7 @@ static bool shrink_lock_dentry(struct dentry *dentry) goto out; } spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); - if (likely(!dentry->d_lockref.count)) + if (likely(!dentry->d_lockref.count && inode == dentry->d_inode)) return true; spin_unlock(&parent->d_lock); out: -- 2.46.1
2 1
0 0
[PATCH openEuler-1.0-LTS] firmware: arm_scmi: Fix list protocols enumeration in the base protocol
by Gu Bowen 29 Mar '25

29 Mar '25
From: Cristian Marussi <cristian.marussi(a)arm.com> stable inclusion from stable-v4.19.247 commit 444a2d27fe9867d0da4b28fc45b793f32e099ab8 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP2JX CVE: CVE-2022-49451 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit 8009120e0354a67068e920eb10dce532391361d0 ] While enumerating protocols implemented by the SCMI platform using BASE_DISCOVER_LIST_PROTOCOLS, the number of returned protocols is currently validated in an improper way since the check employs a sum between unsigned integers that could overflow and cause the check itself to be silently bypassed if the returned value 'loop_num_ret' is big enough. Fix the validation avoiding the addition. Link: https://lore.kernel.org/r/20220330150551.2573938-4-cristian.marussi@arm.com Fixes: b6f20ff8bd94 ("firmware: arm_scmi: add common infrastructure and support for base protocol") Signed-off-by: Cristian Marussi <cristian.marussi(a)arm.com> Signed-off-by: Sudeep Holla <sudeep.holla(a)arm.com> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Signed-off-by: Gu Bowen <gubowen5(a)huawei.com> --- drivers/firmware/arm_scmi/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c index 204390297f4b..95d892db0dff 100644 --- a/drivers/firmware/arm_scmi/base.c +++ b/drivers/firmware/arm_scmi/base.c @@ -164,7 +164,7 @@ static int scmi_base_implementation_list_get(const struct scmi_handle *handle, break; loop_num_ret = le32_to_cpu(*num_ret); - if (tot_num_ret + loop_num_ret > MAX_PROTOCOLS_IMP) { + if (loop_num_ret > MAX_PROTOCOLS_IMP - tot_num_ret) { dev_err(dev, "No. of Protocol > MAX_PROTOCOLS_IMP"); break; } -- 2.25.1
2 1
0 0
  • ← Newer
  • 1
  • ...
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • ...
  • 1829
  • Older →

HyperKitty Powered by HyperKitty