Commit 84a9f336 authored by Al Viro's avatar Al Viro Committed by Mauro Carvalho Chehab

V4L/DVB (8136): xc2028 unaligned access fixes

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 153755a7
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <media/tuner.h> #include <media/tuner.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <asm/unaligned.h>
#include "tuner-i2c.h" #include "tuner-i2c.h"
#include "tuner-xc2028.h" #include "tuner-xc2028.h"
#include "tuner-xc2028-types.h" #include "tuner-xc2028-types.h"
...@@ -292,10 +293,10 @@ static int load_all_firmwares(struct dvb_frontend *fe) ...@@ -292,10 +293,10 @@ static int load_all_firmwares(struct dvb_frontend *fe)
name[sizeof(name) - 1] = 0; name[sizeof(name) - 1] = 0;
p += sizeof(name) - 1; p += sizeof(name) - 1;
priv->firm_version = le16_to_cpu(*(__u16 *) p); priv->firm_version = get_unaligned_le16(p);
p += 2; p += 2;
n_array = le16_to_cpu(*(__u16 *) p); n_array = get_unaligned_le16(p);
p += 2; p += 2;
tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n", tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n",
...@@ -324,26 +325,26 @@ static int load_all_firmwares(struct dvb_frontend *fe) ...@@ -324,26 +325,26 @@ static int load_all_firmwares(struct dvb_frontend *fe)
} }
/* Checks if there's enough bytes to read */ /* Checks if there's enough bytes to read */
if (p + sizeof(type) + sizeof(id) + sizeof(size) > endp) { if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
tuner_err("Firmware header is incomplete!\n"); goto header;
goto corrupt;
}
type = le32_to_cpu(*(__u32 *) p); type = get_unaligned_le32(p);
p += sizeof(type); p += sizeof(type);
id = le64_to_cpu(*(v4l2_std_id *) p); id = get_unaligned_le64(p);
p += sizeof(id); p += sizeof(id);
if (type & HAS_IF) { if (type & HAS_IF) {
int_freq = le16_to_cpu(*(__u16 *) p); int_freq = get_unaligned_le16(p);
p += sizeof(int_freq); p += sizeof(int_freq);
if (endp - p < sizeof(size))
goto header;
} }
size = le32_to_cpu(*(__u32 *) p); size = get_unaligned_le32(p);
p += sizeof(size); p += sizeof(size);
if ((!size) || (size + p > endp)) { if (!size || size > endp - p) {
tuner_err("Firmware type "); tuner_err("Firmware type ");
dump_firm_type(type); dump_firm_type(type);
printk("(%x), id %llx is corrupted " printk("(%x), id %llx is corrupted "
...@@ -382,6 +383,8 @@ static int load_all_firmwares(struct dvb_frontend *fe) ...@@ -382,6 +383,8 @@ static int load_all_firmwares(struct dvb_frontend *fe)
goto done; goto done;
header:
tuner_err("Firmware header is incomplete!\n");
corrupt: corrupt:
rc = -EINVAL; rc = -EINVAL;
tuner_err("Error: firmware file is corrupted!\n"); tuner_err("Error: firmware file is corrupted!\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment