diff options
| author | David Gibson <david@gibson.dropbear.id.au> | 2009-02-06 14:03:24 +1100 | 
|---|---|---|
| committer | Gerald Van Baren <vanbaren@cideas.com> | 2009-04-01 19:29:31 -0400 | 
| commit | a22d9cfbb5bcfb3dc6ffd64d391b568e8a0ce383 (patch) | |
| tree | 83dd65295d64b33daca89502df5c4e28e857112a /libfdt/fdt_sw.c | |
| parent | 2c0b843e710aa1e2da25c2592e6dbe5d0b0ab7da (diff) | |
| download | olio-uboot-2014.01-a22d9cfbb5bcfb3dc6ffd64d391b568e8a0ce383.tar.xz olio-uboot-2014.01-a22d9cfbb5bcfb3dc6ffd64d391b568e8a0ce383.zip | |
libfdt: Rework/cleanup fdt_next_tag()
Currently, callers of fdt_next_tag() must usually follow the call with
some sort of call to fdt_offset_ptr() to verify that the blob isn't
truncated in the middle of the tag data they're going to process.
This is a bit silly, since fdt_next_tag() generally has to call
fdt_offset_ptr() on at least some of the data following the tag for
its own operation.
This patch alters fdt_next_tag() to always use fdt_offset_ptr() to
verify the data between its starting offset and the offset it returns
in nextoffset.  This simplifies fdt_get_property() which no longer has
to verify itself that the property data is all present.
At the same time, I neaten and clarify the error handling for
fdt_next_tag().  Previously, fdt_next_tag() could return -1 instead of
a tag value in some circumstances - which almost none of the callers
checked for.  Also, fdt_next_tag() could return FDT_END either because
it encountered an FDT_END tag, or because it reached the end of the
structure block - no way was provided to tell between these cases.
With this patch, fdt_next_tag() always returns FDT_END with a negative
value in nextoffset for an error.  This means the several places which
loop looking for FDT_END will still work correctly - they only need to
check for errors at the end.  The errors which fdt_next_tag() can
report are:
	- -FDT_ERR_TRUNCATED if it reached the end of the structure
	   block instead of finding a tag.
	- -FDT_BADSTRUCTURE if a bad tag was encountered, or if the
           tag data couldn't be verified with fdt_offset_ptr().
This patch also updates the callers of fdt_next_tag(), where
appropriate, to make use of the new error reporting.
Finally, the prototype for the long gone _fdt_next_tag() is removed
from libfdt_internal.h.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'libfdt/fdt_sw.c')
| -rw-r--r-- | libfdt/fdt_sw.c | 9 | 
1 files changed, 4 insertions, 5 deletions
| diff --git a/libfdt/fdt_sw.c b/libfdt/fdt_sw.c index 698329e0c..2380b2750 100644 --- a/libfdt/fdt_sw.c +++ b/libfdt/fdt_sw.c @@ -82,7 +82,7 @@ static void *_fdt_grab_space(void *fdt, int len)  		return NULL;  	fdt_set_size_dt_struct(fdt, offset + len); -	return fdt_offset_ptr_w(fdt, offset, len); +	return _fdt_offset_ptr_w(fdt, offset);  }  int fdt_create(void *buf, int bufsize) @@ -237,18 +237,17 @@ int fdt_finish(void *fdt)  	while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {  		if (tag == FDT_PROP) {  			struct fdt_property *prop = -				fdt_offset_ptr_w(fdt, offset, sizeof(*prop)); +				_fdt_offset_ptr_w(fdt, offset);  			int nameoff; -			if (! prop) -				return -FDT_ERR_BADSTRUCTURE; -  			nameoff = fdt32_to_cpu(prop->nameoff);  			nameoff += fdt_size_dt_strings(fdt);  			prop->nameoff = cpu_to_fdt32(nameoff);  		}  		offset = nextoffset;  	} +	if (nextoffset < 0) +		return nextoffset;  	/* Finally, adjust the header */  	fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt)); |