Skip to content

Commit

Permalink
libfdt: Add support for disabling dtb checks
Browse files Browse the repository at this point in the history
Support ASSUME_VALID_DTB to disable some sanity checks

If we assume that the DTB itself is valid then we can skip some checks and
save code space. Add various conditions to handle this.

Signed-off-by: Simon Glass <sjg@chromium.org>
Message-Id: <20200220214557.176528-4-sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
  • Loading branch information
sjg20 authored and dgibson committed Feb 24, 2020
1 parent 4649624 commit 57bc632
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 29 deletions.
53 changes: 31 additions & 22 deletions libfdt/fdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ int32_t fdt_ro_probe_(const void *fdt)
{
uint32_t totalsize = fdt_totalsize(fdt);

if (can_assume(VALID_DTB))
return totalsize;

if (fdt_magic(fdt) == FDT_MAGIC) {
/* Complete tree */
if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
Expand Down Expand Up @@ -81,38 +84,44 @@ int fdt_check_header(const void *fdt)

if (fdt_magic(fdt) != FDT_MAGIC)
return -FDT_ERR_BADMAGIC;
hdrsize = fdt_header_size(fdt);
if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
|| (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION))
return -FDT_ERR_BADVERSION;
if (fdt_version(fdt) < fdt_last_comp_version(fdt))
return -FDT_ERR_BADVERSION;
hdrsize = fdt_header_size(fdt);
if (!can_assume(VALID_DTB)) {

if ((fdt_totalsize(fdt) < hdrsize)
|| (fdt_totalsize(fdt) > INT_MAX))
return -FDT_ERR_TRUNCATED;

/* Bounds check memrsv block */
if (!check_off_(hdrsize, fdt_totalsize(fdt), fdt_off_mem_rsvmap(fdt)))
return -FDT_ERR_TRUNCATED;
if ((fdt_totalsize(fdt) < hdrsize)
|| (fdt_totalsize(fdt) > INT_MAX))
return -FDT_ERR_TRUNCATED;

/* Bounds check structure block */
if (fdt_version(fdt) < 17) {
/* Bounds check memrsv block */
if (!check_off_(hdrsize, fdt_totalsize(fdt),
fdt_off_dt_struct(fdt)))
fdt_off_mem_rsvmap(fdt)))
return -FDT_ERR_TRUNCATED;
} else {
}

if (!can_assume(VALID_DTB)) {
/* Bounds check structure block */
if (fdt_version(fdt) < 17) {
if (!check_off_(hdrsize, fdt_totalsize(fdt),
fdt_off_dt_struct(fdt)))
return -FDT_ERR_TRUNCATED;
} else {
if (!check_block_(hdrsize, fdt_totalsize(fdt),
fdt_off_dt_struct(fdt),
fdt_size_dt_struct(fdt)))
return -FDT_ERR_TRUNCATED;
}

/* Bounds check strings block */
if (!check_block_(hdrsize, fdt_totalsize(fdt),
fdt_off_dt_struct(fdt),
fdt_size_dt_struct(fdt)))
fdt_off_dt_strings(fdt),
fdt_size_dt_strings(fdt)))
return -FDT_ERR_TRUNCATED;
}

/* Bounds check strings block */
if (!check_block_(hdrsize, fdt_totalsize(fdt),
fdt_off_dt_strings(fdt), fdt_size_dt_strings(fdt)))
return -FDT_ERR_TRUNCATED;

return 0;
}

Expand Down Expand Up @@ -142,7 +151,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)

*nextoffset = -FDT_ERR_TRUNCATED;
tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
if (!tagp)
if (!can_assume(VALID_DTB) && !tagp)
return FDT_END; /* premature end */
tag = fdt32_to_cpu(*tagp);
offset += FDT_TAGSIZE;
Expand All @@ -154,13 +163,13 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
do {
p = fdt_offset_ptr(fdt, offset++, 1);
} while (p && (*p != '\0'));
if (!p)
if (!can_assume(VALID_DTB) && !p)
return FDT_END; /* premature end */
break;

case FDT_PROP:
lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
if (!lenp)
if (!can_assume(VALID_DTB) && !lenp)
return FDT_END; /* premature end */
/* skip-name offset, length and value */
offset += sizeof(struct fdt_property) - FDT_TAGSIZE
Expand Down
3 changes: 2 additions & 1 deletion libfdt/fdt_ro.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,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(VALID_DTB) && !prop) {
offset = -FDT_ERR_INTERNAL;
break;
}
Expand Down
2 changes: 2 additions & 0 deletions libfdt/fdt_rw.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ static int fdt_blocks_misordered_(const void *fdt,

static int fdt_rw_probe_(void *fdt)
{
if (can_assume(VALID_DTB))
return 0;
FDT_RO_PROBE(fdt);

if (fdt_version(fdt) < 17)
Expand Down
16 changes: 10 additions & 6 deletions libfdt/fdt_sw.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@

static int fdt_sw_probe_(void *fdt)
{
if (fdt_magic(fdt) == FDT_MAGIC)
return -FDT_ERR_BADSTATE;
else if (fdt_magic(fdt) != FDT_SW_MAGIC)
return -FDT_ERR_BADMAGIC;
if (!can_assume(VALID_DTB)) {
if (fdt_magic(fdt) == FDT_MAGIC)
return -FDT_ERR_BADSTATE;
else if (fdt_magic(fdt) != FDT_SW_MAGIC)
return -FDT_ERR_BADMAGIC;
}

return 0;
}

Expand All @@ -38,7 +41,7 @@ static int fdt_sw_probe_memrsv_(void *fdt)
if (err)
return err;

if (fdt_off_dt_strings(fdt) != 0)
if (!can_assume(VALID_DTB) && fdt_off_dt_strings(fdt) != 0)
return -FDT_ERR_BADSTATE;
return 0;
}
Expand Down Expand Up @@ -151,7 +154,8 @@ int fdt_resize(void *fdt, void *buf, int bufsize)
headsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
tailsize = fdt_size_dt_strings(fdt);

if ((headsize + tailsize) > fdt_totalsize(fdt))
if (!can_assume(VALID_DTB) &&
headsize + tailsize > fdt_totalsize(fdt))
return -FDT_ERR_INTERNAL;

if ((headsize + tailsize) > bufsize)
Expand Down

0 comments on commit 57bc632

Please sign in to comment.