Skip to content

Commit

Permalink
scripts/dtc/libfdt: add integer overflow checks
Browse files Browse the repository at this point in the history
This patch applies the same changes in the original commit
below to the dtc to keep both sources in sync.

original commit:
    lib: fdt: add integer overflow checks

    added integer overflow checks to avoid buffer over reads/write
    while using the fdt header fields.

    CRs-fixed: 705078.

Bug: 19136881
Change-Id: I41843ed8e82930502432dc547f872b882c1a5b4b
Signed-off-by: Patrick Tjin <pattjin@google.com>
  • Loading branch information
vijay kumar authored and basilgello committed Nov 6, 2018
1 parent 7e3102d commit c9d1f8c
Showing 1 changed file with 22 additions and 5 deletions.
27 changes: 22 additions & 5 deletions scripts/dtc/libfdt/fdt_rw.c
Expand Up @@ -388,20 +388,31 @@ static void _fdt_packblocks(const char *old, char *new,

int fdt_open_into(const void *fdt, void *buf, int bufsize)
{
int err;
int mem_rsv_size, struct_size;
int newsize;
int err = -1;
uint32_t mem_rsv_size;
int struct_size;
uint32_t newsize;
const char *fdtstart = fdt;
const char *fdtend = fdtstart + fdt_totalsize(fdt);
const char *fdtend = NULL;
char *tmp;

if (fdtstart + fdt_totalsize(fdt) < fdtstart) {
return err;
}
fdtend = fdtstart + fdt_totalsize(fdt);
FDT_CHECK_HEADER(fdt);

if ((fdt_num_mem_rsv(fdt)+1) > (UINT_MAX / sizeof(struct fdt_reserve_entry))) {
return err;
}

mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
* sizeof(struct fdt_reserve_entry);

if (fdt_version(fdt) >= 17) {
struct_size = fdt_size_dt_struct(fdt);
if (struct_size < 0)
return struct_size;
} else {
struct_size = 0;
while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
Expand All @@ -418,16 +429,22 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
fdt_set_totalsize(buf, bufsize);
return 0;
}
if (((uint64_t)FDT_ALIGN(sizeof(struct fdt_header), 8) + (uint64_t)mem_rsv_size \
+ (uint64_t)struct_size + (uint64_t)fdt_size_dt_strings(fdt)) > UINT_MAX) {
return (err = -1);
}

/* Need to reorder */
newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
+ struct_size + fdt_size_dt_strings(fdt);

if (bufsize < newsize)
return -FDT_ERR_NOSPACE;

/* First attempt to build converted tree at beginning of buffer */
tmp = buf;
if (((tmp + newsize) < tmp) || ((buf + bufsize) < buf)) {
return (err = -1);
}
/* But if that overlaps with the old tree... */
if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
/* Try right after the old tree instead */
Expand Down

0 comments on commit c9d1f8c

Please sign in to comment.