diff --git a/fdt.c b/fdt.c index d3844fc..4271dfd 100644 --- a/fdt.c +++ b/fdt.c @@ -33,7 +33,7 @@ int _fdt_check_header(const struct fdt_header *fdt) return FDT_ERR_BADVERSION; } else if (fdt_magic(fdt) == SW_MAGIC) { /* Unfinished sequential-write blob */ - if (sw_size_dt_struct(fdt) == 0) + if (fdt_size_dt_struct(fdt) == 0) return FDT_ERR_BADSTATE; } else { return FDT_ERR_BADMAGIC; @@ -46,6 +46,11 @@ void *fdt_offset_ptr(const struct fdt_header *fdt, int offset, int len) { void *p; + if (fdt_version(fdt) >= 0x11) + if (((offset + len) < offset) + || ((offset + len) > fdt_size_dt_struct(fdt))) + return NULL; + p = (void *)fdt + fdt_off_dt_struct(fdt) + offset; if (p + len < p) diff --git a/fdt.h b/fdt.h index 10b5544..fff533e 100644 --- a/fdt.h +++ b/fdt.h @@ -19,6 +19,9 @@ struct fdt_header { booting on */ /* version 3 fields below */ uint32_t size_dt_strings; /* size of the strings block */ + + /* version 17 fields below */ + uint32_t size_dt_struct; /* size of the structure block */ }; struct fdt_reserve_entry { @@ -53,6 +56,7 @@ struct fdt_property { #define FDT_V1_SIZE (7*sizeof(uint32_t)) #define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t)) #define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t)) - +#define FDT_V16_SIZE FDT_V3_SIZE +#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t)) #endif /* _FDT_H */ diff --git a/fdt_sw.c b/fdt_sw.c index 89abacb..1a6b2cf 100644 --- a/fdt_sw.c +++ b/fdt_sw.c @@ -32,7 +32,7 @@ static int check_header_sw(struct fdt_header *fdt) static void *grab_space(struct fdt_header *fdt, int len) { - int offset = sw_size_dt_struct(fdt); + int offset = fdt_size_dt_struct(fdt); int spaceleft; spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt) @@ -41,7 +41,7 @@ static void *grab_space(struct fdt_header *fdt, int len) if ((offset + len < offset) || (offset + len > spaceleft)) return NULL; - fdt->version = cpu_to_fdt32(offset + len); + fdt->size_dt_struct = cpu_to_fdt32(offset + len); return fdt_offset_ptr(fdt, offset, len); } @@ -55,6 +55,8 @@ struct fdt_header *fdt_create(void *buf, int bufsize) memset(buf, 0, bufsize); fdt->magic = cpu_to_fdt32(SW_MAGIC); + fdt->version = cpu_to_fdt32(FDT_LAST_SUPPORTED_VERSION); + fdt->last_comp_version= cpu_to_fdt32(FDT_FIRST_SUPPORTED_VERSION); fdt->totalsize = cpu_to_fdt32(bufsize); fdt->off_mem_rsvmap = cpu_to_fdt32(ALIGN(sizeof(*fdt), @@ -73,7 +75,7 @@ int fdt_add_reservemap_entry(struct fdt_header *fdt, uint64_t addr, uint64_t siz if (err) return err; - if (sw_size_dt_struct(fdt)) + if (fdt_size_dt_struct(fdt)) return FDT_ERR_BADSTATE; offset = fdt_off_dt_struct(fdt); @@ -142,7 +144,7 @@ static int find_add_string(struct fdt_header *fdt, const char *s) /* Add it */ offset = -strtabsize - len; - struct_top = fdt_off_dt_struct(fdt) + sw_size_dt_struct(fdt); + struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); if (fdt_totalsize(fdt) + offset < struct_top) return 0; /* no more room :( */ @@ -195,7 +197,7 @@ int fdt_finish(struct fdt_header *fdt) /* Relocate the string table */ oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt); - newstroffset = fdt_off_dt_struct(fdt) + sw_size_dt_struct(fdt); + newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt)); fdt->off_dt_strings = fdt32_to_cpu(newstroffset); @@ -219,8 +221,6 @@ int fdt_finish(struct fdt_header *fdt) /* Finally, adjust the header */ fdt->totalsize = cpu_to_fdt32(newstroffset + fdt_size_dt_strings(fdt)); - fdt->version = cpu_to_fdt32(FDT_LAST_SUPPORTED_VERSION); - fdt->last_comp_version= cpu_to_fdt32(FDT_FIRST_SUPPORTED_VERSION); fdt->magic = cpu_to_fdt32(FDT_MAGIC); return 0; } diff --git a/libfdt.h b/libfdt.h index c0ee2b7..a3da19c 100644 --- a/libfdt.h +++ b/libfdt.h @@ -23,7 +23,7 @@ #include #define FDT_FIRST_SUPPORTED_VERSION 0x10 -#define FDT_LAST_SUPPORTED_VERSION 0x10 +#define FDT_LAST_SUPPORTED_VERSION 0x11 /* Errors */ #define FDT_ERR_OK 0 @@ -52,6 +52,7 @@ #define fdt_last_comp_version(fdt) (fdt32_to_cpu(fdt)->last_comp_version) #define fdt_boot_cpuid_phys(fdt) (fdt32_to_cpu(fdt)->boot_cpuid_phys) #define fdt_size_dt_strings(fdt) (fdt32_to_cpu(fdt)->size_dt_strings) +#define fdt_size_dt_struct(fdt) (fdt32_to_cpu(fdt)->size_dt_struct) void *fdt_offset_ptr(const struct fdt_header *fdt, int offset, int checklen); diff --git a/libfdt_internal.h b/libfdt_internal.h index 96f5fa8..67ef91d 100644 --- a/libfdt_internal.h +++ b/libfdt_internal.h @@ -36,6 +36,5 @@ const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); #define PTR_ERROR(code) (void *)(-(code)) #define SW_MAGIC (~FDT_MAGIC) -#define sw_size_dt_struct(fdt) (fdt32_to_cpu(((fdt)->version))) #endif /* _LIBFDT_INTERNAL_H */ diff --git a/tests/trees.S b/tests/trees.S index 095f781..7fa4e65 100644 --- a/tests/trees.S +++ b/tests/trees.S @@ -10,10 +10,11 @@ tree: \ .long tree##_struct - tree ; \ .long tree##_strings - tree ; \ .long tree##_rsvmap - tree ; \ - .long 0x10 ; \ + .long 0x11 ; \ .long 0x10 ; \ .long 0 ; \ - .long tree##_end - tree##_strings ; + .long tree##_end - tree##_strings ; \ + .long tree##_strings - tree##_struct ; #define RSVMAP_ENTRY(addr, len) \ .quad addr ; \