In the Linux kernel, the following vulnerability has been resolved:
libceph: Fix slab-out-of-bounds access in auth message processing
If a (potentially corrupted) message of type CEPHMSGAUTHREPLY contains a positive value in its result field, it is treated as an error code by cephhandleauthreply() and returned to handleauthreply(). Thereafter, an attempt is made to send the preallocated message of type CEPHMSGAUTH, where the returned value is interpreted as the size of the front segment to send. If the result value in the message is greater than the size of the memory buffer allocated for the front segment, an out-of-bounds access occurs, and the content of the memory region beyond this buffer is sent out.
This patch fixes the issue by treating only negative values in the result field as errors. Positive values are therefore treated as success in the same way as a zero value. Additionally, a BUGON is added to sendpreparedauthrequest() comparing the len parameter to frontalloclen to prevent sending the message if it exceeds the bounds of the allocation and to make it easier to catch any logic flaws leading to this.
In the Linux kernel, the following vulnerability has been resolved:
libceph: Fix potential out-of-bounds access in cephhandleauthreply()
This patch fixes an out-of-bounds access in cephhandleauthreply() that can be triggered by a message of type CEPHMSGAUTHREPLY. In cephhandleauthreply(), the value of the payloadlen field of such a message is stored in a variable of type int. A value greater than INTMAX leads to an integer overflow and is interpreted as a negative value. This leads to decrementing the pointer address by this value and subsequently accessing it because cephdecodeneed() only checks that the memory access does not exceed the end address of the allocation.
This patch fixes the issue by changing the data type of payloadlen to u32. Additionally, the data type of resultmsglen is changed to u32, as it is also a variable holding a non-negative length.
Also, an additional layer of sanity checks is introduced, ensuring that directly after reading it from the message, payloadlen and resultmsglen are not greater than the overall segment length.
BUG: KASAN: slab-out-of-bounds in cephhandleauthreply+0x642/0x7a0 [libceph] Read of size 4 at addr ffff88811404df14 by task kworker/20:1/262
CPU: 20 UID: 0 PID: 262 Comm: kworker/20:1 Not tainted 6.19.2 #5 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Workqueue: ceph-msgr cephconworkfn [libceph] Call Trace: <TASK> dumpstacklvl+0x76/0xa0 printreport+0xd1/0x620 ? pfxrawspinlockirqsave+0x10/0x10 ? kasancompletemodereportinfo+0x72/0x210 kasanreport+0xe7/0x130 ? cephhandleauthreply+0x642/0x7a0 [libceph] ? cephhandleauthreply+0x642/0x7a0 [libceph] asanreportloadnnoabort+0xf/0x20 cephhandleauthreply+0x642/0x7a0 [libceph] mondispatch+0x973/0x23d0 [libceph] ? apparmorsocketrecvmsg+0x6b/0xa0 ? pfxmondispatch+0x10/0x10 [libceph] ? kasancheckwrite+0x14/0x30i ? mutexunlock+0x7f/0xd0 ? pfxmutexunlock+0x10/0x10 ? pfxdorecvmsg+0x10/0x10 [libceph] cephconprocessmessage+0x1f1/0x650 [libceph] processmessage+0x1e/0x450 [libceph] cephconv2tryread+0x2e48/0x6c80 [libceph] ? pfxcephconv2tryread+0x10/0x10 [libceph] ? savefpregstofpstate+0xb0/0x230 ? rawspinrqunlock+0x17/0xa0 ? finishtaskswitch.isra.0+0x13b/0x760 ? switchto+0x385/0xda0 ? kasancheckwrite+0x14/0x30 ? mutexlock+0x8d/0xe0 ? pfxmutexlock+0x10/0x10 cephconworkfn+0x248/0x10c0 [libceph] processonework+0x629/0xf80 ? kasancheckwrite+0x14/0x30 workerthread+0x87f/0x1570 ? pfxrawspinlockirqsave+0x10/0x10 ? pfxtrytowakeup+0x10/0x10 ? kasanprintaddressstackframe+0x1f7/0x280 ? pfxworkerthread+0x10/0x10 kthread+0x396/0x830 ? pfxrawspinlockirq+0x10/0x10 ? pfxkthread+0x10/0x10 ? kasancheckwrite+0x14/0x30 ? recalcsigpending+0x180/0x210 ? pfxkthread+0x10/0x10 retfromfork+0x3f7/0x610 ? pfxretfromfork+0x10/0x10 ? switchto+0x385/0xda0 ? pfxkthread+0x10/0x10 retfromforkasm+0x1a/0x30 </TASK>
[ idryomov: replace if statements with cephdecodeneed() for payloadlen and resultmsglen ]
In the Linux kernel, the following vulnerability has been resolved:
libceph: prevent potential out-of-bounds reads in processmessageheader()
If the message frame is (maliciously) corrupted in a way that the length of the control segment ends up being less than the size of the message header or a different frame is made to look like a message frame, out-of-bounds reads may ensue in processmessageheader().
Perform an explicit bounds check before decoding the message header.
In the Linux kernel, the following vulnerability has been resolved:
libceph: define and enforce CEPHMAXKEYLEN
When decoding the key, verify that the key material would fit into a fixed-size buffer in processauthdone() and generally has a sane length.
The new CEPHMAXKEYLEN check replaces the existing check for a key with no key material which is a) not universal since CEPHCRYPTONONE has to be excluded and b) doesn't provide much value since a smaller than needed key is just as invalid as no key -- this has to be handled elsewhere anyway.