public inbox for ceph-devel@vger.kernel.org
 help / color / mirror / Atom feed
From: Daniel Vogelbacher <daniel@chaospixel.com>
To: ceph-devel@vger.kernel.org
Cc: Slava.Dubeyko@ibm.com, xiubli@redhat.com, idryomov@gmail.com
Subject: [PATCH v2] fs/ceph: Fix kernel oops due invalid pointer for kfree() in parse_longname()
Date: Sun,  1 Feb 2026 09:34:01 +0100	[thread overview]
Message-ID: <20260201083624.2093540-1-daniel@chaospixel.com> (raw)
In-Reply-To: <20251220140153.1523907-1-daniel@chaospixel.com>

This fixes a kernel oops when reading ceph snapshot directories (.snap),
for example by simply run `ls /mnt/my_ceph/.snap`.

The bug was introduced in commit:

bb80f7618832 - parse_longname(): strrchr() expects NUL-terminated string

The variable str is guarded by __free(kfree), but advanced by one for
skipping the initial '_' in snapshot names. Thus, kfree() is called
with an invalid pointer.
This patch removes the need for advancing the pointer so kfree()
is called with correct memory pointer.

The full trace is:

[   53.703013] Oops: general protection fault, probably for non-canonical address 0xd0c22857c0000000: 0000 [#1] SMP PTI
[   53.703201] CPU: 11 UID: 0 PID: 360 Comm: kworker/11:2 Not tainted 6.18.0-rc7 #41 PREEMPT(voluntary)
[   53.703281] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[   53.703317] Workqueue: ceph-msgr ceph_con_workfn [libceph]
[   53.703424] RIP: 0010:rb_insert_color (/usr/src/linux/lib/rbtree.c:185 (discriminator 1) /usr/src/linux/lib/rbtree.c:436 (discriminator 1))
[   53.704503] Code: 76 17 48 83 e1 fc 48 3b 51 10 0f 84 b7 00 00 00 48 89 41 08 c3 cc cc cc cc 48 89 06 c3 cc cc cc cc 48 8b 4a 10 48 85 c9 74 05 <f6> 01 01 74 1b 48 8b 48 10 48 39 f9 74 68 48 89 c7 48 89 4a 08 48
All code
========
   0:	76 17                	jbe    0x19
   2:	48 83 e1 fc          	and    $0xfffffffffffffffc,%rcx
   6:	48 3b 51 10          	cmp    0x10(%rcx),%rdx
   a:	0f 84 b7 00 00 00    	je     0xc7
  10:	48 89 41 08          	mov    %rax,0x8(%rcx)
  14:	c3                   	ret
  15:	cc                   	int3
  16:	cc                   	int3
  17:	cc                   	int3
  18:	cc                   	int3
  19:	48 89 06             	mov    %rax,(%rsi)
  1c:	c3                   	ret
  1d:	cc                   	int3
  1e:	cc                   	int3
  1f:	cc                   	int3
  20:	cc                   	int3
  21:	48 8b 4a 10          	mov    0x10(%rdx),%rcx
  25:	48 85 c9             	test   %rcx,%rcx
  28:	74 05                	je     0x2f
  2a:*	f6 01 01             	testb  $0x1,(%rcx)		<-- trapping instruction
  2d:	74 1b                	je     0x4a
  2f:	48 8b 48 10          	mov    0x10(%rax),%rcx
  33:	48 39 f9             	cmp    %rdi,%rcx
  36:	74 68                	je     0xa0
  38:	48 89 c7             	mov    %rax,%rdi
  3b:	48 89 4a 08          	mov    %rcx,0x8(%rdx)
  3f:	48                   	rex.W

Code starting with the faulting instruction
===========================================
   0:	f6 01 01             	testb  $0x1,(%rcx)
   3:	74 1b                	je     0x20
   5:	48 8b 48 10          	mov    0x10(%rax),%rcx
   9:	48 39 f9             	cmp    %rdi,%rcx
   c:	74 68                	je     0x76
   e:	48 89 c7             	mov    %rax,%rdi
  11:	48 89 4a 08          	mov    %rcx,0x8(%rdx)
  15:	48                   	rex.W
[   53.704559] RSP: 0018:ffff9ab7c07579e0 EFLAGS: 00010286
[   53.704591] RAX: ffff8bd0c2285b40 RBX: ffff8bd0c2285240 RCX: d0c22857c0000000
[   53.704616] RDX: ffff8bd0c2285910 RSI: ffff8bd0c3e695c0 RDI: ffff8bd0c22855c0
[   53.704645] RBP: 0000000000002139 R08: 0000000000000000 R09: 0000000000000000
[   53.704668] R10: 0000000000000000 R11: ffff8bd0c16244e0 R12: ffff8bd0c3e695b8
[   53.704691] R13: ffff8bd0c3b62000 R14: ffff8bd0c22857c0 R15: ffff8bd0c3e695c0
[   53.704714] FS:  0000000000000000(0000) GS:ffff8bd1815ca000(0000) knlGS:0000000000000000
[   53.704741] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   53.704762] CR2: 000055667ef28e10 CR3: 0000000106cc2005 CR4: 0000000000772ef0
[   53.704790] PKRU: 55555554
[   53.704803] Call Trace:
[   53.704844]  <TASK>
[   53.704862] ceph_get_snapid_map (/usr/src/linux/./include/linux/spinlock.h:391 /usr/src/linux/fs/ceph/snap.c:1255) ceph
[   53.704957] ceph_fill_inode (/usr/src/linux/fs/ceph/inode.c:1062 (discriminator 2)) ceph
[   53.705019]  ? __pfx_ceph_set_ino_cb (/usr/src/linux/fs/ceph/inode.c:46) ceph
[   53.705074]  ? __pfx_ceph_ino_compare (/usr/src/linux/fs/ceph/super.h:595) ceph
[   53.705132] ceph_readdir_prepopulate (/usr/src/linux/fs/ceph/inode.c:2113) ceph
[   53.705191] mds_dispatch (/usr/src/linux/fs/ceph/mds_client.c:3993 /usr/src/linux/fs/ceph/mds_client.c:6299) ceph
[   53.705253]  ? sock_recvmsg (/usr/src/linux/net/socket.c:1078 (discriminator 1) /usr/src/linux/net/socket.c:1100 (discriminator 1))
[   53.705279] ceph_con_process_message (/usr/src/linux/net/ceph/messenger.c:1427) libceph
[   53.705347] process_message (/usr/src/linux/net/ceph/messenger_v2.c:2879) libceph
[   53.705406] ceph_con_v2_try_read (/usr/src/linux/net/ceph/messenger_v2.c:3043 /usr/src/linux/net/ceph/messenger_v2.c:3099 /usr/src/linux/net/ceph/messenger_v2.c:3148) libceph
[   53.705467]  ? psi_group_change (/usr/src/linux/kernel/sched/psi.c:876)
[   53.705488]  ? sched_balance_newidle (/usr/src/linux/kernel/sched/fair.c:12902 (discriminator 2))
[   53.705512]  ? psi_task_switch (/usr/src/linux/kernel/sched/psi.c:984 (discriminator 2))
[   53.705532]  ? _raw_spin_unlock (/usr/src/linux/./arch/x86/include/asm/paravirt.h:562 /usr/src/linux/./arch/x86/include/asm/qspinlock.h:57 /usr/src/linux/./include/linux/spinlock.h:204 /usr/src/linux/./include/linux/spinlock_api_smp.h:142 /usr/src/linux/kernel/locking/spinlock.c:186)
[   53.705550]  ? finish_task_switch.isra.0 (/usr/src/linux/./arch/x86/include/asm/paravirt.h:671 /usr/src/linux/kernel/sched/sched.h:1559 /usr/src/linux/kernel/sched/core.c:5073 /usr/src/linux/kernel/sched/core.c:5191)
[   53.705575] ceph_con_workfn (/usr/src/linux/net/ceph/messenger.c:1578) libceph
[   53.705627]  process_one_work (/usr/src/linux/./arch/x86/include/asm/jump_label.h:36 /usr/src/linux/./include/trace/events/workqueue.h:110 /usr/src/linux/kernel/workqueue.c:3268)
[   53.705657]  worker_thread (/usr/src/linux/kernel/workqueue.c:3340 (discriminator 2) /usr/src/linux/kernel/workqueue.c:3427 (discriminator 2))
[   53.705679]  ? __pfx_worker_thread (/usr/src/linux/kernel/workqueue.c:3373)
[   53.705700]  kthread (/usr/src/linux/kernel/kthread.c:463)
[   53.705717]  ? __pfx_kthread (/usr/src/linux/kernel/kthread.c:412)
[   53.705734]  ? __pfx_kthread (/usr/src/linux/kernel/kthread.c:412)
[   53.705752]  ret_from_fork (/usr/src/linux/arch/x86/kernel/process.c:164)
[   53.705776]  ? __pfx_kthread (/usr/src/linux/kernel/kthread.c:412)
[   53.705793]  ret_from_fork_asm (/usr/src/linux/arch/x86/entry/entry_64.S:255)
[   53.705826]  </TASK>
[   53.705842] Modules linked in: ceph netfs libceph cfg80211 rfkill 8021q garp stp mrp llc binfmt_misc intel_rapl_msr intel_rapl_common intel_uncore_frequency_common kvm_intel virtio_gpu joydev kvm drm_client_lib virtio_dma_buf evdev drm_shmem_helper sg drm_kms_helper virtio_balloon button irqbypass ghash_clmulni_intel aesni_intel rapl pcspkr drm configfs efi_pstore nfnetlink vsock_loopback vmw_vsock_virtio_transport_common vmw_vsock_vmci_transport vmw_vmci vsock qemu_fw_cfg virtio_rng autofs4 ext4 crc16 mbcache jbd2 hid_generic usbhid hid sr_mod cdrom dm_mod ahci libahci libata xhci_pci iTCO_wdt intel_pmc_bxt xhci_hcd iTCO_vendor_support scsi_mod psmouse virtio_net i2c_i801 watchdog serio_raw i2c_smbus lpc_ich scsi_common usbcore net_failover failover virtio_blk usb_common
[   53.708740] ---[ end trace 0000000000000000 ]---
[   53.709462] RIP: 0010:rb_insert_color (/usr/src/linux/lib/rbtree.c:185 (discriminator 1) /usr/src/linux/lib/rbtree.c:436 (discriminator 1))
[   53.710118] Code: 76 17 48 83 e1 fc 48 3b 51 10 0f 84 b7 00 00 00 48 89 41 08 c3 cc cc cc cc 48 89 06 c3 cc cc cc cc 48 8b 4a 10 48 85 c9 74 05 <f6> 01 01 74 1b 48 8b 48 10 48 39 f9 74 68 48 89 c7 48 89 4a 08 48
All code
========
   0:	76 17                	jbe    0x19
   2:	48 83 e1 fc          	and    $0xfffffffffffffffc,%rcx
   6:	48 3b 51 10          	cmp    0x10(%rcx),%rdx
   a:	0f 84 b7 00 00 00    	je     0xc7
  10:	48 89 41 08          	mov    %rax,0x8(%rcx)
  14:	c3                   	ret
  15:	cc                   	int3
  16:	cc                   	int3
  17:	cc                   	int3
  18:	cc                   	int3
  19:	48 89 06             	mov    %rax,(%rsi)
  1c:	c3                   	ret
  1d:	cc                   	int3
  1e:	cc                   	int3
  1f:	cc                   	int3
  20:	cc                   	int3
  21:	48 8b 4a 10          	mov    0x10(%rdx),%rcx
  25:	48 85 c9             	test   %rcx,%rcx
  28:	74 05                	je     0x2f
  2a:*	f6 01 01             	testb  $0x1,(%rcx)		<-- trapping instruction
  2d:	74 1b                	je     0x4a
  2f:	48 8b 48 10          	mov    0x10(%rax),%rcx
  33:	48 39 f9             	cmp    %rdi,%rcx
  36:	74 68                	je     0xa0
  38:	48 89 c7             	mov    %rax,%rdi
  3b:	48 89 4a 08          	mov    %rcx,0x8(%rdx)
  3f:	48                   	rex.W

