aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common/tuners/tuner-xc2028.c
diff options
context:
space:
mode:
authorAl Viro <viro@ftp.linux.org.uk>2008-06-22 13:19:29 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:13:50 -0400
commit84a9f33614e3cfcc7326629a503d4389c9d84e0f (patch)
tree2d13e91561d455f41467dab521e935532a5e4a7d /drivers/media/common/tuners/tuner-xc2028.c
parent153755a774578dcf921f8145e786ce25f72368d2 (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/tuners/tuner-xc2028.c')
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.c25
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
386header:
387 tuner_err("Firmware header is incomplete!\n");
385corrupt: 388corrupt:
386 rc = -EINVAL; 389 rc = -EINVAL;
387 tuner_err("Error: firmware file is corrupted!\n"); 390 tuner_err("Error: firmware file is corrupted!\n");