From nobody Wed Feb 11 01:25:55 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AE07438B7CA; Tue, 10 Feb 2026 17:34:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744871; cv=none; b=al7B1AhoW8pUGCgaW4EIQV5yhwKNl1FbolKBFaUS9Qoll/s1hVOvela6KAUKvUQSSsZm3BetASEQBN2INCM86srTlJvy25CrQRCtO6KyGUdn4sD7/IKIltiD/JkRCPdj2SdUbgh7yAfpQev463qaGwtWqdpSfQZnAGDiqWVoOHQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770744871; c=relaxed/simple; bh=Z/oydfpGOCxdFGc372aiXq83qdbcRaqJqG51xjNfBrI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pifzUA15m7FQaoOqGzoOAqG4H14ILzjZFQooXw9YFtd/HXO5rSP52spn9LDn0XHv3Xc59QZ9DJA2gsFrpBEuupabDdxXkIyz/SLbETExaE3ziA8SkPrwRZgOZgYADlRy3ZrAP1VyrqsiSQSKl/OO/gJ7MBXVQLk+vUVMBQWFb3g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=N5sRmW2h; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="N5sRmW2h" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 65BF54E40C0D; Tue, 10 Feb 2026 17:34:29 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 3BE8B606BD; Tue, 10 Feb 2026 17:34:29 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 5FF9110B92228; Tue, 10 Feb 2026 18:34:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1770744868; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=lfBZyaOnQKahul2oKqZRv4nz6l5s4zrM0dhVGQ0T4Ak=; b=N5sRmW2hTPH7fhqm581SWeOx+3u7OTlL6VWaYvZ3Fvb2WCDzZAhpnr+9d58vItsBnolJAd r267RfSI27SHVweFqiiofw2+c9Taer9MQ4Zmaomj9CVSL5K2iLkkpAn3G1rULTexeO6+fK xD0PO/jUdP3HswSJaaNgcHfIgvPn6p1BkIIh6ePALVL5OqhxwRDszrB8iIb/LJmGgx3OYX xMPEnnWQtCIWxhmDV5br8wq7q6Kd+tAetPpx0RvdYgsW/SVq6nGPWqDPWCsvWRoNzJZSbY ctvmcfIUPDQlcv3CMqGFStmC2LnIQB6yxtF4mV5/RhMv3al2/LH/XX+7bxG3MA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH 06/15] libfdt: Don't assume that a FDT_BEGIN_NODE tag is available at offset 0 Date: Tue, 10 Feb 2026 18:33:34 +0100 Message-ID: <20260210173349.636766-7-herve.codina@bootlin.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260210173349.636766-1-herve.codina@bootlin.com> References: <20260210173349.636766-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" In several places, libfdt assumes that a FDT_BEGIN_NODE tag is present at the offset 0 of the structure block. This assumption is not correct. Indeed, a FDT_NOP can be present at the offset 0 and this is a legit case. fdt_first_node() has been introduce recently to get the offset of the first node (first FDT_BEGIN_NODE) in a fdt blob. Use this function to get the first node offset instead of looking for this node at offset 0. Signed-off-by: Herve Codina --- libfdt/fdt.c | 10 ++++++++-- libfdt/fdt_ro.c | 16 +++++++++++++--- libfdt/fdt_rw.c | 6 ++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 676c7d7..ff2fa6c 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -279,11 +279,17 @@ int fdt_first_node(const void *fdt) =20 int fdt_next_node(const void *fdt, int offset, int *depth) { - int nextoffset =3D 0; + int nextoffset =3D offset; uint32_t tag; =20 + if (offset <=3D 0) { + nextoffset =3D fdt_first_node(fdt); + if (nextoffset < 0) + return nextoffset; + } + if (offset >=3D 0) - if ((nextoffset =3D fdt_check_node_offset_(fdt, offset)) < 0) + if ((nextoffset =3D fdt_check_node_offset_(fdt, nextoffset)) < 0) return nextoffset; =20 do { diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 63494fb..8e1db7d 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -229,6 +229,12 @@ int fdt_subnode_offset_namelen(const void *fdt, int of= fset, =20 FDT_RO_PROBE(fdt); =20 + if (!offset) { + offset =3D fdt_first_node(fdt); + if (offset < 0) + return offset; + } + for (depth =3D 0; (offset >=3D 0) && (depth >=3D 0); offset =3D fdt_next_node(fdt, offset, &depth)) @@ -251,13 +257,17 @@ int fdt_path_offset_namelen(const void *fdt, const ch= ar *path, int namelen) { const char *end =3D path + namelen; const char *p =3D path; - int offset =3D 0; + int offset; =20 FDT_RO_PROBE(fdt); =20 if (!can_assume(VALID_INPUT) && namelen <=3D 0) return -FDT_ERR_BADPATH; =20 + offset =3D fdt_first_node(fdt); + if (offset < 0) + return offset; + /* see if we have an alias */ if (*path !=3D '/') { const char *q =3D memchr(path, '/', end - p); @@ -579,7 +589,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char = *buf, int buflen) if (buflen < 2) return -FDT_ERR_NOSPACE; =20 - for (offset =3D 0, depth =3D 0; + for (offset =3D fdt_first_node(fdt), depth =3D 0; (offset >=3D 0) && (offset <=3D nodeoffset); offset =3D fdt_next_node(fdt, offset, &depth)) { while (pdepth > depth) { @@ -617,7 +627,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char = *buf, int buflen) else if (offset =3D=3D -FDT_ERR_BADOFFSET) return -FDT_ERR_BADSTRUCTURE; =20 - return offset; /* error from fdt_next_node() */ + return offset; /* error from fdt_next_node() or fdt_first_node() */ } =20 int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c index 90ea14e..f5c28fc 100644 --- a/libfdt/fdt_rw.c +++ b/libfdt/fdt_rw.c @@ -354,6 +354,12 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffse= t, =20 FDT_RW_PROBE(fdt); =20 + if (!parentoffset) { + parentoffset =3D fdt_first_node(fdt); + if (parentoffset < 0) + return parentoffset; + } + offset =3D fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); if (offset >=3D 0) return -FDT_ERR_EXISTS; --=20 2.52.0