Code starting with the faulting instruction
===========================================
   0:	f6 01 01             	testb  $0x1,(%rcx)
   3:	74 1b                	je     0x20
   5:	48 8b 48 10          	mov    0x10(%rax),%rcx
   9:	48 39 f9             	cmp    %rdi,%rcx
   c:	74 68                	je     0x76
   e:	48 89 c7             	mov    %rax,%rdi
  11:	48 89 4a 08          	mov    %rcx,0x8(%rdx)
  15:	48                   	rex.W
[   53.711453] RSP: 0018:ffff9ab7c07579e0 EFLAGS: 00010286
[   53.712112] RAX: ffff8bd0c2285b40 RBX: ffff8bd0c2285240 RCX: d0c22857c0000000
[   53.712798] RDX: ffff8bd0c2285910 RSI: ffff8bd0c3e695c0 RDI: ffff8bd0c22855c0
[   53.713423] RBP: 0000000000002139 R08: 0000000000000000 R09: 0000000000000000
[   53.714061] R10: 0000000000000000 R11: ffff8bd0c16244e0 R12: ffff8bd0c3e695b8
[   53.714696] R13: ffff8bd0c3b62000 R14: ffff8bd0c22857c0 R15: ffff8bd0c3e695c0
[   53.715321] FS:  0000000000000000(0000) GS:ffff8bd1815ca000(0000) knlGS:0000000000000000
[   53.715956] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   53.716651] CR2: 000055667ef28e10 CR3: 0000000106cc2005 CR4: 0000000000772ef0
[   53.717295] PKRU: 55555554
[   53.717918] note: kworker/11:2[360] exited with preempt_count 1


Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220807
Fixes: bb80f7618832 - parse_longname(): strrchr() expects NUL-terminated string

