[PATCH] firmware: tegra: bpmp: reject truncated debugfs entries

Pengpeng Hou <[email protected]>
Newsgroups org.kernel.vger.linux-tegra,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The BPMP debugfs response parser reads u32 fields and NUL-terminated
names from a size-delimited reply. seqbuf_read() currently clamps a
request to the remaining input bytes and can return success after a
short read. Consequently, a truncated u32 can be partially copied and
the directory parser can continue with an incomplete field.

seqbuf_read_str() also moves the cursor one byte beyond the current
range when no NUL terminator exists, and reports the failure only after
changing the parser state.

Make fixed-width reads fail when the full request is unavailable and
require a terminator within the current range before advancing the
cursor. Use a signed return type for the status helper so its error
contract matches its callers.

Fixes: f2381f652266 ("firmware: tegra: Add BPMP debugfs support")
Signed-off-by: Pengpeng Hou <[email protected]>
---
 drivers/firmware/tegra/bpmp-debugfs.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/tegra/bpmp-debugfs.c b/drivers/firmware/tegra/bpmp-debugfs.c
index 33c6300af964..bb2ce5be2e78 100644
--- a/drivers/firmware/tegra/bpmp-debugfs.c
+++ b/drivers/firmware/tegra/bpmp-debugfs.c
@@ -32,7 +32,7 @@ static size_t seqbuf_avail(struct seqbuf *seqbuf)
 	return seqbuf->pos < seqbuf->size ? seqbuf->size - seqbuf->pos : 0;
 }
 
-static size_t seqbuf_status(struct seqbuf *seqbuf)
+static int seqbuf_status(struct seqbuf *seqbuf)
 {
 	return seqbuf->pos <= seqbuf->size ? 0 : -EOVERFLOW;
 }
@@ -44,7 +44,9 @@ static int seqbuf_eof(struct seqbuf *seqbuf)
 
 static int seqbuf_read(struct seqbuf *seqbuf, void *buf, size_t nbyte)
 {
-	nbyte = min(nbyte, seqbuf_avail(seqbuf));
+	if (nbyte > seqbuf_avail(seqbuf))
+		return -EOVERFLOW;
+
 	memcpy(buf, seqbuf->buf + seqbuf->pos, nbyte);
 	seqbuf->pos += nbyte;
 	return seqbuf_status(seqbuf);
@@ -57,9 +59,16 @@ static int seqbuf_read_u32(struct seqbuf *seqbuf, u32 *v)
 
 static int seqbuf_read_str(struct seqbuf *seqbuf, const char **str)
 {
+	size_t avail;
+	size_t len;
+
+	avail = seqbuf_avail(seqbuf);
 	*str = seqbuf->buf + seqbuf->pos;
-	seqbuf->pos += strnlen(*str, seqbuf_avail(seqbuf));
-	seqbuf->pos++;
+	len = strnlen(*str, avail);
+	if (len == avail)
+		return -EOVERFLOW;
+
+	seqbuf->pos += len + 1;
 	return seqbuf_status(seqbuf);
 }
 
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.