Re: [PATCH 3/7] libfdt: Allow control of checks in fdt_ro.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



On Sat, Jul 20, 2019 at 05:31:08PM -0600, Simon Glass wrote:
> This file provides read-only access to the device tree and includes many
> sanity checks. Allow these checks to be disabled to reduce code size.
> 
> Signed-off-by: Simon Glass <sjg@xxxxxxxxxxxx>
> ---
> 
>  libfdt/fdt_ro.c | 73 +++++++++++++++++++++++++++++++------------------
>  1 file changed, 47 insertions(+), 26 deletions(-)
> 
> diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
> index 6fd9ec1..bc1b4e0 100644
> --- a/libfdt/fdt_ro.c
> +++ b/libfdt/fdt_ro.c
> @@ -14,9 +14,13 @@ static int fdt_nodename_eq_(const void *fdt, int offset,
>  			    const char *s, int len)
>  {
>  	int olen;
> -	const char *p = fdt_get_name(fdt, offset, &olen);
> +	const char *p;
>  
> -	if (!p || olen < len)
> +	if (_check2())
> +		p = fdt_get_name(fdt, offset, &olen);
> +	else
> +		p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);

Here we're not just excising code based on check level but taking a
different path.  This makes me nervous about fragility - I'd be a lot
more comfortable if we could somehow extend the testsuite to run at
all the different check levels (except for tests that clearly rely on
the extra checking, obviously).

> +	if (!p || (_check2() && olen < len))
>  		/* short match */
>  		return 0;
>  
> @@ -33,16 +37,19 @@ static int fdt_nodename_eq_(const void *fdt, int offset,
>  
>  const char *fdt_get_string(const void *fdt, int stroffset, int *lenp)
>  {
> -	uint32_t absoffset = stroffset + fdt_off_dt_strings(fdt);
> +	uint32_t absoffset;
>  	size_t len;
>  	int err;
>  	const char *s, *n;
>  
> +	if (!_check2())
> +		return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
>  	err = fdt_ro_probe_(fdt);
>  	if (err != 0)
>  		goto fail;
>  
>  	err = -FDT_ERR_BADOFFSET;
> +	absoffset = stroffset + fdt_off_dt_strings(fdt);
>  	if (absoffset >= fdt_totalsize(fdt))
>  		goto fail;
>  	len = fdt_totalsize(fdt) - absoffset;
> @@ -150,10 +157,13 @@ static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n)
>  	int offset = n * sizeof(struct fdt_reserve_entry);
>  	int absoffset = fdt_off_mem_rsvmap(fdt) + offset;
>  
> -	if (absoffset < fdt_off_mem_rsvmap(fdt))
> -		return NULL;
> -	if (absoffset > fdt_totalsize(fdt) - sizeof(struct fdt_reserve_entry))
> -		return NULL;
> +	if (_check2()) {
> +		if (absoffset < fdt_off_mem_rsvmap(fdt))
> +			return NULL;
> +		if (absoffset > fdt_totalsize(fdt) -
> +		    sizeof(struct fdt_reserve_entry))
> +			return NULL;
> +	}
>  	return fdt_mem_rsv_(fdt, n);
>  }
>  
> @@ -163,7 +173,7 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
>  
>  	FDT_RO_PROBE(fdt);
>  	re = fdt_mem_rsv(fdt, n);
> -	if (!re)
> +	if (_check2() && !re)
>  		return -FDT_ERR_BADOFFSET;
>  
>  	*address = fdt64_ld(&re->address);
> @@ -288,13 +298,14 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
>  	const char *nameptr;
>  	int err;
>  
> -	if (((err = fdt_ro_probe_(fdt)) != 0)
> -	    || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0))
> -			goto fail;
> +	if (_check2() &&
> +	    (((err = fdt_ro_probe_(fdt)) != 0)
> +	     || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0)))
> +		goto fail;
>  
>  	nameptr = nh->name;
>  
> -	if (fdt_version(fdt) < 0x10) {
> +	if (_check1() && fdt_version(fdt) < 0x10) {
>  		/*
>  		 * For old FDT versions, match the naming conventions of V16:
>  		 * give only the leaf name (after all /). The actual tree
> @@ -345,7 +356,7 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
>  	int err;
>  	const struct fdt_property *prop;
>  
> -	if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) {
> +	if (_check1() && (err = fdt_check_prop_offset_(fdt, offset)) < 0) {
>  		if (lenp)
>  			*lenp = err;
>  		return NULL;
> @@ -387,7 +398,8 @@ static const struct fdt_property *fdt_get_property_namelen_(const void *fdt,
>  	     (offset = fdt_next_property_offset(fdt, offset))) {
>  		const struct fdt_property *prop;
>  
> -		if (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) {
> +		prop = fdt_get_property_by_offset_(fdt, offset, lenp);
> +		if (_check2() && !prop) {
>  			offset = -FDT_ERR_INTERNAL;
>  			break;
>  		}
> @@ -460,14 +472,19 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
>  	if (namep) {
>  		const char *name;
>  		int namelen;
> -		name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff),
> -				      &namelen);
> -		if (!name) {
> -			if (lenp)
> -				*lenp = namelen;
> -			return NULL;
> +
> +		if (_check2()) {
> +			name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff),
> +					      &namelen);
> +			if (!name) {
> +				if (lenp)
> +					*lenp = namelen;
> +				return NULL;
> +			}
> +			*namep = name;
> +		} else {
> +			*namep = fdt_string(fdt, fdt32_ld(&prop->nameoff));
>  		}
> -		*namep = name;
>  	}
>  
>  	/* Handle realignment */
> @@ -597,10 +614,12 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
>  		}
>  	}
>  
> -	if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
> -		return -FDT_ERR_BADOFFSET;
> -	else if (offset == -FDT_ERR_BADOFFSET)
> -		return -FDT_ERR_BADSTRUCTURE;
> +	if (_check2()) {
> +		if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
> +			return -FDT_ERR_BADOFFSET;
> +		else if (offset == -FDT_ERR_BADOFFSET)
> +			return -FDT_ERR_BADSTRUCTURE;
> +	}
>  
>  	return offset; /* error from fdt_next_node() */
>  }
> @@ -612,7 +631,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset)
>  
>  	err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
>  	if (err)
> -		return (err < 0) ? err : -FDT_ERR_INTERNAL;
> +		return (!_check2() || err < 0) ? err : -FDT_ERR_INTERNAL;
>  	return nodedepth;
>  }
>  
> @@ -833,6 +852,7 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
>  	return offset; /* error from fdt_next_node() */
>  }
>  
> +#if !defined(CHECK_LEVEL) || CHECK_LEVEL > 0
>  int fdt_check_full(const void *fdt, size_t bufsize)
>  {
>  	int err;
> @@ -895,3 +915,4 @@ int fdt_check_full(const void *fdt, size_t bufsize)
>  		}
>  	}
>  }
> +#endif

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux