mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
scripts/dtc/libfdt: add integer overflow checks
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. Change-Id: I062ee9e0610eeeeea32dd95695b18aa9dbca06ea Bug: 19136881 Signed-off-by: Patrick Tjin <pattjin@google.com>
This commit is contained in:
parent
18d456d3b2
commit
c4a17c8dd4
1 changed files with 22 additions and 5 deletions
|
@ -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 fdt_open_into(const void *fdt, void *buf, int bufsize)
|
||||||
{
|
{
|
||||||
int err;
|
int err = -1;
|
||||||
int mem_rsv_size, struct_size;
|
uint32_t mem_rsv_size;
|
||||||
int newsize;
|
int struct_size;
|
||||||
|
uint32_t newsize;
|
||||||
const char *fdtstart = fdt;
|
const char *fdtstart = fdt;
|
||||||
const char *fdtend = fdtstart + fdt_totalsize(fdt);
|
const char *fdtend = NULL;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
|
if (fdtstart + fdt_totalsize(fdt) < fdtstart) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
fdtend = fdtstart + fdt_totalsize(fdt);
|
||||||
FDT_CHECK_HEADER(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)
|
mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
|
||||||
* sizeof(struct fdt_reserve_entry);
|
* sizeof(struct fdt_reserve_entry);
|
||||||
|
|
||||||
if (fdt_version(fdt) >= 17) {
|
if (fdt_version(fdt) >= 17) {
|
||||||
struct_size = fdt_size_dt_struct(fdt);
|
struct_size = fdt_size_dt_struct(fdt);
|
||||||
|
if (struct_size < 0)
|
||||||
|
return struct_size;
|
||||||
} else {
|
} else {
|
||||||
struct_size = 0;
|
struct_size = 0;
|
||||||
while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
|
while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
|
||||||
|
@ -418,16 +429,22 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
|
||||||
fdt_set_totalsize(buf, bufsize);
|
fdt_set_totalsize(buf, bufsize);
|
||||||
return 0;
|
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 */
|
/* Need to reorder */
|
||||||
newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
|
newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
|
||||||
+ struct_size + fdt_size_dt_strings(fdt);
|
+ struct_size + fdt_size_dt_strings(fdt);
|
||||||
|
|
||||||
if (bufsize < newsize)
|
if (bufsize < newsize)
|
||||||
return -FDT_ERR_NOSPACE;
|
return -FDT_ERR_NOSPACE;
|
||||||
|
|
||||||
/* First attempt to build converted tree at beginning of buffer */
|
/* First attempt to build converted tree at beginning of buffer */
|
||||||
tmp = buf;
|
tmp = buf;
|
||||||
|
if (((tmp + newsize) < tmp) || ((buf + bufsize) < buf)) {
|
||||||
|
return (err = -1);
|
||||||
|
}
|
||||||
/* But if that overlaps with the old tree... */
|
/* But if that overlaps with the old tree... */
|
||||||
if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
|
if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
|
||||||
/* Try right after the old tree instead */
|
/* Try right after the old tree instead */
|
||||||
|
|
Loading…
Reference in a new issue