Cc: stable@vger.kernel.org
Suggested-by: Helge Deller <deller@gmx.de>
Signed-off-by: Daniel Vogelbacher <daniel@chaospixel.com>
---
 fs/ceph/crypto.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c
index 0ea4db650f85..9a115282f67d 100644
--- a/fs/ceph/crypto.c
+++ b/fs/ceph/crypto.c
@@ -166,12 +166,13 @@ static struct inode *parse_longname(const struct inode *parent,
 	struct ceph_vino vino = { .snap = CEPH_NOSNAP };
 	char *name_end, *inode_number;
 	int ret = -EIO;
-	/* NUL-terminate */
-	char *str __free(kfree) = kmemdup_nul(name, *name_len, GFP_KERNEL);
+	/* Snapshot name must start with an underscore */
+	if (*name_len <= 0 || name[0] != '_')
+		return ERR_PTR(-EIO);
+	/* Skip initial '_' and NUL-terminate */
+	char *str __free(kfree) = kmemdup_nul(name + 1, *name_len - 1, GFP_KERNEL);
 	if (!str)
 		return ERR_PTR(-ENOMEM);
-	/* Skip initial '_' */
-	str++;
 	name_end = strrchr(str, '_');
 	if (!name_end) {
 		doutc(cl, "failed to parse long snapshot name: %s\n", str);
-- 
2.47.3


  parent reply	other threads:[~2026-02-01  8:42 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-20 14:01 [PATCH] fs/ceph: Fix kernel oops due invalid pointer for kfree() in parse_longname() Daniel Vogelbacher
2025-12-22 20:08 ` Viacheslav Dubeyko
2025-12-22 21:26   ` Daniel Vogelbacher
2025-12-23 22:49     ` Viacheslav Dubeyko
2026-01-20 13:42       ` Daniel Vogelbacher
2026-01-21 20:44         ` Viacheslav Dubeyko
2026-01-21 21:38           ` Daniel Vogelbacher
2026-02-01  8:34 ` Daniel Vogelbacher [this message]
2026-02-02 19:13   ` [PATCH v2] " Viacheslav Dubeyko
2026-02-03 19:23     ` Viacheslav Dubeyko
2026-02-03 19:41       ` Daniel Vogelbacher
2026-02-03 19:40 ` [PATCH v3] " Daniel Vogelbacher
2026-02-03 20:16   ` Viacheslav Dubeyko
2026-02-03 20:22     ` Ilya Dryomov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260201083624.2093540-1-daniel@chaospixel.com \
    --to=daniel@chaospixel.com \
    --cc=Slava.Dubeyko@ibm.com \
    --cc=ceph-devel@vger.kernel.org \
    --cc=idryomov@gmail.com \
    --cc=xiubli@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox