libblkid: fix potential bufer overflows
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>
This commit is contained in:
parent
764b697c56
commit
109df14fad
|
@ -17,6 +17,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "partitions.h"
|
#include "partitions.h"
|
||||||
#include "crc32.h"
|
#include "crc32.h"
|
||||||
|
@ -263,14 +264,17 @@ static struct gpt_header *get_gpt_header(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Size of blocks with GPT entries */
|
if (le32_to_cpu(h->num_partition_entries) == 0 ||
|
||||||
esz = le32_to_cpu(h->num_partition_entries) *
|
le32_to_cpu(h->sizeof_partition_entry) == 0 ||
|
||||||
le32_to_cpu(h->sizeof_partition_entry);
|
ULONG_MAX / le32_to_cpu(h->num_partition_entries) < le32_to_cpu(h->sizeof_partition_entry)) {
|
||||||
if (!esz) {
|
|
||||||
DBG(LOWPROBE, ul_debug("GPT entries undefined"));
|
DBG(LOWPROBE, ul_debug("GPT entries undefined"));
|
||||||
return NULL;
|
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
|
/* The header seems valid, save it
|
||||||
* (we don't care about zeros in hdr->reserved2 area) */
|
* (we don't care about zeros in hdr->reserved2 area) */
|
||||||
memcpy(hdr, h, sizeof(*h));
|
memcpy(hdr, h, sizeof(*h));
|
||||||
|
|
|
@ -103,6 +103,7 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#ifdef HAVE_LIBUUID
|
#ifdef HAVE_LIBUUID
|
||||||
# include <uuid.h>
|
# include <uuid.h>
|
||||||
|
@ -578,6 +579,12 @@ unsigned char *blkid_probe_get_buffer(blkid_probe pr,
|
||||||
return NULL;
|
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 */
|
/* allocate info and space for data by why call */
|
||||||
bf = calloc(1, sizeof(struct blkid_bufinfo) + len);
|
bf = calloc(1, sizeof(struct blkid_bufinfo) + len);
|
||||||
if (!bf) {
|
if (!bf) {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "superblocks.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_type = be32_to_cpu(nvs->nvs_type);
|
||||||
nvs->nvs_strlen = be32_to_cpu(nvs->nvs_strlen);
|
nvs->nvs_strlen = be32_to_cpu(nvs->nvs_strlen);
|
||||||
|
if (nvs->nvs_strlen > UINT_MAX - sizeof(*nvs))
|
||||||
|
break;
|
||||||
avail -= nvs->nvs_strlen + sizeof(*nvs);
|
avail -= nvs->nvs_strlen + sizeof(*nvs);
|
||||||
nvdebug("nvstring: type %u string %*s\n", nvs->nvs_type,
|
nvdebug("nvstring: type %u string %*s\n", nvs->nvs_type,
|
||||||
nvs->nvs_strlen, nvs->nvs_string);
|
nvs->nvs_strlen, nvs->nvs_string);
|
||||||
|
|
Loading…
Reference in New Issue