]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: fix potential bufer overflows
authorSebastian Krahmer <krahmer@suse.de>
Fri, 5 Dec 2014 09:06:42 +0000 (10:06 +0100)
committerKarel Zak <kzak@redhat.com>
Fri, 5 Dec 2014 10:37:05 +0000 (11:37 +0100)
While digging deeper into libblk probing, I found that some
computations might wrap and allocate too few buffer space which then
overflows. In particular on 32bit systems (chromebook) where size_t is
32bit, this is problematic (for 64bit the result fits into the calloc
size_t).

Signed-off-by: Karel Zak <kzak@redhat.com>
libblkid/src/partitions/gpt.c
libblkid/src/probe.c
libblkid/src/superblocks/zfs.c

index 6ab4f7118f6170c3bd9e43854532fc6683979322..665577fa42a5c1aaaa418307681850b15bd3e0bf 100644 (file)
@@ -17,6 +17,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <stddef.h>
+#include <limits.h>
 
 #include "partitions.h"
 #include "crc32.h"
@@ -263,14 +264,17 @@ static struct gpt_header *get_gpt_header(
                return NULL;
        }
 
-       /* Size of blocks with GPT entries */
-       esz = le32_to_cpu(h->num_partition_entries) *
-                       le32_to_cpu(h->sizeof_partition_entry);
-       if (!esz) {
+       if (le32_to_cpu(h->num_partition_entries) == 0 ||
+           le32_to_cpu(h->sizeof_partition_entry) == 0 ||
+           ULONG_MAX / le32_to_cpu(h->num_partition_entries) < le32_to_cpu(h->sizeof_partition_entry)) {
                DBG(LOWPROBE, ul_debug("GPT entries undefined"));
                return NULL;
        }
 
+       /* Size of blocks with GPT entries */
+       esz = le32_to_cpu(h->num_partition_entries) *
+                       le32_to_cpu(h->sizeof_partition_entry);
+
        /* The header seems valid, save it
         * (we don't care about zeros in hdr->reserved2 area) */
        memcpy(hdr, h, sizeof(*h));
index 3f7e43bec6e9bb52d0ee8912cd3ccea33ec34f6f..70e882ac9b0f724389ce01c4d9477b7c0881f471 100644 (file)
 #include <inttypes.h>
 #include <stdint.h>
 #include <stdarg.h>
+#include <limits.h>
 
 #ifdef HAVE_LIBUUID
 # include <uuid.h>
@@ -578,6 +579,12 @@ unsigned char *blkid_probe_get_buffer(blkid_probe pr,
                        return NULL;
                }
 
+               /* someone trying to overflow some buffers? */
+               if (len > ULONG_MAX - sizeof(struct blkid_bufinfo)) {
+                       errno = ENOMEM;
+                       return NULL;
+               }
+
                /* allocate info and space for data by why call */
                bf = calloc(1, sizeof(struct blkid_bufinfo) + len);
                if (!bf) {
index 6ffa24d69f90dd6e97af5ba3b5dfb18ed29e9d4a..86da59d4a08bf17609707223a145e3922a5c0243 100644 (file)
@@ -12,6 +12,7 @@
 #include <errno.h>
 #include <ctype.h>
 #include <inttypes.h>
+#include <limits.h>
 
 #include "superblocks.h"
 
@@ -108,6 +109,8 @@ static void zfs_extract_guid_name(blkid_probe pr, loff_t offset)
 
                        nvs->nvs_type = be32_to_cpu(nvs->nvs_type);
                        nvs->nvs_strlen = be32_to_cpu(nvs->nvs_strlen);
+                       if (nvs->nvs_strlen > UINT_MAX - sizeof(*nvs))
+                               break;
                        avail -= nvs->nvs_strlen + sizeof(*nvs);
                        nvdebug("nvstring: type %u string %*s\n", nvs->nvs_type,
                                nvs->nvs_strlen, nvs->nvs_string);