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

  • 20 participants
  • 24620 discussions
[PATCH openEuler-1.0-LTS] ipv4: validate IPV4_DEVCONF attributes properly
by JiangJieHua 03 Sep '26

03 Sep '26
hulk inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/9803 CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- syzbot reported a UBSAN undefined behavior issue in vif_delete(): UBSAN: Undefined behaviour in net/ipv4/ipmr.c:720:43 signed integer overflow: -2147483648 - 1 cannot be represented in type 'int' When vif_delete() is called with vifi = -2147483648 (INT_MIN), the operation "vifi - 1" causes a signed integer overflow, which is undefined behavior in C. This occurs because the function does not validate the vifi range before using it as an array index. Fix by adding a proper range check at the beginning of vif_delete() to ensure vifi falls within [0, maxvif) before any arithmetic operation is performed. This prevents the overflow and eliminates the UBSAN warning. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: JiangJieHua <jiangjiehua1(a)huawei.com> --- net/ipv4/devinet.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 64f0fa0be370e..acf60f0a01a4a 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1796,6 +1796,9 @@ static int inet_validate_link_af(const struct net_device *dev, if (cfgid <= 0 || cfgid > IPV4_DEVCONF_MAX) return -EINVAL; + + if (cfgid == IPV4_DEVCONF_MC_FORWARDING) + return -EINVAL; } } -- 2.33.8
2 1
0 0
[PATCH openEuler-1.0-LTS] ipv4: validate IPV4_DEVCONF attributes properly
by JiangJieHua 03 Sep '26

03 Sep '26
hulk inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/9803 CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- syzbot reported a UBSAN undefined behavior issue in vif_delete(): UBSAN: Undefined behaviour in net/ipv4/ipmr.c:720:43 signed integer overflow: -2147483648 - 1 cannot be represented in type 'int' When vif_delete() is called with vifi = -2147483648 (INT_MIN), the operation "vifi - 1" causes a signed integer overflow, which is undefined behavior in C. This occurs because the function does not validate the vifi range before using it as an array index. Fix by adding a proper range check at the beginning of vif_delete() to ensure vifi falls within [0, maxvif) before any arithmetic operation is performed. This prevents the overflow and eliminates the UBSAN warning. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: JiangJieHua <jiangjiehua1(a)huawei.com> --- net/ipv4/devinet.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 64f0fa0be370e..acf60f0a01a4a 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1796,6 +1796,9 @@ static int inet_validate_link_af(const struct net_device *dev, if (cfgid <= 0 || cfgid > IPV4_DEVCONF_MAX) return -EINVAL; + + if (cfgid == IPV4_DEVCONF_MC_FORWARDING) + return -EINVAL; } } -- 2.33.8
2 1
0 0
[PATCH openEuler-1.0-LTS] ipv4: validate IPV4_DEVCONF attributes properly
by JiangJieHua 03 Sep '26

03 Sep '26
hulk inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/9803 CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- syzbot reported a UBSAN undefined behavior issue in vif_delete(): UBSAN: Undefined behaviour in net/ipv4/ipmr.c:720:43 signed integer overflow: -2147483648 - 1 cannot be represented in type 'int' When vif_delete() is called with vifi = -2147483648 (INT_MIN), the operation "vifi - 1" causes a signed integer overflow, which is undefined behavior in C. This occurs because the function does not validate the vifi range before using it as an array index. Fix by adding a proper range check at the beginning of vif_delete() to ensure vifi falls within [0, maxvif) before any arithmetic operation is performed. This prevents the overflow and eliminates the UBSAN warning. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: JiangJieHua <jiangjiehua1(a)huawei.com> Therefore, this self-developed adaptation adopts an equivalent manual validation approach: add checks for key attributes in inet_validate_link_af(), reject read-only attributes (e.g., mc_forwarding) by returning -EINVAL, preventing them from being modified via netlink. This approach aligns with the upstream fix's objective, does not introduce additional kernel ABI changes, and has no impact on existing netlink users. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: JiangJieHua <jiangjiehua1(a)huawei.com> --- net/ipv4/devinet.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 64f0fa0be370e..acf60f0a01a4a 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1796,6 +1796,9 @@ static int inet_validate_link_af(const struct net_device *dev, if (cfgid <= 0 || cfgid > IPV4_DEVCONF_MAX) return -EINVAL; + + if (cfgid == IPV4_DEVCONF_MC_FORWARDING) + return -EINVAL; } } -- 2.33.8
2 1
0 0
[PATCH OLK-6.6 0/4] smb: client: backport fixes for CVE-2026-72031
by Lu Chentao 03 Sep '26

