ceph: fix kernel memory exposure issue in ceph_netfs_issue_op_inline()
Repeatable running of generic/013 test has revealed
the kernel memory exposure attempt for 6.19.0-rc8+ in
ceph_netfs_issue_op_inline():
while true; do
sudo ./check generic/013
done
[17660.888303] ceph: ceph_netfs_issue_op_inline():317 iinfo->inline_data
ffff8881000b0112,
iinfo->inline_len 0, subreq->start
328187904, subreq->len 4096, len 0
[17660.891728] usercopy: Kernel memory exposure attempt detected from SLUB object 'kmemleak_object' (offset 274, size 4096)!
[17660.893370] ------------[ cut here ]------------
[17660.893377] kernel BUG at mm/usercopy.c:102!
[17660.894426] Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
[17660.895749] CPU: 1 UID: 0 PID: 150873 Comm: fsstress Not tainted 6.19.0-rc8+ #13 PREEMPT(voluntary)
[17660.896823] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-9.fc43 06/10/2025
[17660.897891] RIP: 0010:usercopy_abort+0x7a/0x7c
[17660.898575] Code: 48 c7 c6 80 bb 3e 8c eb 0e 48 c7 c7 c0 bb 3e 8c 48 c7 c6 00 bc 3e 8c 52
48 89 fa 48 c7 c7 40 bc 3e 8c 50 41 52 e8 e6 00 fb ff <0f> 0b e8 ef 0e fb 00 4d 89 e0 31 c9 44 89 f2 48 c7 c6 c0 bd 3e 8c
[17660.901225] RSP: 0018:
ffff888179fbf340 EFLAGS:
00010246
[17660.901762] RAX:
000000000000006d RBX:
ffff8881139ac112 RCX:
0000000000000000
[17660.902295] RDX:
0000000000000000 RSI:
0000000000000000 RDI:
0000000000000000
[17660.902813] RBP:
ffff888179fbf358 R08:
0000000000000000 R09:
0000000000000000
[17660.903317] R10:
0000000000000000 R11:
0000000000000000 R12:
0000000000001000
[17660.903820] R13:
ffff8881139ad112 R14:
0000000000000001 R15:
ffff888119da8bb0
[17660.904283] FS:
0000747714d62740(0000) GS:
ffff888266112000(0000) knlGS:
0000000000000000
[17660.904719] CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
[17660.905122] CR2:
00007477143ffff0 CR3:
00000001014f9005 CR4:
0000000000772ef0
[17660.905555] PKRU:
55555554
[17660.905743] Call Trace:
[17660.905902] <TASK>
[17660.906042] __check_heap_object+0xf1/0x130
[17660.906372] ? __virt_addr_valid+0x26b/0x510
[17660.906667] __check_object_size+0x401/0x700
[17660.906959] ceph_netfs_issue_read.cold+0x295/0x2f1
[17660.907322] ? __pfx_ceph_netfs_issue_read+0x10/0x10
[17660.907657] ? __kasan_check_write+0x14/0x30
[17660.907940] ? kvm_sched_clock_read+0x11/0x20
[17660.908268] ? sched_clock_noinstr+0x9/0x10
[17660.908531] ? local_clock_noinstr+0xf/0x120
[17660.908817] netfs_read_to_pagecache+0x45a/0x10f0
[17660.909168] ? netfs_read_to_pagecache+0x45a/0x10f0
[17660.909482] netfs_write_begin+0x589/0xfc0
[17660.909761] ? __kasan_check_read+0x11/0x20
[17660.910019] ? __pfx_netfs_write_begin+0x10/0x10
[17660.910340] ? mark_held_locks+0x46/0x90
[17660.910629] ? inode_set_ctime_current+0x3d0/0x520
[17660.910965] ceph_write_begin+0x8c/0x1c0
[17660.911237] generic_perform_write+0x391/0x8f0
The reason of the issue is located in this code:
err = copy_to_iter(iinfo->inline_data + subreq->start,
len, &subreq->io_iter);
We have valid pointer iinfo->inline_data
ffff8881000b0112.
The iinfo->inline_len has 0 size in bytes. However, subreq->start
has really big value
328187904. Finally, the sum of iinfo->inline_data
and subreq->start results in the pointer that is out of available
memory area.
This patch checks the iinfo->inline_len value. If it has zero value,
then -EFAULT code error will be return. Otherwise, the copy_to_iter()
logic will be executed.
Signed-off-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
cc: Alex Markuze <amarkuze@redhat.com>
cc: Ilya Dryomov <idryomov@gmail.com>
cc: Patrick Donnelly <pdonnell@redhat.com>
cc: Ceph Development <ceph-devel@vger.kernel.org>