On Sat, 7 Oct 2023 at 12:07, Pierre-Clément Tosi <ptosi@xxxxxxxxxx> wrote: > > Ensure that the alias found is valid i.e. > > An alias value is a device path and is encoded as a string. > The value represents the full path to a node, ... > > This protects against a stack overflow (fdt_path_offset_namelen() calls > fdt_get_alias_namelen() then fdt_path_offset(alias), ...) when /aliases > has an empty property with an empty name. > > Co-developed-by: Mike McTernan <mikemcternan@xxxxxxxxxx> > Signed-off-by: Pierre-Clément Tosi <ptosi@xxxxxxxxxx> Acked-by: Mike McTernan <mikemcternan@xxxxxxxxxx> > --- > libfdt/fdt_ro.c | 11 ++++++++++- > tests/aliases.dts | 3 +++ > tests/get_alias.c | 12 +++++++++++- > 3 files changed, 24 insertions(+), 2 deletions(-) > > diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c > index c4c520c..bda5c0d 100644 > --- a/libfdt/fdt_ro.c > +++ b/libfdt/fdt_ro.c > @@ -537,7 +537,16 @@ static const void *fdt_path_getprop_namelen(const void *fdt, const char *path, > const char *fdt_get_alias_namelen(const void *fdt, > const char *name, int namelen) > { > - return fdt_path_getprop_namelen(fdt, "/aliases", name, namelen, NULL); > + int len; > + const char *alias; > + > + alias = fdt_path_getprop_namelen(fdt, "/aliases", name, namelen, &len); > + > + if (!can_assume(VALID_DTB) && > + !(len > 0 && alias && memchr(alias, '\0', len) && *alias == '/')) > + return NULL; > + > + return alias; > } > > const char *fdt_get_alias(const void *fdt, const char *name) > diff --git a/tests/aliases.dts b/tests/aliases.dts > index 853479a..8820974 100644 > --- a/tests/aliases.dts > +++ b/tests/aliases.dts > @@ -8,6 +8,9 @@ > s1 = &sub1; > ss1 = &subsub1; > sss1 = &subsubsub1; > + badpath = "wrong"; > + badpathlong = "wrong/with/parts"; > + empty = ""; > }; > > sub1: subnode@1 { > diff --git a/tests/get_alias.c b/tests/get_alias.c > index fb2c38c..4f3f6fd 100644 > --- a/tests/get_alias.c > +++ b/tests/get_alias.c > @@ -21,9 +21,16 @@ static void check_alias(void *fdt, const char *path, const char *alias) > > aliaspath = fdt_get_alias(fdt, alias); > > - if (path && !aliaspath) > + if (!path && !aliaspath) > + return; > + > + if (!aliaspath) > FAIL("fdt_get_alias(%s) failed\n", alias); > > + if (!path) > + FAIL("fdt_get_alias(%s) returned %s instead of NULL", > + alias, aliaspath); > + > if (strcmp(aliaspath, path) != 0) > FAIL("fdt_get_alias(%s) returned %s instead of %s\n", > alias, aliaspath, path); > @@ -36,6 +43,9 @@ int main(int argc, char *argv[]) > test_init(argc, argv); > fdt = load_blob_arg(argc, argv); > > + check_alias(fdt, NULL, "badpath"); > + check_alias(fdt, NULL, "badpathlong"); > + check_alias(fdt, NULL, "empty"); > check_alias(fdt, "/subnode@1", "s1"); > check_alias(fdt, "/subnode@1/subsubnode", "ss1"); > check_alias(fdt, "/subnode@1/subsubnode/subsubsubnode", "sss1"); > -- > 2.42.0.609.gbb76f46606-goog > > > -- > Pierre