Browse Source

libfdt: Clean up header checking functions

Many of the libfdt entry points call some sort of sanity check function
before doing anything else.  These need to do slightly different things for
the various classes of functions.

The read-only version is shared with the exported fdt_check_header(), which
limits us a bit in how we can improve it.  For that reason split the two
functions apart (though the exported one just calls the ro one for now).

We also rename the functions for more consistency - they're all named
fdt_XX_probe_() where the XX indicates which class of functions they're
for.  "probe" is a better "term" than the previous check, since they really
only do minimal validation.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Tested-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
main
David Gibson 7 years ago
parent
commit
04b5b4062c
  1. 14
      libfdt/fdt.c
  2. 6
      libfdt/fdt_overlay.c
  3. 18
      libfdt/fdt_ro.c
  4. 28
      libfdt/fdt_rw.c
  5. 18
      libfdt/fdt_sw.c
  6. 5
      libfdt/libfdt_internal.h

14
libfdt/fdt.c

@ -55,7 +55,12 @@


#include "libfdt_internal.h" #include "libfdt_internal.h"


int fdt_check_header(const void *fdt) /*
* Minimal sanity check for a read-only tree. fdt_ro_probe_() checks
* that the given buffer contains what appears to be a flattened
* device tree with sane information in its header.
*/
int fdt_ro_probe_(const void *fdt)
{ {
if (fdt_magic(fdt) == FDT_MAGIC) { if (fdt_magic(fdt) == FDT_MAGIC) {
/* Complete tree */ /* Complete tree */
@ -74,6 +79,11 @@ int fdt_check_header(const void *fdt)
return 0; return 0;
} }


int fdt_check_header(const void *fdt)
{
return fdt_ro_probe_(fdt);
}

const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
{ {
unsigned absoffset = offset + fdt_off_dt_struct(fdt); unsigned absoffset = offset + fdt_off_dt_struct(fdt);
@ -244,7 +254,7 @@ const char *fdt_find_string_(const char *strtab, int tabsize, const char *s)


int fdt_move(const void *fdt, void *buf, int bufsize) int fdt_move(const void *fdt, void *buf, int bufsize)
{ {
FDT_CHECK_HEADER(fdt); FDT_RO_PROBE(fdt);


if (fdt_totalsize(fdt) > bufsize) if (fdt_totalsize(fdt) > bufsize)
return -FDT_ERR_NOSPACE; return -FDT_ERR_NOSPACE;

6
libfdt/fdt_overlay.c

@ -697,7 +697,7 @@ static int get_path_len(const void *fdt, int nodeoffset)
int len = 0, namelen; int len = 0, namelen;
const char *name; const char *name;


FDT_CHECK_HEADER(fdt); FDT_RO_PROBE(fdt);


for (;;) { for (;;) {
name = fdt_get_name(fdt, nodeoffset, &namelen); name = fdt_get_name(fdt, nodeoffset, &namelen);
@ -866,8 +866,8 @@ int fdt_overlay_apply(void *fdt, void *fdto)
uint32_t delta = fdt_get_max_phandle(fdt); uint32_t delta = fdt_get_max_phandle(fdt);
int ret; int ret;


FDT_CHECK_HEADER(fdt); FDT_RO_PROBE(fdt);
FDT_CHECK_HEADER(fdto); FDT_RO_PROBE(fdto);


ret = overlay_adjust_local_phandles(fdto, delta); ret = overlay_adjust_local_phandles(fdto, delta);
if (ret) if (ret)

18
libfdt/fdt_ro.c

@ -117,7 +117,7 @@ uint32_t fdt_get_max_phandle(const void *fdt)


int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
{ {
FDT_CHECK_HEADER(fdt); FDT_RO_PROBE(fdt);
*address = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->address); *address = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->address);
*size = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->size); *size = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->size);
return 0; return 0;
@ -161,7 +161,7 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset,
{ {
int depth; int depth;


FDT_CHECK_HEADER(fdt); FDT_RO_PROBE(fdt);


for (depth = 0; for (depth = 0;
(offset >= 0) && (depth >= 0); (offset >= 0) && (depth >= 0);
@ -187,7 +187,7 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen)
const char *p = path; const char *p = path;
int offset = 0; int offset = 0;


FDT_CHECK_HEADER(fdt); FDT_RO_PROBE(fdt);


/* see if we have an alias */ /* see if we have an alias */
if (*path != '/') { if (*path != '/') {
@ -237,7 +237,7 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
const char *nameptr; const char *nameptr;
int err; int err;


if (((err = fdt_check_header(fdt)) != 0) if (((err = fdt_ro_probe_(fdt)) != 0)
|| ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0)) || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0))
goto fail; goto fail;


@ -462,7 +462,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
int offset, depth, namelen; int offset, depth, namelen;
const char *name; const char *name;


FDT_CHECK_HEADER(fdt); FDT_RO_PROBE(fdt);


if (buflen < 2) if (buflen < 2)
return -FDT_ERR_NOSPACE; return -FDT_ERR_NOSPACE;
@ -514,7 +514,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
int offset, depth; int offset, depth;
int supernodeoffset = -FDT_ERR_INTERNAL; int supernodeoffset = -FDT_ERR_INTERNAL;


FDT_CHECK_HEADER(fdt); FDT_RO_PROBE(fdt);


if (supernodedepth < 0) if (supernodedepth < 0)
return -FDT_ERR_NOTFOUND; return -FDT_ERR_NOTFOUND;
@ -573,7 +573,7 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
const void *val; const void *val;
int len; int len;


FDT_CHECK_HEADER(fdt); FDT_RO_PROBE(fdt);


/* FIXME: The algorithm here is pretty horrible: we scan each /* FIXME: The algorithm here is pretty horrible: we scan each
* property of a node in fdt_getprop(), then if that didn't * property of a node in fdt_getprop(), then if that didn't
@ -599,7 +599,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
if ((phandle == 0) || (phandle == -1)) if ((phandle == 0) || (phandle == -1))
return -FDT_ERR_BADPHANDLE; return -FDT_ERR_BADPHANDLE;


FDT_CHECK_HEADER(fdt); FDT_RO_PROBE(fdt);


/* FIXME: The algorithm here is pretty horrible: we /* FIXME: The algorithm here is pretty horrible: we
* potentially scan each property of a node in * potentially scan each property of a node in
@ -752,7 +752,7 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
{ {
int offset, err; int offset, err;


FDT_CHECK_HEADER(fdt); FDT_RO_PROBE(fdt);


/* FIXME: The algorithm here is pretty horrible: we scan each /* FIXME: The algorithm here is pretty horrible: we scan each
* property of a node in fdt_node_check_compatible(), then if * property of a node in fdt_node_check_compatible(), then if

28
libfdt/fdt_rw.c

@ -67,9 +67,9 @@ static int fdt_blocks_misordered_(const void *fdt,
(fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
} }


static int fdt_rw_check_header_(void *fdt) static int fdt_rw_probe_(void *fdt)
{ {
FDT_CHECK_HEADER(fdt); FDT_RO_PROBE(fdt);


if (fdt_version(fdt) < 17) if (fdt_version(fdt) < 17)
return -FDT_ERR_BADVERSION; return -FDT_ERR_BADVERSION;
@ -82,10 +82,10 @@ static int fdt_rw_check_header_(void *fdt)
return 0; return 0;
} }


#define FDT_RW_CHECK_HEADER(fdt) \ #define FDT_RW_PROBE(fdt) \
{ \ { \
int err_; \ int err_; \
if ((err_ = fdt_rw_check_header_(fdt)) != 0) \ if ((err_ = fdt_rw_probe_(fdt)) != 0) \
return err_; \ return err_; \
} }


@ -176,7 +176,7 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
struct fdt_reserve_entry *re; struct fdt_reserve_entry *re;
int err; int err;


FDT_RW_CHECK_HEADER(fdt); FDT_RW_PROBE(fdt);


re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt)); re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt));
err = fdt_splice_mem_rsv_(fdt, re, 0, 1); err = fdt_splice_mem_rsv_(fdt, re, 0, 1);
@ -192,7 +192,7 @@ int fdt_del_mem_rsv(void *fdt, int n)
{ {
struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n); struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n);


FDT_RW_CHECK_HEADER(fdt); FDT_RW_PROBE(fdt);


if (n >= fdt_num_mem_rsv(fdt)) if (n >= fdt_num_mem_rsv(fdt))
return -FDT_ERR_NOTFOUND; return -FDT_ERR_NOTFOUND;
@ -252,7 +252,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name)
int oldlen, newlen; int oldlen, newlen;
int err; int err;


FDT_RW_CHECK_HEADER(fdt); FDT_RW_PROBE(fdt);


namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen); namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
if (!namep) if (!namep)
@ -275,7 +275,7 @@ int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
struct fdt_property *prop; struct fdt_property *prop;
int err; int err;


FDT_RW_CHECK_HEADER(fdt); FDT_RW_PROBE(fdt);


err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop); err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop);
if (err == -FDT_ERR_NOTFOUND) if (err == -FDT_ERR_NOTFOUND)
@ -308,7 +308,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
struct fdt_property *prop; struct fdt_property *prop;
int err, oldlen, newlen; int err, oldlen, newlen;


FDT_RW_CHECK_HEADER(fdt); FDT_RW_PROBE(fdt);


prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
if (prop) { if (prop) {
@ -334,7 +334,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
struct fdt_property *prop; struct fdt_property *prop;
int len, proplen; int len, proplen;


FDT_RW_CHECK_HEADER(fdt); FDT_RW_PROBE(fdt);


prop = fdt_get_property_w(fdt, nodeoffset, name, &len); prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
if (!prop) if (!prop)
@ -354,7 +354,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
uint32_t tag; uint32_t tag;
fdt32_t *endtag; fdt32_t *endtag;


FDT_RW_CHECK_HEADER(fdt); FDT_RW_PROBE(fdt);


offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
if (offset >= 0) if (offset >= 0)
@ -394,7 +394,7 @@ int fdt_del_node(void *fdt, int nodeoffset)
{ {
int endoffset; int endoffset;


FDT_RW_CHECK_HEADER(fdt); FDT_RW_PROBE(fdt);


endoffset = fdt_node_end_offset_(fdt, nodeoffset); endoffset = fdt_node_end_offset_(fdt, nodeoffset);
if (endoffset < 0) if (endoffset < 0)
@ -435,7 +435,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
const char *fdtend = fdtstart + fdt_totalsize(fdt); const char *fdtend = fdtstart + fdt_totalsize(fdt);
char *tmp; char *tmp;


FDT_CHECK_HEADER(fdt); FDT_RO_PROBE(fdt);


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);
@ -494,7 +494,7 @@ int fdt_pack(void *fdt)
{ {
int mem_rsv_size; int mem_rsv_size;


FDT_RW_CHECK_HEADER(fdt); FDT_RW_PROBE(fdt);


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

18
libfdt/fdt_sw.c

@ -55,7 +55,7 @@


#include "libfdt_internal.h" #include "libfdt_internal.h"


static int fdt_sw_check_header_(void *fdt) static int fdt_sw_probe_(void *fdt)
{ {
if (fdt_magic(fdt) != FDT_SW_MAGIC) if (fdt_magic(fdt) != FDT_SW_MAGIC)
return -FDT_ERR_BADMAGIC; return -FDT_ERR_BADMAGIC;
@ -63,10 +63,10 @@ static int fdt_sw_check_header_(void *fdt)
return 0; return 0;
} }


#define FDT_SW_CHECK_HEADER(fdt) \ #define FDT_SW_PROBE(fdt) \
{ \ { \
int err; \ int err; \
if ((err = fdt_sw_check_header_(fdt)) != 0) \ if ((err = fdt_sw_probe_(fdt)) != 0) \
return err; \ return err; \
} }


@ -112,7 +112,7 @@ int fdt_resize(void *fdt, void *buf, int bufsize)
size_t headsize, tailsize; size_t headsize, tailsize;
char *oldtail, *newtail; char *oldtail, *newtail;


FDT_SW_CHECK_HEADER(fdt); FDT_SW_PROBE(fdt);


headsize = fdt_off_dt_struct(fdt); headsize = fdt_off_dt_struct(fdt);
tailsize = fdt_size_dt_strings(fdt); tailsize = fdt_size_dt_strings(fdt);
@ -144,7 +144,7 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
struct fdt_reserve_entry *re; struct fdt_reserve_entry *re;
int offset; int offset;


FDT_SW_CHECK_HEADER(fdt); FDT_SW_PROBE(fdt);


if (fdt_size_dt_struct(fdt)) if (fdt_size_dt_struct(fdt))
return -FDT_ERR_BADSTATE; return -FDT_ERR_BADSTATE;
@ -172,7 +172,7 @@ int fdt_begin_node(void *fdt, const char *name)
struct fdt_node_header *nh; struct fdt_node_header *nh;
int namelen = strlen(name) + 1; int namelen = strlen(name) + 1;


FDT_SW_CHECK_HEADER(fdt); FDT_SW_PROBE(fdt);


nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
if (! nh) if (! nh)
@ -187,7 +187,7 @@ int fdt_end_node(void *fdt)
{ {
fdt32_t *en; fdt32_t *en;


FDT_SW_CHECK_HEADER(fdt); FDT_SW_PROBE(fdt);


en = fdt_grab_space_(fdt, FDT_TAGSIZE); en = fdt_grab_space_(fdt, FDT_TAGSIZE);
if (! en) if (! en)
@ -225,7 +225,7 @@ int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)
struct fdt_property *prop; struct fdt_property *prop;
int nameoff; int nameoff;


FDT_SW_CHECK_HEADER(fdt); FDT_SW_PROBE(fdt);


nameoff = fdt_find_add_string_(fdt, name); nameoff = fdt_find_add_string_(fdt, name);
if (nameoff == 0) if (nameoff == 0)
@ -262,7 +262,7 @@ int fdt_finish(void *fdt)
uint32_t tag; uint32_t tag;
int offset, nextoffset; int offset, nextoffset;


FDT_SW_CHECK_HEADER(fdt); FDT_SW_PROBE(fdt);


/* Add terminator */ /* Add terminator */
end = fdt_grab_space_(fdt, sizeof(*end)); end = fdt_grab_space_(fdt, sizeof(*end));

5
libfdt/libfdt_internal.h

@ -55,10 +55,11 @@
#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) #define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))


#define FDT_CHECK_HEADER(fdt) \ int fdt_ro_probe_(const void *fdt);
#define FDT_RO_PROBE(fdt) \
{ \ { \
int err_; \ int err_; \
if ((err_ = fdt_check_header(fdt)) != 0) \ if ((err_ = fdt_ro_probe_(fdt)) != 0) \
return err_; \ return err_; \
} }



Loading…
Cancel
Save