From f20cff01e7e83ef976787bab1571568d64c0b11d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre-Cl=C3=A9ment=20Tosi?= Date: Wed, 11 Oct 2023 17:04:33 +0100 Subject: ANDROID: Revert "libfdt: Validate alias property value is a valid string." This reverts commit 9308e7f9772bd226fea9925b1fc4d53c127ed4d5. Revert the Android patch to apply the upstream fix [1] instead. [1]: https://android.googlesource.com/platform/external/dtc/+/79b9e326a162b15ca5758ee214e350f4f7c038fe Test: N/A Change-Id: I702e619c875449b5efda529d01350117a1c4a435 --- libfdt/fdt_ro.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 362cc4a..e61df25 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -10,14 +10,6 @@ #include "libfdt_internal.h" -/* Check if a buffer contains a nul-terminated string. - * Used for checking property values which should be strings. - */ -static bool is_nul_string(const char *buf, const size_t buf_len) { - return buf_len > 0 && buf[buf_len - 1] == '\0' && - strnlen(buf, buf_len) == buf_len - 1; -} - static int fdt_nodename_eq_(const void *fdt, int offset, const char *s, int len) { @@ -536,27 +528,13 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) const char *fdt_get_alias_namelen(const void *fdt, const char *name, int namelen) { - const char *prop; int aliasoffset; - int prop_len; aliasoffset = fdt_path_offset(fdt, "/aliases"); if (aliasoffset < 0) return NULL; - prop = fdt_getprop_namelen(fdt, aliasoffset, name, namelen, &prop_len); - if (prop && !can_assume(VALID_INPUT)) { - /* Validate the alias value. From the devicetree spec v0.3: - * "An alias value is a device path and is encoded as a string. - * The value representes the full path to a node, ..." - * A full path must start at the root to prevent recursion. - */ - if (prop_len == 0 || *prop != '/' || !is_nul_string(prop, prop_len)) { - prop = NULL; - } - } - - return prop; + return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL); } const char *fdt_get_alias(const void *fdt, const char *name) -- cgit v1.2.3 From 19db536250d6357c47a75f0d06f691fd025a25c8 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Thu, 9 Mar 2023 11:28:32 +0100 Subject: FROMGIT: add fdt_path_getprop_namelen() helper Add a wrapper for fdt_getprop_namelen() allowing one to specify the node by path instead of offset. Signed-off-by: Rasmus Villemoes Signed-off-by: David Gibson (cherry-picked from commit df093279282ca0cff4d20ceb3bb5857117ed4cc4 git://git.kernel.org/pub/scm/utils/dtc/dtc.git main) Test: N/A Change-Id: If9a102a622dfa726b7cb10f58c38f1b52d233be6 --- libfdt/fdt_ro.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index e61df25..31f78e2 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -525,6 +525,18 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) return fdt32_ld_(php); } +static const void *fdt_path_getprop_namelen(const void *fdt, const char *path, + const char *propname, int propnamelen, + int *lenp) +{ + int offset = fdt_path_offset(fdt, path); + + if (offset < 0) + return NULL; + + return fdt_getprop_namelen(fdt, offset, propname, propnamelen, lenp); +} + const char *fdt_get_alias_namelen(const void *fdt, const char *name, int namelen) { -- cgit v1.2.3 From 8106368cb0a70f327cb2cb411a46eb33cb4bded7 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Thu, 9 Mar 2023 11:32:39 +0100 Subject: FROMGIT: use fdt_path_getprop_namelen() in fdt_get_alias_namelen() Simplify the code by making use of the new helper. Signed-off-by: Rasmus Villemoes Signed-off-by: David Gibson (cherry-picked from commit 18f5ec12a10ec84e957222074dadf4a3e4cc8d59 git://git.kernel.org/pub/scm/utils/dtc/dtc.git main) Test: N/A Change-Id: I43c6ad22dbaa718cd77421a44d5e87d188d26ca0 --- libfdt/fdt_ro.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 31f78e2..c7fc486 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -540,13 +540,7 @@ 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) { - int aliasoffset; - - aliasoffset = fdt_path_offset(fdt, "/aliases"); - if (aliasoffset < 0) - return NULL; - - return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL); + return fdt_path_getprop_namelen(fdt, "/aliases", name, namelen, NULL); } const char *fdt_get_alias(const void *fdt, const char *name) -- cgit v1.2.3 From 9964e3b4f954968406fd49b325c4d1ae86cc6e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre-Cl=C3=A9ment=20Tosi?= Date: Tue, 10 Oct 2023 10:27:25 +0100 Subject: FROMGIT: libfdt: fdt_get_alias_namelen: Validate aliases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure that the alias found matches the device tree specification v0.4: Each property of the /aliases node defines an alias. The property name specifies the alias name. The property value specifies the full path to a node in the devicetree. This protects against a stack overflow caused by fdt_path_offset_namelen(fdt, path, namelen) calling fdt_path_offset(fdt, fdt_get_alias_namelen(fdt, path, namelen)) leading to infinite recursion on DTs with "circular" aliases. This fix was originally written by Mike McTernan for Android in [1]. [1]: https://android.googlesource.com/platform/external/dtc/+/9308e7f9772bd226fea9925b1fc4d53c127ed4d5 Signed-off-by: Pierre-Clément Tosi Acked-by: Mike McTernan Message-ID: <20231010092725.63h7c45p2fnmj577@google.com> Signed-off-by: David Gibson (cherry-picked from commit 79b9e326a162b15ca5758ee214e350f4f7c038fe git://git.kernel.org/pub/scm/utils/dtc/dtc.git main) Test: N/A Change-Id: I1e5a89039f6b70c82e17739379d97dbf130036e8 --- libfdt/fdt_ro.c | 11 ++++++++++- tests/aliases.dts | 4 ++++ tests/get_alias.c | 14 +++++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index c7fc486..f40333b 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -540,7 +540,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) && + !(alias && len > 0 && alias[len - 1] == '\0' && *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..03ed675 100644 --- a/tests/aliases.dts +++ b/tests/aliases.dts @@ -5,6 +5,10 @@ #size-cells = <0>; aliases { + empty = ""; + loop = "loop"; + nonull = [626164]; + relative = "s1/subsubnode"; s1 = &sub1; ss1 = &subsub1; sss1 = &subsubsub1; diff --git a/tests/get_alias.c b/tests/get_alias.c index fb2c38c..d2888d6 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,9 +43,14 @@ int main(int argc, char *argv[]) test_init(argc, argv); fdt = load_blob_arg(argc, argv); + check_alias(fdt, NULL, "empty"); + check_alias(fdt, NULL, "nonull"); + check_alias(fdt, NULL, "relative"); check_alias(fdt, "/subnode@1", "s1"); check_alias(fdt, "/subnode@1/subsubnode", "ss1"); check_alias(fdt, "/subnode@1/subsubnode/subsubsubnode", "sss1"); + check_alias(fdt, NULL, "loop"); // Might trigger a stack overflow + PASS(); } -- cgit v1.2.3