diff mbox series

nvram: Improve partition validation

Message ID 20260826181657.184870-1-arbab@linux.ibm.com
State New
Headers show
Series nvram: Improve partition validation | expand

Commit Message

Reza Arbab Aug. 26, 2026, 6:16 p.m. UTC
Add checks for incorrectly sized sections in a NVRAM partition.

Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
---
 core/nvram-format.c | 34 +++++++++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/core/nvram-format.c b/core/nvram-format.c
index 8aa5abf22..e4197fc28 100644
--- a/core/nvram-format.c
+++ b/core/nvram-format.c
@@ -2,7 +2,7 @@ 
 /*
  * NVRAM Format as specified in PAPR
  *
- * Copyright 2013-2019 IBM Corp.
+ * Copyright 2013-2026 IBM Corp.
  */
 
 #include <skiboot.h>
@@ -121,9 +121,13 @@  int nvram_check(void *nvram_image, const uint32_t nvram_size)
 				offset, h->cksum, chrp_nv_cksum(h));
 			goto failed;
 		}
-		if (be16_to_cpu(h->len) < 1) {
-			prerror("NVRAM: Partition at offset 0x%x"
-				" has incorrect 0 length\n", offset);
+		/*
+		 * Length can't be zero or 1; need a length of at least 2 to account
+		 * for the size of the chrp_nvram_hdr itself
+		 */
+		if (be16_to_cpu(h->len) < 2) {
+			prerror("NVRAM: Partition at offset 0x%x has incorrect length of 0x%x\n",
+				offset, be16_to_cpu(h->len));
 			goto failed;
 		}
 
@@ -211,6 +215,8 @@  static void nvram_dangerous(const char *key)
  * nvram_query_safe/dangerous() - Searches skiboot NVRAM partition
  * for a key=value pair.
  *
+ * Note: nvram_check() must have already been called to set skiboot_part_hdr
+ *
  * Dangerous means it should only be used for testing as it may
  * mask issues. Safe is ok for long term use.
  *
@@ -245,12 +251,27 @@  static const char *__nvram_query(const char *key, bool dangerous)
 
 	assert(skiboot_part_hdr);
 
+	/*
+	 * The end of the skiboot section is from the start of the section
+	 * to len * 16 - 1
+	 */
 	part_end = (const char *) skiboot_part_hdr
 		+ be16_to_cpu(skiboot_part_hdr->len) * 16 - 1;
 
+	/* Start just past the header */
 	start = (const char *) skiboot_part_hdr
 		+ sizeof(*skiboot_part_hdr);
 
+	/*
+	 * To account for sizeof(*skiboot_part_hdr), the len must be at least 2 to
+	 * put part_end after start
+	 */
+	if ((be16_to_cpu(skiboot_part_hdr->len) < 2) || (start > part_end)) {
+		prlog(PR_WARNING, "NVRAM: skiboot section length 0x%x is too small\n",
+		      be16_to_cpu(skiboot_part_hdr->len));
+		return NULL;
+	}
+
 	if (!key_len) {
 		prlog(PR_WARNING, "NVRAM: search key is empty!\n");
 		return NULL;
@@ -262,12 +283,11 @@  static const char *__nvram_query(const char *key, bool dangerous)
 	while (start) {
 		int remaining = part_end - start;
 
-		prlog(PR_TRACE, "NVRAM: '%s' (%lu)\n",
-			start, strlen(start));
-
 		if (key_len + 1 > remaining)
 			return NULL;
 
+		prlog(PR_TRACE, "NVRAM: '%s' (%lu)\n", start, strlen(start));
+
 		if (!strncmp(key, start, key_len) && start[key_len] == '=') {
 			const char *value = &start[key_len + 1];