carl9170: fix out of bounds read
authorChristian Lamparter <chunkeey@googlemail.com>
Tue, 15 Jan 2013 21:31:15 +0000 (22:31 +0100)
committerChristian Lamparter <chunkeey@googlemail.com>
Tue, 15 Jan 2013 21:31:15 +0000 (22:31 +0100)
__carlfw_find_desc didn't check whenever the area for
a descriptor was within the file length. Also it could
read beyond the file while looking for a said descriptor.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
tools/lib/carlfw.c

index ce61afb244913f1c892a878d5f6b90ac60bc287a..79a7467ad3f5e0e0f547f5263d8215b91b1d560d 100644 (file)
@@ -186,10 +186,15 @@ static void *__carlfw_find_desc(struct carlfw_file *file,
                                unsigned int len,
                                uint8_t compatible_revision)
 {
-       int scan = file->len, found = 0;
+       int scan, found = 0;
        struct carl9170fw_desc_head *tmp = NULL;
 
-       while (scan >= 0) {
+       /*
+        * Note: the last desc also has atleast a full desc_head.
+        * There's no reason for looking beyond that point.
+        */
+       scan = (file->len - 1) - (sizeof(*tmp) - CARL9170FW_MAGIC_SIZE);
+       while (scan > 0) {
                if (file->data[scan] == descid[CARL9170FW_MAGIC_SIZE - found - 1])
                        found++;
                else
@@ -202,10 +207,13 @@ static void *__carlfw_find_desc(struct carlfw_file *file,
        }
 
        if (found == CARL9170FW_MAGIC_SIZE) {
+               u16 tmp_desc_len;
+
                tmp = (void *) &file->data[scan];
+               tmp_desc_len = le16_to_cpu(tmp->length);
 
                if (!CHECK_HDR_VERSION(tmp, compatible_revision) &&
-                   (le16_to_cpu(tmp->length) >= len))
+                   (scan + tmp_desc_len <= file->len) && (tmp_desc_len >= len))
                        return tmp;
        }