mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
libceph: Fix multiplication overflow in decode_new_up_state_weight()
commit98917a499eupstream. If a message of type CEPH_MSG_OSD_MAP contains a (maliciously) corrupted osdmap, out-of-bounds memory accesses may occur in decode_new_up_state_weight(). This happens because the bounds check for the new_state part is based on calculating its length depending on a len value read from the incoming message. This calculation may overflow leading to an incorrect bounds check. Subsequently, out-of-bounds reads may occur when decoding this part. This patch switches the multiplication to use check_mul_overflow() to abort processing the osdmap if an overflow occurred. Therefore, osdmaps/messages containing large values for len that result in a multiplication overflow are treated as invalid. [ idryomov: rename new_state_len -> new_state_item_size, formatting ] Cc: stable@vger.kernel.org Fixes:930c532869("libceph: apply new_state before new_up_client on incrementals") Signed-off-by: Raphael Zimmer <raphael.zimmer@tu-ilmenau.de> Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
4e7ebfaa0d
commit
1732d89dfc
+4
-1
@@ -1844,6 +1844,8 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v,
|
||||
void *new_up_client;
|
||||
void *new_state;
|
||||
void *new_weight_end;
|
||||
const u32 new_state_item_size =
|
||||
sizeof(u32) + (struct_v >= 5 ? sizeof(u32) : sizeof(u8));
|
||||
u32 len;
|
||||
int ret;
|
||||
int i;
|
||||
@@ -1864,7 +1866,8 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v,
|
||||
|
||||
new_state = *p;
|
||||
ceph_decode_32_safe(p, end, len, e_inval);
|
||||
len *= sizeof(u32) + (struct_v >= 5 ? sizeof(u32) : sizeof(u8));
|
||||
if (check_mul_overflow(len, new_state_item_size, &len))
|
||||
goto e_inval;
|
||||
ceph_decode_need(p, end, len, e_inval);
|
||||
*p += len;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user