Skip to content

Commit

Permalink
mei: fix transfer over dma with extended header
Browse files Browse the repository at this point in the history
The size in header field for packet transferred over DMA
includes size of the extended header.
Include extended header in size check.
Add size and sanity checks on extended header.

Cc: <stable@vger.kernel.org> # v5.10+
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Link: https://lore.kernel.org/r/20210129120752.850325-1-tomas.winkler@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Alexander Usyskin authored and Greg Kroah-Hartman committed Jan 29, 2021
1 parent d71277d commit 1309ecc
Showing 1 changed file with 30 additions and 3 deletions.
33 changes: 30 additions & 3 deletions drivers/misc/mei/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,17 @@ static inline bool hdr_is_fixed(struct mei_msg_hdr *mei_hdr)
static inline int hdr_is_valid(u32 msg_hdr)
{
struct mei_msg_hdr *mei_hdr;
u32 expected_len = 0;

mei_hdr = (struct mei_msg_hdr *)&msg_hdr;
if (!msg_hdr || mei_hdr->reserved)
return -EBADMSG;

if (mei_hdr->dma_ring && mei_hdr->length != MEI_SLOT_SIZE)
if (mei_hdr->dma_ring)
expected_len += MEI_SLOT_SIZE;
if (mei_hdr->extended)
expected_len += MEI_SLOT_SIZE;
if (mei_hdr->length < expected_len)
return -EBADMSG;

return 0;
Expand All @@ -324,6 +329,8 @@ int mei_irq_read_handler(struct mei_device *dev,
struct mei_cl *cl;
int ret;
u32 ext_meta_hdr_u32;
u32 hdr_size_left;
u32 hdr_size_ext;
int i;
int ext_hdr_end;

Expand Down Expand Up @@ -353,6 +360,7 @@ int mei_irq_read_handler(struct mei_device *dev,
}

ext_hdr_end = 1;
hdr_size_left = mei_hdr->length;

if (mei_hdr->extended) {
if (!dev->rd_msg_hdr[1]) {
Expand All @@ -363,8 +371,21 @@ int mei_irq_read_handler(struct mei_device *dev,
dev_dbg(dev->dev, "extended header is %08x\n",
ext_meta_hdr_u32);
}
meta_hdr = ((struct mei_ext_meta_hdr *)
dev->rd_msg_hdr + 1);
meta_hdr = ((struct mei_ext_meta_hdr *)dev->rd_msg_hdr + 1);
if (check_add_overflow((u32)sizeof(*meta_hdr),
mei_slots2data(meta_hdr->size),
&hdr_size_ext)) {
dev_err(dev->dev, "extended message size too big %d\n",
meta_hdr->size);
return -EBADMSG;
}
if (hdr_size_left < hdr_size_ext) {
dev_err(dev->dev, "corrupted message header len %d\n",
mei_hdr->length);
return -EBADMSG;
}
hdr_size_left -= hdr_size_ext;

ext_hdr_end = meta_hdr->size + 2;
for (i = dev->rd_msg_hdr_count; i < ext_hdr_end; i++) {
dev->rd_msg_hdr[i] = mei_read_hdr(dev);
Expand All @@ -376,6 +397,12 @@ int mei_irq_read_handler(struct mei_device *dev,
}

if (mei_hdr->dma_ring) {
if (hdr_size_left != sizeof(dev->rd_msg_hdr[ext_hdr_end])) {
dev_err(dev->dev, "corrupted message header len %d\n",
mei_hdr->length);
return -EBADMSG;
}

dev->rd_msg_hdr[ext_hdr_end] = mei_read_hdr(dev);
dev->rd_msg_hdr_count++;
(*slots)--;
Expand Down

0 comments on commit 1309ecc

Please sign in to comment.