Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipmi: ssif_bmc: prevent integer overflow on 32bit systems

There are actually two bugs here. First, we need to ensure that count
is at least sizeof(u32) or msg.len will be uninitialized data.

The "msg.len" variable is a u32 that comes from the user. On 32bit
systems the "sizeof_field(struct ipmi_ssif_msg, len) + msg.len"
addition can overflow if "msg.len" is greater than U32_MAX - 4.

Valid lengths for "msg.len" are 1-254. Add a check for that to
prevent the integer overflow.

Fixes: dd2bc5cc9e25 ("ipmi: ssif_bmc: Add SSIF BMC driver")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Message-Id: <1431ca2e-4e9c-4520-bfc0-6879313c30e9@moroto.mountain>
Signed-off-by: Corey Minyard <corey@minyard.net>

authored by

Dan Carpenter and committed by
Corey Minyard
0627cef3 0cac73eb

+4 -2
+4 -2
drivers/char/ipmi/ssif_bmc.c
··· 177 177 unsigned long flags; 178 178 ssize_t ret; 179 179 180 - if (count > sizeof(struct ipmi_ssif_msg)) 180 + if (count < sizeof(msg.len) || 181 + count > sizeof(struct ipmi_ssif_msg)) 181 182 return -EINVAL; 182 183 183 184 if (copy_from_user(&msg, buf, count)) 184 185 return -EFAULT; 185 186 186 - if (!msg.len || count < sizeof_field(struct ipmi_ssif_msg, len) + msg.len) 187 + if (!msg.len || msg.len > IPMI_SSIF_PAYLOAD_MAX || 188 + count < sizeof_field(struct ipmi_ssif_msg, len) + msg.len) 187 189 return -EINVAL; 188 190 189 191 spin_lock_irqsave(&ssif_bmc->lock, flags);