mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
libceph: bound mon_command ack decode to front len
handle_command_ack() bounds the decode with msg->front_alloc_len, the size of the reply buffer, instead of msg->front.iov_len, the number of bytes the monitor sent. mon_alloc_msg() routes every CEPH_MSG_MON_COMMAND_ACK to get_generic_reply(), which returns the preallocated ->reply of whichever generic request carries the same tid, so the buffer keeps its fixed size however short the reply is. An ack with hdr.front_len below sizeof(struct ceph_mon_request_header) + sizeof(u32), including 0, still passes ceph_decode_need(), and ceph_decode_32() returns four bytes that were never received: uninitialized slab memory, stale bytes of an earlier message, or bytes the peer planted by sending a reply that lands in the same buffer and is then rejected. The read stays within the allocation, so KASAN does not flag it. req->result reaches userspace through ceph_monc_do_statfs(), ceph_monc_get_version() and ceph_monc_blocklist_add(); rbd hands it back from write() on /sys/bus/rbd/add_single_major, and rbd_get_client() passes it to ERR_PTR() unchecked, which faults: rbd: failed to get latest osdmap: -186318427 BUG: unable to handle page fault for address: fffffbfffe9ca034 Oops: Oops: 0000 [#1] SMP KASAN NOPTI RIP: 0010:do_rbd_add (drivers/block/rbd.c:7105) Call Trace: ... kernfs_fop_write_iter (fs/kernfs/file.c:345) vfs_write (fs/read_write.c:595 fs/read_write.c:687) ksys_write (fs/read_write.c:739) do_syscall_64 (arch/x86/entry/syscall_64.c:61 arch/x86/entry/syscall_64.c:84) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121) Kernel panic - not syncing: Fatal exception Use msg->front.iov_len, matching handle_subscribe_ack(), handle_statfs_reply(), handle_get_version_reply() and handle_auth_reply(). A well-formed ack has front.iov_len >= 22 and is unaffected; a short one takes the existing bad: path. This applies commitd3c32939fa("libceph: bound get_version reply decode to front len") to the last decode-side use of front_alloc_len in this file. Cc: stable@vger.kernel.org Fixes:6305a3b415("libceph: support for blacklisting clients") Reported-by: co+25860fb17af97289@bugs.sh Assisted-by: Cursor Signed-off-by: Xiang Mei <xmei5@asu.edu> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
516b07ee26
commit
62b41a16d8
|
|
@ -943,7 +943,7 @@ static void handle_command_ack(struct ceph_mon_client *monc,
|
|||
{
|
||||
struct ceph_mon_generic_request *req;
|
||||
void *p = msg->front.iov_base;
|
||||
void *const end = p + msg->front_alloc_len;
|
||||
void *const end = p + msg->front.iov_len;
|
||||
u64 tid = le64_to_cpu(msg->hdr.tid);
|
||||
|
||||
dout("%s msg %p tid %llu\n", __func__, msg, tid);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user