03 Sep '26
Backport four upstream smb client fixes required to address CVE-2026-72031 on OLK-6.6. Lu Chentao (4): [OLK-6.6] cifs: prevent readdir from changing file size due to stale directory metadata [OLK-6.6] cifs: fix cifsFileInfo leak on kmalloc failure in deferred close drain paths [OLK-6.6] cifs: consolidate time_last_write stamp into _cifsFileInfo_put() [OLK-6.6] cifs: fix time_last_write stamp placement in setattr/truncate paths fs/smb/client/cifsfs.c | 1 + fs/smb/client/cifsglob.h | 1 + fs/smb/client/file.c | 65 ++++++++++++++++++++++++++++++++++++---- fs/smb/client/inode.c | 25 +++++++++++++++- fs/smb/client/misc.c | 27 +++++++++++++---- 5 files changed, 106 insertions(+), 13 deletions(-) -- 2.52.0
2 5
0 0
[PATCH openEuler-1.0-LTS] ext4: validate readdir offset before accessing dirent
by Yao Kai 03 Sep '26

03 Sep '26
hulk inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/9553 CVE: NA ------------------------ A corrupted directory can trigger the following KASAN report when ext4_readdir() resumes from an invalid position: BUG: KASAN: use-after-free in __ext4_check_dir_entry+0x5ef/0x820 Read of size 2 at addr ffff88810a646000 by task repro_linear/509 Call Trace: <TASK> dump_stack_lvl+0x53/0x70 print_report+0xd0/0x630 kasan_report+0xce/0x100 __ext4_check_dir_entry+0x5ef/0x820 ext4_readdir+0xcde/0x2b70 iterate_dir+0x1a1/0x520 __x64_sys_getdents64+0x12b/0x220 do_syscall_64+0xf9/0x540 entry_SYSCALL_64_after_hwframe+0x77/0x7f </TASK> KASAN reports use-after-free because the out-of-bounds access lands in an adjacent freed page. The directory buffer itself is still referenced. ext4_dir_llseek() invalidates the directory cookie so that ext4_readdir() rescans directory entries from the start of the block. The rescan checks only the lower bound of rec_len before advancing. A corrupted rec_len can therefore place the offset where the block has insufficient space for a complete directory entry. The rescan itself may dereference that truncated entry, or the main loop may pass it to __ext4_check_dir_entry(). The latter reads de->rec_len before validating the range. For example: block offset 0 4092 4096 |---- de1.rec_len = 4092 -----|----| de2.inode | de2.rec_len ^ OOB, reported as UAF de2 starts at offset 4092 in this 4 KiB block. Its four-byte inode fits in the block, but its rec_len starts at offset 4096 and crosses the boundary. The minimum safe length is inode-dependent. Encrypted and casefolded directory entries need eight additional hash bytes, while a valid metadata checksum tail is only 12 bytes. Cache the metadata checksum feature state and derive the minimum directory entry length from the on-disk format. Use it to bound both the rescan and the offset passed to the main loop. Report an offset in a truncated block tail and skip the remainder of the block, while continuing to accept an offset exactly at the block boundary. Reported-by: syzbot+5322c5c260eb44d209ed(a)syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=5322c5c260eb44d209ed Fixes: ac27a0ec112a ("[PATCH] ext4: initial copy of files from ext3") Signed-off-by: Yao Kai <yaokai34(a)huawei.com> Reviewed-by: Zhihao Cheng <chengzhihao1(a)huawei.com> Reviewed-by: Jan Kara <jack(a)suse.cz> Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com> --- fs/ext4/dir.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 5def57966807..9c5ff45bfd6b 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -216,7 +216,9 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx) * dirent right now. Scan from the start of the block * to make sure. */ if (!inode_eq_iversion(inode, file->f_version)) { - for (i = 0; i < sb->s_blocksize && i < offset; ) { + for (i = 0; + i <= sb->s_blocksize - EXT4_DIR_REC_LEN(1) && + i < offset;) { de = (struct ext4_dir_entry_2 *) (bh->b_data + i); /* It's too expensive to do a full @@ -237,6 +239,16 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx) file->f_version = inode_query_iversion(inode); } + if (unlikely(offset < sb->s_blocksize && + offset > sb->s_blocksize - EXT4_DIR_REC_LEN(1))) { + EXT4_ERROR_FILE(file, bh->b_blocknr, + "bad entry in directory: %s - offset=%u, size=%lu", + "directory entry too close to block end", + offset, sb->s_blocksize); + ctx->pos = round_up(ctx->pos, sb->s_blocksize); + goto next_block; + } + while (ctx->pos < inode->i_size && offset < sb->s_blocksize) { de = (struct ext4_dir_entry_2 *) (bh->b_data + offset); @@ -282,6 +294,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx) ctx->pos += ext4_rec_len_from_disk(de->rec_len, sb->s_blocksize); } +next_block: if ((ctx->pos < inode->i_size) && !dir_relax_shared(inode)) goto done; brelse(bh); -- 2.43.0
2 1
0 0
[PATCH openEuler-1.0-LTS] perf sched: Fix register_pid() overflow, strcpy, and BUG_ON
by Gu Bowen 03 Sep '26

03 Sep '26
From: Arnaldo Carvalho de Melo <acme(a)redhat.com> mainline inclusion from mainline-v7.2-rc1 commit 5949d339f5ec98752d56dcd4e36f619a59d513a5 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/18115 CVE: CVE-2026-80671 Reference: https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/comm… -------------------------------- register_pid() has several issues when processing untrusted perf.data: 1. Integer overflow: (pid + 1) * sizeof(struct task_desc *) can wrap to a small value on 32-bit systems when pid is large (e.g. 0x40000000), causing realloc to return a tiny buffer followed by out-of-bounds writes in the initialization loop. 2. Heap buffer overflow: strcpy(task->comm, comm) copies the untrusted comm string into a fixed 20-byte COMM_LEN buffer with no length check. 3. BUG_ON on allocation failure: perf.data is untrusted input, so allocation failures should be handled gracefully rather than killing the process. 4. Realloc of sched->tasks assigned directly back, leaking the old pointer on failure; nr_tasks incremented before the realloc, leaving corrupted state on failure. Cap pid at PID_MAX_LIMIT (4194304, matching the kernel's maximum on 64-bit), replace strcpy with strlcpy, guard against NULL comm, replace BUG_ON with NULL returns using safe realloc patterns, and add NULL checks in callers that dereference the result. Fixes: ec156764d424 ("perf sched: Import schedbench.c") Reported-by: sashiko-bot <sashiko-bot(a)kernel.org> Cc: Ingo Molnar <mingo(a)elte.hu> Assisted-by: Claude:claude-opus-4.6 Signed-off-by: Arnaldo Carvalho de Melo <acme(a)redhat.com> Conflicts: tools/perf/builtin-sched.c [Context conflicts.] Signed-off-by: Gu Bowen <gubowen5(a)huawei.com> --- tools/perf/builtin-sched.c | 40 ++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 8927952a6d26..ff664763602b 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -43,6 +43,7 @@ #define COMM_LEN 20 #define SYM_LEN 129 #define MAX_PID 1024000 +#define PID_MAX_LIMIT 4194304 /* kernel limit on 64-bit */ struct sched_atom; @@ -435,17 +436,28 @@ static void add_sched_event_sleep(struct perf_sched *sched, struct task_desc *ta static struct task_desc *register_pid(struct perf_sched *sched, unsigned long pid, const char *comm) { - struct task_desc *task; + struct task_desc *task, **tasks_p; static int pid_max; + /* perf.data is untrusted — cap pid to prevent overflow in size calculations */ + if (pid >= PID_MAX_LIMIT) { + pr_err("pid %lu exceeds limit %d, skipping\n", pid, PID_MAX_LIMIT); + return NULL; + } + if (sched->pid_to_task == NULL) { if (sysctl__read_int("kernel/pid_max", &pid_max) < 0) pid_max = MAX_PID; - BUG_ON((sched->pid_to_task = calloc(pid_max, sizeof(struct task_desc *))) == NULL); + sched->pid_to_task = calloc(pid_max, sizeof(struct task_desc *)); + if (sched->pid_to_task == NULL) + return NULL; } if (pid >= (unsigned long)pid_max) { - BUG_ON((sched->pid_to_task = realloc(sched->pid_to_task, (pid + 1) * - sizeof(struct task_desc *))) == NULL); + void *p = realloc(sched->pid_to_task, (pid + 1) * sizeof(struct task_desc *)); + + if (p == NULL) + return NULL; + sched->pid_to_task = p; while (pid >= (unsigned long)pid_max) sched->pid_to_task[pid_max++] = NULL; } @@ -456,9 +468,11 @@ static struct task_desc *register_pid(struct perf_sched *sched, return task; task = zalloc(sizeof(*task)); + if (task == NULL) + return NULL; task->pid = pid; - task->nr = sched->nr_tasks; - strcpy(task->comm, comm); + if (comm) + strlcpy(task->comm, comm, sizeof(task->comm)); /* * every task starts in sleeping state - this gets ignored * if there's no wakeup pointing to this sleep state: @@ -466,10 +480,12 @@ static struct task_desc *register_pid(struct perf_sched *sched, add_sched_event_sleep(sched, task, 0, 0); sched->pid_to_task[pid] = task; - sched->nr_tasks++; - sched->tasks = realloc(sched->tasks, sched->nr_tasks * sizeof(struct task_desc *)); - BUG_ON(!sched->tasks); - sched->tasks[task->nr] = task; + tasks_p = realloc(sched->tasks, (sched->nr_tasks + 1) * sizeof(struct task_desc *)); + if (!tasks_p) + return NULL; + sched->tasks = tasks_p; + sched->tasks[sched->nr_tasks] = task; + task->nr = sched->nr_tasks++; if (verbose > 0) printf("registered task #%ld, PID %ld (%s)\n", sched->nr_tasks, pid, comm); @@ -813,6 +829,8 @@ replay_wakeup_event(struct perf_sched *sched, waker = register_pid(sched, sample->tid, "<unknown>"); wakee = register_pid(sched, pid, comm); + if (waker == NULL || wakee == NULL) + return -1; add_sched_event_wakeup(sched, waker, sample->time, wakee); return 0; @@ -855,6 +873,8 @@ static int replay_switch_event(struct perf_sched *sched, prev = register_pid(sched, prev_pid, prev_comm); next = register_pid(sched, next_pid, next_comm); + if (prev == NULL || next == NULL) + return -1; sched->cpu_last_switched[cpu] = timestamp; -- 2.43.0
2 1
0 0
[PATCH OLK-5.10] openvswitch: fix GSO userspace truncation underflow
by Yi Yang 03 Sep '26

03 Sep '26
From: Kyle Zeng <kylebot(a)openai.com> stable inclusion from stable-v5.10.265 commit 50a6a85f3d6b1d22d8436848606cdef5d2c490b4 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/16932 CVE: CVE-2026-68123 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id… -------------------------------- [ Upstream commit 4032f8ed10fcb84d41c508dfb04be96589f78dfe ] OVS_ACTION_ATTR_TRUNC currently stores a delta from the original skb length in OVS_CB(skb)->cutlen. When a later userspace action segments a GSO skb, queue_gso_packets() reuses that delta for each smaller segment. A segment can then reach queue_userspace_packet() with cutlen greater than skb->len, underflowing the length passed to skb_zerocopy(). Store the maximum preserved length instead and bound each consumer against the current skb length. Use U32_MAX as the no-truncation sentinel so the value remains valid if skb geometry changes before a consumer handles it. Fixes: f2a4d086ed4c ("openvswitch: Add packet truncation support.") Cc: stable(a)vger.kernel.org Assisted-by: Codex:gpt-5.5 Signed-off-by: Kyle Zeng <kylebot(a)openai.com> Reviewed-by: Ilya Maximets <i.maximets(a)ovn.org> Reviewed-by: Aaron Conole <aconole(a)redhat.com> Link: https://patch.msgid.link/20260707221635.27489-1-kylebot@openai.com Signed-off-by: Paolo Abeni <pabeni(a)redhat.com> [5.10.y supports neither OVS_ACTION_ATTR_PSAMPLE nor OVS drop reasons] Signed-off-by: Ilya Maximets <i.maximets(a)ovn.org> Signed-off-by: Sasha Levin <sashal(a)kernel.org> Conflicts: net/openvswitch/actions.c [The two parameters of the max function are of inconsistent types.] Signed-off-by: Yi Yang <yiyang13(a)huawei.com> --- net/openvswitch/actions.c | 15 +++++---------- net/openvswitch/datapath.c | 25 ++++++++++++++----------- net/openvswitch/datapath.h | 2 +- net/openvswitch/vport.c | 2 +- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index a02ea493c269..cdf7696d2a20 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -918,12 +918,8 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port, u16 mru = OVS_CB(skb)->mru; u32 cutlen = OVS_CB(skb)->cutlen; - if (unlikely(cutlen > 0)) { - if (skb->len - cutlen > ovs_mac_header_len(key)) - pskb_trim(skb, skb->len - cutlen); - else - pskb_trim(skb, ovs_mac_header_len(key)); - } + if (unlikely(cutlen < skb->len)) + pskb_trim(skb, max(cutlen, (u32)ovs_mac_header_len(key))); if (likely(!mru || (skb->len <= mru + vport->dev->hard_header_len))) { @@ -1299,22 +1295,21 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, clone = skb_clone(skb, GFP_ATOMIC); if (clone) do_output(dp, clone, port, key); - OVS_CB(skb)->cutlen = 0; + OVS_CB(skb)->cutlen = U32_MAX; break; } case OVS_ACTION_ATTR_TRUNC: { struct ovs_action_trunc *trunc = nla_data(a); - if (skb->len > trunc->max_len) - OVS_CB(skb)->cutlen = skb->len - trunc->max_len; + OVS_CB(skb)->cutlen = trunc->max_len; break; } case OVS_ACTION_ATTR_USERSPACE: output_userspace(dp, skb, key, a, attr, len, OVS_CB(skb)->cutlen); - OVS_CB(skb)->cutlen = 0; + OVS_CB(skb)->cutlen = U32_MAX; break; case OVS_ACTION_ATTR_HASH: diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 1c69aa986633..529eb9d6acab 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -240,7 +240,7 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key) upcall.cmd = OVS_PACKET_CMD_MISS; upcall.portid = ovs_vport_find_upcall_portid(p, skb); upcall.mru = OVS_CB(skb)->mru; - error = ovs_dp_upcall(dp, skb, key, &upcall, 0); + error = ovs_dp_upcall(dp, skb, key, &upcall, U32_MAX); switch (error) { case 0: case -EAGAIN: @@ -400,7 +400,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, struct sk_buff *nskb = NULL; struct sk_buff *user_skb = NULL; /* to be queued to userspace */ struct nlattr *nla; - size_t len; + size_t msg_size; + size_t skb_len; unsigned int hlen; int err, dp_ifindex; u64 hash; @@ -421,7 +422,8 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, skb = nskb; } - if (nla_attr_size(skb->len) > USHRT_MAX) { + skb_len = min(skb->len, cutlen); + if (nla_attr_size(skb_len) > USHRT_MAX) { err = -EFBIG; goto out; } @@ -436,13 +438,13 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, * padding logic. Only perform zerocopy if padding is not required. */ if (dp->user_features & OVS_DP_F_UNALIGNED) - hlen = skb_zerocopy_headlen(skb); + hlen = min(skb_zerocopy_headlen(skb), cutlen); else - hlen = skb->len; + hlen = skb_len; - len = upcall_msg_size(upcall_info, hlen - cutlen, - OVS_CB(skb)->acts_origlen); - user_skb = genlmsg_new(len, GFP_ATOMIC); + msg_size = upcall_msg_size(upcall_info, hlen, + OVS_CB(skb)->acts_origlen); + user_skb = genlmsg_new(msg_size, GFP_ATOMIC); if (!user_skb) { err = -ENOMEM; goto out; @@ -503,7 +505,7 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, } /* Add OVS_PACKET_ATTR_LEN when packet is truncated */ - if (cutlen > 0 && + if (skb_len < skb->len && nla_put_u32(user_skb, OVS_PACKET_ATTR_LEN, skb->len)) { err = -ENOBUFS; goto out; @@ -528,9 +530,9 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, err = -ENOBUFS; goto out; } - nla->nla_len = nla_attr_size(skb->len - cutlen); + nla->nla_len = nla_attr_size(skb_len); - err = skb_zerocopy(user_skb, skb, skb->len - cutlen, hlen); + err = skb_zerocopy(user_skb, skb, skb_len, hlen); if (err) goto out; @@ -587,6 +589,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) packet->ignore_df = 1; } OVS_CB(packet)->mru = mru; + OVS_CB(packet)->cutlen = U32_MAX; if (a[OVS_PACKET_ATTR_HASH]) { hash = nla_get_u64(a[OVS_PACKET_ATTR_HASH]); diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index 38f7d3e66ca6..62e7ad32f837 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h @@ -96,7 +96,7 @@ struct datapath { * @mru: The maximum received fragement size; 0 if the packet is not * fragmented. * @acts_origlen: The netlink size of the flow actions applied to this skb. - * @cutlen: The number of bytes from the packet end to be removed. + * @cutlen: The number of bytes in the packet to preserve on output. */ struct ovs_skb_cb { struct vport *input_vport; diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index da733b92ae8a..ced707ff6dd9 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c @@ -436,7 +436,7 @@ int ovs_vport_receive(struct vport *vport, struct sk_buff *skb, OVS_CB(skb)->input_vport = vport; OVS_CB(skb)->mru = 0; - OVS_CB(skb)->cutlen = 0; + OVS_CB(skb)->cutlen = U32_MAX; if (unlikely(dev_net(skb->dev) != ovs_dp_get_net(vport->dp))) { u32 mark; -- 2.25.1
2 1
0 0
[PATCH OLK-6.6] net/mlx5: Fix MCIA register buffer overflow on 32 dword reads
by Yi Yang 03 Sep '26

03 Sep '26
From: Gal Pressman <gal(a)nvidia.com> mainline inclusion from mainline-v7.2-rc5 commit 11c057d23465c7a5817a7284c896d19d54c0b616 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/17144 CVE: CVE-2026-68293 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- The MCIA register can return up to 32 dwords (128 bytes) when the device advertises the mcia_32dwords capability, but struct mlx5_ifc_mcia_reg_bits only defines dword_0..11, leaving room for just 12 dwords (48 bytes) of data. mlx5_query_mcia() clamps the read size to mlx5_mcia_max_bytes() and then memcpy()s that many bytes out of the register, potentially reading past the end of the 'out' buffer. On kernels built with FORTIFY_SOURCE this is caught as a buffer overflow while reading the module EEPROM via ethtool: detected buffer overflow in memcpy kernel BUG at lib/string_helpers.c:1048! RIP: 0010:fortify_panic+0x13/0x20 Call Trace: mlx5_query_mcia.isra.0+0x200/0x210 [mlx5_core] mlx5_query_module_eeprom_by_page+0x4a/0xa0 [mlx5_core] mlx5e_get_module_eeprom_by_page+0xbb/0x120 [mlx5_core] eeprom_prepare_data+0xf3/0x170 ethnl_default_doit+0xf1/0x3b0 Extend the mcia_reg layout to 32 dwords. Fixes: 271907ee2f29 ("net/mlx5: Query the maximum MCIA register read size from firmware") Signed-off-by: Gal Pressman <gal(a)nvidia.com> Reviewed-by: Alex Lazar <alazar(a)nvidia.com> Signed-off-by: Tariq Toukan <tariqt(a)nvidia.com> Link: https://patch.msgid.link/20260717072338.1240582-1-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba(a)kernel.org> Conflicts: drivers/net/ethernet/mellanox/mlx5/core/port.c [Commit 2e4c44b12f4d ("net/mlx5: Refactor EEPROM query error handling to return status separately") was not merged. Context conflicts.] Signed-off-by: Yi Yang <yiyang13(a)huawei.com> --- drivers/net/ethernet/mellanox/mlx5/core/port.c | 4 ++-- include/linux/mlx5/mlx5_ifc.h | 13 +------------ 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c index a5622b44385e..ec739b2f0ada 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c @@ -316,7 +316,7 @@ static int mlx5_query_module_id(struct mlx5_core_dev *dev, int module_num, status); return -EIO; } - ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0); + ptr = MLX5_ADDR_OF(mcia_reg, out, dwords); *module_id = ptr[0]; @@ -401,7 +401,7 @@ static int mlx5_query_mcia(struct mlx5_core_dev *dev, return -EIO; } - ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0); + ptr = MLX5_ADDR_OF(mcia_reg, out, dwords); memcpy(data, ptr, size); return size; diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index c59fd31719a1..573461c9dced 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -11320,18 +11320,7 @@ struct mlx5_ifc_mcia_reg_bits { u8 reserved_at_60[0x20]; - u8 dword_0[0x20]; - u8 dword_1[0x20]; - u8 dword_2[0x20]; - u8 dword_3[0x20]; - u8 dword_4[0x20]; - u8 dword_5[0x20]; - u8 dword_6[0x20]; - u8 dword_7[0x20]; - u8 dword_8[0x20]; - u8 dword_9[0x20]; - u8 dword_10[0x20]; - u8 dword_11[0x20]; + u8 dwords[0x400]; }; struct mlx5_ifc_dcbx_param_bits { -- 2.25.1
2 1
0 0
[PATCH OLK-6.6] RDMA/nldev: Fix locking when accessing mr->pd
by Chen Jinghuang 03 Sep '26

03 Sep '26
From: Jason Gunthorpe <jgg(a)nvidia.com> mainline inclusion from mainline-v7.2-rc1 commit 50d5c02ab8e62325548bd3a6e6b758a9dcd6e7c3 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/17658 CVE: CVE-2026-74334 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- Sashiko points out that, due to rereg_mr, the PD is actually variable and all the touches in nldev are racy. Use mr->device instead of mr->pd->device. Getting the PD restrack ID is more tricky. To avoid disturbing all the happy paths, add an rdma_restrack_sync() operation which is sort of like flush_workqueue() or synchronize_irq(): after it returns, all the old nldev touches to the mr are gone and everything sees the new PD. This makes it safe to reach into the PD pointer. Fixes: da5c85078215 ("RDMA/nldev: add driver-specific resource tracking") Link: https://patch.msgid.link/r/4-v1-29ebd2c229b5+fd5-ib_mr_pd_jgg@nvidia.com Signed-off-by: Jason Gunthorpe <jgg(a)nvidia.com> Conflicts: drivers/infiniband/core/restrack.c drivers/infiniband/core/uverbs_cmd.c include/rdma/ib_verbs.h [In restrack.c, rdma_restrack_count() in target tree lacks show_details parameter and RESTRACK_DD mark logic; only added xa_is_zero() check required by rdma_restrack_sync(). Removed RESTRACK_DD xa_get_mark() check in rdma_restrack_sync() as target tree does not have driver-specific resource tracking (RESTRACK_DD mark). In uverbs_cmd.c, kept downstream #include "uverbs_profile.h" alongside new #include "restrack.h".] Signed-off-by: Chen Jinghuang <chenjinghuang2(a)huawei.com> --- drivers/infiniband/core/nldev.c | 15 +++++---- drivers/infiniband/core/restrack.c | 50 +++++++++++++++++++++++++++- drivers/infiniband/core/restrack.h | 1 + drivers/infiniband/core/uverbs_cmd.c | 10 ++++-- include/rdma/ib_verbs.h | 5 +++ 5 files changed, 72 insertions(+), 9 deletions(-) diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c index 9d6627bde61a..6c4008a1e18f 100644 --- a/drivers/infiniband/core/nldev.c +++ b/drivers/infiniband/core/nldev.c @@ -644,7 +644,7 @@ static int fill_res_mr_entry(struct sk_buff *msg, bool has_cap_net_admin, struct rdma_restrack_entry *res, uint32_t port) { struct ib_mr *mr = container_of(res, struct ib_mr, res); - struct ib_device *dev = mr->pd->device; + struct ib_device *dev = mr->device; if (has_cap_net_admin) { if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_RKEY, mr->rkey)) @@ -660,9 +660,12 @@ static int fill_res_mr_entry(struct sk_buff *msg, bool has_cap_net_admin, if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_MRN, res->id)) return -EMSGSIZE; - if (!rdma_is_kernel_res(res) && - nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_PDN, mr->pd->res.id)) - return -EMSGSIZE; + if (!rdma_is_kernel_res(res)) { + struct ib_pd *pd = READ_ONCE(mr->pd); + + if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_PDN, pd->res.id)) + return -EMSGSIZE; + } if (fill_res_name_pid(msg, res)) return -EMSGSIZE; @@ -676,7 +679,7 @@ static int fill_res_mr_raw_entry(struct sk_buff *msg, bool has_cap_net_admin, struct rdma_restrack_entry *res, uint32_t port) { struct ib_mr *mr = container_of(res, struct ib_mr, res); - struct ib_device *dev = mr->pd->device; + struct ib_device *dev = mr->device; if (!dev->ops.fill_res_mr_entry_raw) return -EINVAL; @@ -966,7 +969,7 @@ static int fill_stat_mr_entry(struct sk_buff *msg, bool has_cap_net_admin, struct rdma_restrack_entry *res, uint32_t port) { struct ib_mr *mr = container_of(res, struct ib_mr, res); - struct ib_device *dev = mr->pd->device; + struct ib_device *dev = mr->device; if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_MRN, res->id)) goto err; diff --git a/drivers/infiniband/core/restrack.c b/drivers/infiniband/core/restrack.c index 438ed3588175..7ffb7701516f 100644 --- a/drivers/infiniband/core/restrack.c +++ b/drivers/infiniband/core/restrack.c @@ -68,8 +68,11 @@ int rdma_restrack_count(struct ib_device *dev, enum rdma_restrack_type type) u32 cnt = 0; xa_lock(&rt->xa); - xas_for_each(&xas, e, U32_MAX) + xas_for_each(&xas, e, U32_MAX) { + if (xa_is_zero(e)) + continue; cnt++; + } xa_unlock(&rt->xa); return cnt; } @@ -266,6 +269,51 @@ int rdma_restrack_put(struct rdma_restrack_entry *res) } EXPORT_SYMBOL(rdma_restrack_put); +/** + * rdma_restrack_sync() - Fence concurrent netlink dumps on an entry + * @res: resource entry + * + * After this returns any concurrent netlink dump threads will see the current + * value of the object. This is useful if the object has to be changed and there + * is not locking to protect the nl side. Eg for mr->pd. This effectively + * destroys the object from a kref/xarray perspective and then immediately + * restores it. The kref is acting like a lock to barrier concurrent nl threads. + * Callers must ensure rdma_restrack_del() is not concurrently called. + */ +void rdma_restrack_sync(struct rdma_restrack_entry *res) +{ + struct rdma_restrack_entry *old; + struct rdma_restrack_root *rt; + struct task_struct *task; + struct ib_device *dev; + + if (!res->valid || res->no_track) + return; + + dev = res_to_dev(res); + if (WARN_ON(!dev)) + return; + + rt = &dev->res[res->type]; + + old = xa_cmpxchg(&rt->xa, res->id, res, XA_ZERO_ENTRY, GFP_KERNEL); + if (WARN_ON(old != res)) + return; + + task = res->task; + if (task) + get_task_struct(task); + rdma_restrack_put(res); + wait_for_completion(&res->comp); + reinit_completion(&res->comp); + if (task) + res->task = task; + kref_init(&res->kref); + + xa_cmpxchg(&rt->xa, res->id, XA_ZERO_ENTRY, res, GFP_KERNEL); +} +EXPORT_SYMBOL(rdma_restrack_sync); + /** * rdma_restrack_del() - delete object from the reource tracking database * @res: resource entry diff --git a/drivers/infiniband/core/restrack.h b/drivers/infiniband/core/restrack.h index 6a04fc41f738..75b8d1005a98 100644 --- a/drivers/infiniband/core/restrack.h +++ b/drivers/infiniband/core/restrack.h @@ -27,6 +27,7 @@ int rdma_restrack_init(struct ib_device *dev); void rdma_restrack_clean(struct ib_device *dev); void rdma_restrack_add(struct rdma_restrack_entry *res); void rdma_restrack_del(struct rdma_restrack_entry *res); +void rdma_restrack_sync(struct rdma_restrack_entry *res); void rdma_restrack_new(struct rdma_restrack_entry *res, enum rdma_restrack_type type); void rdma_restrack_set_name(struct rdma_restrack_entry *res, diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 2e4265ba35b7..f442cca3c05c 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -46,6 +46,7 @@ #include "uverbs.h" #include "core_priv.h" +#include "restrack.h" /* * Copy a response to userspace. If the provided 'resp' is larger than the @@ -813,6 +814,10 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs) ret = PTR_ERR(new_pd); goto put_uobjs; } + if (new_pd == orig_pd) { + uobj_put_obj_read(new_pd); + cmd.flags &= ~IB_MR_REREG_PD; + } } else { new_pd = mr->pd; } @@ -858,9 +863,10 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs) mr = new_mr; } else { if (cmd.flags & IB_MR_REREG_PD) { - atomic_dec(&orig_pd->usecnt); - mr->pd = new_pd; atomic_inc(&new_pd->usecnt); + WRITE_ONCE(mr->pd, new_pd); + rdma_restrack_sync(&mr->res); + atomic_dec(&orig_pd->usecnt); } if (cmd.flags & IB_MR_REREG_TRANS) { mr->iova = cmd.hca_va; diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 3eea95e51928..05b101693cd5 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1833,6 +1833,11 @@ struct ib_dm { struct ib_mr { struct ib_device *device; + /* + * Due to IB_MR_REREG_PD pd is not a fixed pointer and can change. For a + * user MR, this value should only be read from a system call that holds + * the uobject lock, or the driver should disable in-place REREG_PD. + */ struct ib_pd *pd; u32 lkey; u32 rkey; -- 2.34.1
2 1
0 0
[PATCH OLK-6.6] net/mlx5: Fix MCIA register buffer overflow on 32 dword reads
by Yi Yang 03 Sep '26

03 Sep '26
From: Gal Pressman <gal(a)nvidia.com> mainline inclusion from mainline-v5.13-rc1 commit 11c057d23465c7a5817a7284c896d19d54c0b616 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/17144 CVE: CVE-2026-68293 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?… -------------------------------- The MCIA register can return up to 32 dwords (128 bytes) when the device advertises the mcia_32dwords capability, but struct mlx5_ifc_mcia_reg_bits only defines dword_0..11, leaving room for just 12 dwords (48 bytes) of data. mlx5_query_mcia() clamps the read size to mlx5_mcia_max_bytes() and then memcpy()s that many bytes out of the register, potentially reading past the end of the 'out' buffer. On kernels built with FORTIFY_SOURCE this is caught as a buffer overflow while reading the module EEPROM via ethtool: detected buffer overflow in memcpy kernel BUG at lib/string_helpers.c:1048! RIP: 0010:fortify_panic+0x13/0x20 Call Trace: mlx5_query_mcia.isra.0+0x200/0x210 [mlx5_core] mlx5_query_module_eeprom_by_page+0x4a/0xa0 [mlx5_core] mlx5e_get_module_eeprom_by_page+0xbb/0x120 [mlx5_core] eeprom_prepare_data+0xf3/0x170 ethnl_default_doit+0xf1/0x3b0 Extend the mcia_reg layout to 32 dwords. Fixes: 271907ee2f29 ("net/mlx5: Query the maximum MCIA register read size from firmware") Signed-off-by: Gal Pressman <gal(a)nvidia.com> Reviewed-by: Alex Lazar <alazar(a)nvidia.com> Signed-off-by: Tariq Toukan <tariqt(a)nvidia.com> Link: https://patch.msgid.link/20260717072338.1240582-1-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba(a)kernel.org> Conflicts: drivers/net/ethernet/mellanox/mlx5/core/port.c [Commit 2e4c44b12f4d ("net/mlx5: Refactor EEPROM query error handling to return status separately") was not merged. Context conflicts.] Signed-off-by: Yi Yang <yiyang13(a)huawei.com> --- drivers/net/ethernet/mellanox/mlx5/core/port.c | 4 ++-- include/linux/mlx5/mlx5_ifc.h | 13 +------------ 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c index a5622b44385e..ec739b2f0ada 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c @@ -316,7 +316,7 @@ static int mlx5_query_module_id(struct mlx5_core_dev *dev, int module_num, status); return -EIO; } - ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0); + ptr = MLX5_ADDR_OF(mcia_reg, out, dwords); *module_id = ptr[0]; @@ -401,7 +401,7 @@ static int mlx5_query_mcia(struct mlx5_core_dev *dev, return -EIO; } - ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0); + ptr = MLX5_ADDR_OF(mcia_reg, out, dwords); memcpy(data, ptr, size); return size; diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index c59fd31719a1..573461c9dced 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -11320,18 +11320,7 @@ struct mlx5_ifc_mcia_reg_bits { u8 reserved_at_60[0x20]; - u8 dword_0[0x20]; - u8 dword_1[0x20]; - u8 dword_2[0x20]; - u8 dword_3[0x20]; - u8 dword_4[0x20]; - u8 dword_5[0x20]; - u8 dword_6[0x20]; - u8 dword_7[0x20]; - u8 dword_8[0x20]; - u8 dword_9[0x20]; - u8 dword_10[0x20]; - u8 dword_11[0x20]; + u8 dwords[0x400]; }; struct mlx5_ifc_dcbx_param_bits { -- 2.25.1
2 1
0 0
  • ← Newer
  • 1
  • 2
  • 3
  • 4
  • 5
  • ...
  • 2462
  • Older →

HyperKitty Powered by HyperKitty