diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-06-22 14:19:29 +0000 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-06-22 14:19:29 +0000 |
commit | f340aeab2702516684909a5030646ee8a65cd78b (patch) | |
tree | 58d8342bb44361f40362587604d1149c984c562a /linux/drivers/media/common/tuners/tuner-xc2028.c | |
parent | ab606a3833ef0453fe62bec44913375f5480cddc (diff) | |
download | mediapointer-dvb-s2-f340aeab2702516684909a5030646ee8a65cd78b.tar.gz mediapointer-dvb-s2-f340aeab2702516684909a5030646ee8a65cd78b.tar.bz2 |
xc2028 unaligned access fixes
From: Al Viro <viro@ftp.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/common/tuners/tuner-xc2028.c')
-rw-r--r-- | linux/drivers/media/common/tuners/tuner-xc2028.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/linux/drivers/media/common/tuners/tuner-xc2028.c b/linux/drivers/media/common/tuners/tuner-xc2028.c index 6a9742552..c51a7b4c8 100644 --- a/linux/drivers/media/common/tuners/tuner-xc2028.c +++ b/linux/drivers/media/common/tuners/tuner-xc2028.c @@ -20,6 +20,7 @@ #include <asm/semaphore.h> #endif #include "compat.h" +#include <asm/unaligned.h> #include "tuner-i2c.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) #include "i2c-compat.h" @@ -307,10 +308,10 @@ static int load_all_firmwares(struct dvb_frontend *fe) name[sizeof(name) - 1] = 0; p += sizeof(name) - 1; - priv->firm_version = le16_to_cpu(*(__u16 *) p); + priv->firm_version = get_unaligned_le16(p); p += 2; - n_array = le16_to_cpu(*(__u16 *) p); + n_array = get_unaligned_le16(p); p += 2; tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n", @@ -339,26 +340,26 @@ static int load_all_firmwares(struct dvb_frontend *fe) } /* Checks if there's enough bytes to read */ - if (p + sizeof(type) + sizeof(id) + sizeof(size) > endp) { - tuner_err("Firmware header is incomplete!\n"); - goto corrupt; - } + if (endp - p < sizeof(type) + sizeof(id) + sizeof(size)) + goto header; - type = le32_to_cpu(*(__u32 *) p); + type = get_unaligned_le32(p); p += sizeof(type); - id = le64_to_cpu(*(v4l2_std_id *) p); + id = get_unaligned_le64(p); p += sizeof(id); if (type & HAS_IF) { - int_freq = le16_to_cpu(*(__u16 *) p); + int_freq = get_unaligned_le16(p); 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); - if ((!size) || (size + p > endp)) { + if (!size || size > endp - p) { tuner_err("Firmware type "); dump_firm_type(type); printk("(%x), id %llx is corrupted " @@ -397,6 +398,8 @@ static int load_all_firmwares(struct dvb_frontend *fe) goto done; +header: + tuner_err("Firmware header is incomplete!\n"); corrupt: rc = -EINVAL; tuner_err("Error: firmware file is corrupted!\n"); |