diff options
| -rw-r--r-- | libfdt/fdt.c | 17 | ||||
| -rw-r--r-- | libfdt/fdt_ro.c | 26 | ||||
| -rw-r--r-- | libfdt/fdt_rw.c | 24 | ||||
| -rw-r--r-- | libfdt/fdt_sw.c | 31 | ||||
| -rw-r--r-- | libfdt/libfdt_internal.h | 1 | 
5 files changed, 44 insertions, 55 deletions
| diff --git a/libfdt/fdt.c b/libfdt/fdt.c index cfa1989d8..cb08ba0a9 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -133,16 +133,23 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset)  	return tag;  } +int _fdt_check_node_offset(const void *fdt, int offset) +{ +	if ((offset < 0) || (offset % FDT_TAGSIZE) +	    || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE)) +		return -FDT_ERR_BADOFFSET; + +	return offset; +} +  int fdt_next_node(const void *fdt, int offset, int *depth)  {  	int nextoffset = 0;  	uint32_t tag; -	if (offset >= 0) { -		tag = fdt_next_tag(fdt, offset, &nextoffset); -		if (tag != FDT_BEGIN_NODE) -			return -FDT_ERR_BADOFFSET; -	} +	if (offset >= 0) +		if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0) +			return nextoffset;  	do {  		offset = nextoffset; diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 11d80d2fa..69af7bb84 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -161,16 +161,12 @@ int fdt_path_offset(const void *fdt, const char *path)  const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)  { -	const struct fdt_node_header *nh; +	const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);  	int err; -	if ((err = fdt_check_header(fdt)) != 0) -		goto fail; - -	err = -FDT_ERR_BADOFFSET; -	nh = fdt_offset_ptr(fdt, nodeoffset, sizeof(*nh)); -	if (!nh || (fdt32_to_cpu(nh->tag) != FDT_BEGIN_NODE)) -		goto fail; +	if (((err = fdt_check_header(fdt)) != 0) +	    || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0)) +			goto fail;  	if (len)  		*len = strlen(nh->name); @@ -193,17 +189,11 @@ const struct fdt_property *fdt_get_property(const void *fdt,  	int offset, nextoffset;  	int err; -	if ((err = fdt_check_header(fdt)) != 0) -		goto fail; - -	err = -FDT_ERR_BADOFFSET; -	if (nodeoffset % FDT_TAGSIZE) -		goto fail; - -	tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); -	if (tag != FDT_BEGIN_NODE) -		goto fail; +	if (((err = fdt_check_header(fdt)) != 0) +	    || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0)) +			goto fail; +	nextoffset = err;  	do {  		offset = nextoffset; diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c index 8609fa7d7..95a5c2c62 100644 --- a/libfdt/fdt_rw.c +++ b/libfdt/fdt_rw.c @@ -176,8 +176,7 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)  	struct fdt_reserve_entry *re;  	int err; -	if ((err = rw_check_header(fdt))) -		return err; +	RW_CHECK_HEADER(fdt);  	re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));  	err = _blob_splice_mem_rsv(fdt, re, 0, 1); @@ -194,8 +193,8 @@ int fdt_del_mem_rsv(void *fdt, int n)  	struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);  	int err; -	if ((err = rw_check_header(fdt))) -		return err; +	RW_CHECK_HEADER(fdt); +  	if (n >= fdt_num_mem_rsv(fdt))  		return -FDT_ERR_NOTFOUND; @@ -227,15 +226,13 @@ static int _resize_property(void *fdt, int nodeoffset, const char *name, int len  static int _add_property(void *fdt, int nodeoffset, const char *name, int len,  			 struct fdt_property **prop)  { -	uint32_t tag;  	int proplen;  	int nextoffset;  	int namestroff;  	int err; -	tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); -	if (tag != FDT_BEGIN_NODE) -		return -FDT_ERR_BADOFFSET; +	if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) +		return nextoffset;  	namestroff = _find_add_string(fdt, name);  	if (namestroff < 0) @@ -260,8 +257,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name)  	int oldlen, newlen;  	int err; -	if ((err = rw_check_header(fdt))) -		return err; +	RW_CHECK_HEADER(fdt);  	namep = (char *)fdt_get_name(fdt, nodeoffset, &oldlen);  	if (!namep) @@ -284,8 +280,7 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,  	struct fdt_property *prop;  	int err; -	if ((err = rw_check_header(fdt))) -		return err; +	RW_CHECK_HEADER(fdt);  	err = _resize_property(fdt, nodeoffset, name, len, &prop);  	if (err == -FDT_ERR_NOTFOUND) @@ -456,11 +451,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)  int fdt_pack(void *fdt)  {  	int mem_rsv_size; -	int err; -	err = rw_check_header(fdt); -	if (err) -		return err; +	RW_CHECK_HEADER(fdt);  	mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)  		* sizeof(struct fdt_reserve_entry); diff --git a/libfdt/fdt_sw.c b/libfdt/fdt_sw.c index dda2de34b..df0987606 100644 --- a/libfdt/fdt_sw.c +++ b/libfdt/fdt_sw.c @@ -55,13 +55,21 @@  #include "libfdt_internal.h" -static int check_header_sw(void *fdt) +static int sw_check_header(void *fdt)  {  	if (fdt_magic(fdt) != SW_MAGIC)  		return -FDT_ERR_BADMAGIC; +	/* FIXME: should check more details about the header state */  	return 0;  } +#define SW_CHECK_HEADER(fdt) \ +	{ \ +		int err; \ +		if ((err = sw_check_header(fdt)) != 0) \ +			return err; \ +	} +  static void *grab_space(void *fdt, int len)  {  	int offset = fdt_size_dt_struct(fdt); @@ -102,11 +110,10 @@ int fdt_create(void *buf, int bufsize)  int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)  {  	struct fdt_reserve_entry *re; -	int err = check_header_sw(fdt);  	int offset; -	if (err) -		return err; +	SW_CHECK_HEADER(fdt); +  	if (fdt_size_dt_struct(fdt))  		return -FDT_ERR_BADSTATE; @@ -131,11 +138,9 @@ int fdt_finish_reservemap(void *fdt)  int fdt_begin_node(void *fdt, const char *name)  {  	struct fdt_node_header *nh; -	int err = check_header_sw(fdt);  	int namelen = strlen(name) + 1; -	if (err) -		return err; +	SW_CHECK_HEADER(fdt);  	nh = grab_space(fdt, sizeof(*nh) + ALIGN(namelen, FDT_TAGSIZE));  	if (! nh) @@ -149,10 +154,8 @@ int fdt_begin_node(void *fdt, const char *name)  int fdt_end_node(void *fdt)  {  	uint32_t *en; -	int err = check_header_sw(fdt); -	if (err) -		return err; +	SW_CHECK_HEADER(fdt);  	en = grab_space(fdt, FDT_TAGSIZE);  	if (! en) @@ -188,11 +191,9 @@ static int find_add_string(void *fdt, const char *s)  int fdt_property(void *fdt, const char *name, const void *val, int len)  {  	struct fdt_property *prop; -	int err = check_header_sw(fdt);  	int nameoff; -	if (err) -		return err; +	SW_CHECK_HEADER(fdt);  	nameoff = find_add_string(fdt, name);  	if (nameoff == 0) @@ -211,15 +212,13 @@ int fdt_property(void *fdt, const char *name, const void *val, int len)  int fdt_finish(void *fdt)  { -	int err = check_header_sw(fdt);  	char *p = (char *)fdt;  	uint32_t *end;  	int oldstroffset, newstroffset;  	uint32_t tag;  	int offset, nextoffset; -	if (err) -		return err; +	SW_CHECK_HEADER(fdt);  	/* Add terminator */  	end = grab_space(fdt, sizeof(*end)); diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h index 52e1b8d81..f72e70dbe 100644 --- a/libfdt/libfdt_internal.h +++ b/libfdt/libfdt_internal.h @@ -66,6 +66,7 @@  	}  uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset); +int _fdt_check_node_offset(const void *fdt, int offset);  const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);  int _fdt_node_end_offset(void *fdt, int nodeoffset); |