|
@@ -33,17 +33,26 @@ static int fdt_nodename_eq_(const void *fdt, int offset,
|
|
|
|
|
|
const char *fdt_get_string(const void *fdt, int stroffset, int *lenp)
|
|
|
{
|
|
|
- int32_t totalsize = fdt_ro_probe_(fdt);
|
|
|
- uint32_t absoffset = stroffset + fdt_off_dt_strings(fdt);
|
|
|
+ int32_t totalsize;
|
|
|
+ uint32_t absoffset;
|
|
|
size_t len;
|
|
|
int err;
|
|
|
const char *s, *n;
|
|
|
|
|
|
+ if (can_assume(VALID_INPUT)) {
|
|
|
+ s = (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
|
|
|
+
|
|
|
+ if (lenp)
|
|
|
+ *lenp = strlen(s);
|
|
|
+ return s;
|
|
|
+ }
|
|
|
+ totalsize = fdt_ro_probe_(fdt);
|
|
|
err = totalsize;
|
|
|
if (totalsize < 0)
|
|
|
goto fail;
|
|
|
|
|
|
err = -FDT_ERR_BADOFFSET;
|
|
|
+ absoffset = stroffset + fdt_off_dt_strings(fdt);
|
|
|
if (absoffset >= totalsize)
|
|
|
goto fail;
|
|
|
len = totalsize - absoffset;
|
|
@@ -51,7 +60,7 @@ const char *fdt_get_string(const void *fdt, int stroffset, int *lenp)
|
|
|
if (fdt_magic(fdt) == FDT_MAGIC) {
|
|
|
if (stroffset < 0)
|
|
|
goto fail;
|
|
|
- if (fdt_version(fdt) >= 17) {
|
|
|
+ if (can_assume(LATEST) || fdt_version(fdt) >= 17) {
|
|
|
if (stroffset >= fdt_size_dt_strings(fdt))
|
|
|
goto fail;
|
|
|
if ((fdt_size_dt_strings(fdt) - stroffset) < len)
|
|
@@ -151,10 +160,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 (!can_assume(VALID_INPUT)) {
|
|
|
+ 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);
|
|
|
}
|
|
|
|
|
@@ -164,7 +176,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 (!can_assume(VALID_INPUT) && !re)
|
|
|
return -FDT_ERR_BADOFFSET;
|
|
|
|
|
|
*address = fdt64_ld(&re->address);
|
|
@@ -295,7 +307,7 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
|
|
|
|
|
|
nameptr = nh->name;
|
|
|
|
|
|
- if (fdt_version(fdt) < 0x10) {
|
|
|
+ if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
|
|
|
/*
|
|
|
* For old FDT versions, match the naming conventions of V16:
|
|
|
* give only the leaf name (after all /). The actual tree
|
|
@@ -346,7 +358,8 @@ 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 (!can_assume(VALID_INPUT) &&
|
|
|
+ (err = fdt_check_prop_offset_(fdt, offset)) < 0) {
|
|
|
if (lenp)
|
|
|
*lenp = err;
|
|
|
return NULL;
|
|
@@ -367,7 +380,7 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
|
|
|
/* Prior to version 16, properties may need realignment
|
|
|
* and this API does not work. fdt_getprop_*() will, however. */
|
|
|
|
|
|
- if (fdt_version(fdt) < 0x10) {
|
|
|
+ if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
|
|
|
if (lenp)
|
|
|
*lenp = -FDT_ERR_BADVERSION;
|
|
|
return NULL;
|
|
@@ -388,7 +401,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 (!can_assume(LIBFDT_FLAWLESS) && !prop) {
|
|
|
offset = -FDT_ERR_INTERNAL;
|
|
|
break;
|
|
|
}
|
|
@@ -413,7 +427,7 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt,
|
|
|
{
|
|
|
/* Prior to version 16, properties may need realignment
|
|
|
* and this API does not work. fdt_getprop_*() will, however. */
|
|
|
- if (fdt_version(fdt) < 0x10) {
|
|
|
+ if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
|
|
|
if (lenp)
|
|
|
*lenp = -FDT_ERR_BADVERSION;
|
|
|
return NULL;
|
|
@@ -444,8 +458,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
|
|
|
return NULL;
|
|
|
|
|
|
/* Handle realignment */
|
|
|
- if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 &&
|
|
|
- fdt32_ld(&prop->len) >= 8)
|
|
|
+ if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 &&
|
|
|
+ (poffset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8)
|
|
|
return prop->data + 4;
|
|
|
return prop->data;
|
|
|
}
|
|
@@ -461,19 +475,24 @@ 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 (!can_assume(VALID_INPUT)) {
|
|
|
+ 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 */
|
|
|
- if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 &&
|
|
|
- fdt32_ld(&prop->len) >= 8)
|
|
|
+ if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 &&
|
|
|
+ (offset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8)
|
|
|
return prop->data + 4;
|
|
|
return prop->data;
|
|
|
}
|
|
@@ -598,10 +617,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 (!can_assume(VALID_INPUT)) {
|
|
|
+ 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() */
|
|
|
}
|
|
@@ -613,7 +634,8 @@ 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 (can_assume(LIBFDT_FLAWLESS) || err < 0) ? err :
|
|
|
+ -FDT_ERR_INTERNAL;
|
|
|
return nodedepth;
|
|
|
}
|
|
|
|
|
@@ -833,66 +855,3 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
|
|
|
|
|
|
return offset; /* error from fdt_next_node() */
|
|
|
}
|
|
|
-
|
|
|
-int fdt_check_full(const void *fdt, size_t bufsize)
|
|
|
-{
|
|
|
- int err;
|
|
|
- int num_memrsv;
|
|
|
- int offset, nextoffset = 0;
|
|
|
- uint32_t tag;
|
|
|
- unsigned depth = 0;
|
|
|
- const void *prop;
|
|
|
- const char *propname;
|
|
|
-
|
|
|
- if (bufsize < FDT_V1_SIZE)
|
|
|
- return -FDT_ERR_TRUNCATED;
|
|
|
- err = fdt_check_header(fdt);
|
|
|
- if (err != 0)
|
|
|
- return err;
|
|
|
- if (bufsize < fdt_totalsize(fdt))
|
|
|
- return -FDT_ERR_TRUNCATED;
|
|
|
-
|
|
|
- num_memrsv = fdt_num_mem_rsv(fdt);
|
|
|
- if (num_memrsv < 0)
|
|
|
- return num_memrsv;
|
|
|
-
|
|
|
- while (1) {
|
|
|
- offset = nextoffset;
|
|
|
- tag = fdt_next_tag(fdt, offset, &nextoffset);
|
|
|
-
|
|
|
- if (nextoffset < 0)
|
|
|
- return nextoffset;
|
|
|
-
|
|
|
- switch (tag) {
|
|
|
- case FDT_NOP:
|
|
|
- break;
|
|
|
-
|
|
|
- case FDT_END:
|
|
|
- if (depth != 0)
|
|
|
- return -FDT_ERR_BADSTRUCTURE;
|
|
|
- return 0;
|
|
|
-
|
|
|
- case FDT_BEGIN_NODE:
|
|
|
- depth++;
|
|
|
- if (depth > INT_MAX)
|
|
|
- return -FDT_ERR_BADSTRUCTURE;
|
|
|
- break;
|
|
|
-
|
|
|
- case FDT_END_NODE:
|
|
|
- if (depth == 0)
|
|
|
- return -FDT_ERR_BADSTRUCTURE;
|
|
|
- depth--;
|
|
|
- break;
|
|
|
-
|
|
|
- case FDT_PROP:
|
|
|
- prop = fdt_getprop_by_offset(fdt, offset, &propname,
|
|
|
- &err);
|
|
|
- if (!prop)
|
|
|
- return err;
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- return -FDT_ERR_INTERNAL;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|