Browse Source

libfdt: Introduce flat tree format v17

v17 of the blob format adds a field for the size of the structure
block, but is backwards compatible with v16.  This patch introduces
definitions for the new field, and uses it to improve the bounds
checking in the read-only code.  It also cleans up the sequential
write code using it: we no longer need to borrow the version field as
a write pointer.
main
David Gibson 18 years ago
parent
commit
fe92f6bb75
  1. 7
      fdt.c
  2. 6
      fdt.h
  3. 14
      fdt_sw.c
  4. 3
      libfdt.h
  5. 1
      libfdt_internal.h
  6. 5
      tests/trees.S

7
fdt.c

@ -33,7 +33,7 @@ int _fdt_check_header(const struct fdt_header *fdt) @@ -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) @@ -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)

6
fdt.h

@ -19,6 +19,9 @@ struct fdt_header { @@ -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 { @@ -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 */

14
fdt_sw.c

@ -32,7 +32,7 @@ static int check_header_sw(struct fdt_header *fdt) @@ -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) @@ -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) @@ -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 @@ -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) @@ -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) @@ -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) @@ -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;
}

3
libfdt.h

@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
#include <libfdt_env.h>

#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 @@ @@ -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);


1
libfdt_internal.h

@ -36,6 +36,5 @@ const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); @@ -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 */

5
tests/trees.S

@ -10,10 +10,11 @@ tree: \ @@ -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 ; \

Loading…
Cancel
Save