diff options
Diffstat (limited to 'drivers/misc/mei/interrupt.c')
-rw-r--r-- | drivers/misc/mei/interrupt.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index c14e35201721..b0b8f18a85e3 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -235,6 +235,17 @@ static inline bool hdr_is_fixed(struct mei_msg_hdr *mei_hdr) return mei_hdr->host_addr == 0 && mei_hdr->me_addr != 0; } +static inline int hdr_is_valid(u32 msg_hdr) +{ + struct mei_msg_hdr *mei_hdr; + + mei_hdr = (struct mei_msg_hdr *)&msg_hdr; + if (!msg_hdr || mei_hdr->reserved) + return -EBADMSG; + + return 0; +} + /** * mei_irq_read_handler - bottom half read routine after ISR to * handle the read processing. @@ -256,17 +267,18 @@ int mei_irq_read_handler(struct mei_device *dev, dev->rd_msg_hdr = mei_read_hdr(dev); (*slots)--; dev_dbg(dev->dev, "slots =%08x.\n", *slots); - } - mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr; - dev_dbg(dev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); - if (mei_hdr->reserved || !dev->rd_msg_hdr) { - dev_err(dev->dev, "corrupted message header 0x%08X\n", + ret = hdr_is_valid(dev->rd_msg_hdr); + if (ret) { + dev_err(dev->dev, "corrupted message header 0x%08X\n", dev->rd_msg_hdr); - ret = -EBADMSG; - goto end; + goto end; + } } + mei_hdr = (struct mei_msg_hdr *)&dev->rd_msg_hdr; + dev_dbg(dev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); + if (mei_slots2data(*slots) < mei_hdr->length) { dev_err(dev->dev, "less data available than length=%08x.\n", *slots); |