diff options
author | Al Viro <viro@ftp.linux.org.uk> | 2008-06-22 13:19:29 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-20 06:13:50 -0400 |
commit | 84a9f33614e3cfcc7326629a503d4389c9d84e0f (patch) | |
tree | 2d13e91561d455f41467dab521e935532a5e4a7d /drivers/media/common | |
parent | 153755a774578dcf921f8145e786ce25f72368d2 (diff) |
V4L/DVB (8136): xc2028 unaligned access fixes
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/common')
-rw-r--r-- | drivers/media/common/tuners/tuner-xc2028.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 30eb07b7f9ef..4dd1d2421cc5 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <media/tuner.h> | 16 | #include <media/tuner.h> |
17 | #include <linux/mutex.h> | 17 | #include <linux/mutex.h> |
18 | #include <asm/unaligned.h> | ||
18 | #include "tuner-i2c.h" | 19 | #include "tuner-i2c.h" |
19 | #include "tuner-xc2028.h" | 20 | #include "tuner-xc2028.h" |
20 | #include "tuner-xc2028-types.h" | 21 | #include "tuner-xc2028-types.h" |
@@ -292,10 +293,10 @@ static int load_all_firmwares(struct dvb_frontend *fe) | |||
292 | name[sizeof(name) - 1] = 0; | 293 | name[sizeof(name) - 1] = 0; |
293 | p += sizeof(name) - 1; | 294 | p += sizeof(name) - 1; |
294 | 295 | ||
295 | priv->firm_version = le16_to_cpu(*(__u16 *) p); | 296 | priv->firm_version = get_unaligned_le16(p); |
296 | p += 2; | 297 | p += 2; |
297 | 298 | ||
298 | n_array = le16_to_cpu(*(__u16 *) p); | 299 | n_array = get_unaligned_le16(p); |
299 | p += 2; | 300 | p += 2; |
300 | 301 | ||
301 | tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n", | 302 | 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 | } | 325 | } |
325 | 326 | ||
326 | /* Checks if there's enough bytes to read */ | 327 | /* Checks if there's enough bytes to read */ |
327 | if (p + sizeof(type) + sizeof(id) + sizeof(size) > endp) { | 328 | if (endp - p < sizeof(type) + sizeof(id) + sizeof(size)) |
328 | tuner_err("Firmware header is incomplete!\n"); | 329 | goto header; |
329 | goto corrupt; | ||
330 | } | ||
331 | 330 | ||
332 | type = le32_to_cpu(*(__u32 *) p); | 331 | type = get_unaligned_le32(p); |
333 | p += sizeof(type); | 332 | p += sizeof(type); |
334 | 333 | ||
335 | id = le64_to_cpu(*(v4l2_std_id *) p); | 334 | id = get_unaligned_le64(p); |
336 | p += sizeof(id); | 335 | p += sizeof(id); |
337 | 336 | ||
338 | if (type & HAS_IF) { | 337 | if (type & HAS_IF) { |
339 | int_freq = le16_to_cpu(*(__u16 *) p); | 338 | int_freq = get_unaligned_le16(p); |
340 | p += sizeof(int_freq); | 339 | p += sizeof(int_freq); |
340 | if (endp - p < sizeof(size)) | ||
341 | goto header; | ||
341 | } | 342 | } |
342 | 343 | ||
343 | size = le32_to_cpu(*(__u32 *) p); | 344 | size = get_unaligned_le32(p); |
344 | p += sizeof(size); | 345 | p += sizeof(size); |
345 | 346 | ||
346 | if ((!size) || (size + p > endp)) { | 347 | if (!size || size > endp - p) { |
347 | tuner_err("Firmware type "); | 348 | tuner_err("Firmware type "); |
348 | dump_firm_type(type); | 349 | dump_firm_type(type); |
349 | printk("(%x), id %llx is corrupted " | 350 | printk("(%x), id %llx is corrupted " |
@@ -382,6 +383,8 @@ static int load_all_firmwares(struct dvb_frontend *fe) | |||
382 | 383 | ||
383 | goto done; | 384 | goto done; |
384 | 385 | ||
386 | header: | ||
387 | tuner_err("Firmware header is incomplete!\n"); | ||
385 | corrupt: | 388 | corrupt: |
386 | rc = -EINVAL; | 389 | rc = -EINVAL; |
387 | tuner_err("Error: firmware file is corrupted!\n"); | 390 | tuner_err("Error: firmware file is corrupted!\n"); |