diff mbox

nvram-format: Fix endian issues

Message ID 1484013706-26188-1-git-send-email-stewart@linux.vnet.ibm.com
State Accepted
Headers show

Commit Message

Stewart Smith Jan. 10, 2017, 2:01 a.m. UTC
NVRAM formats are always BE, so let's use the sparse annotation to catch
any issues (and correct said issues).

On LE platforms, the test was erroneously passing as with building the
nvram-format code on LE we were produces an incorrect NVRAM image.

Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
---
 core/nvram-format.c          | 35 ++++++++++++++++++++---------------
 core/test/run-nvram-format.c |  6 +++---
 2 files changed, 23 insertions(+), 18 deletions(-)

Comments

Stewart Smith Feb. 23, 2017, 2:18 a.m. UTC | #1
Stewart Smith <stewart@linux.vnet.ibm.com> writes:
> NVRAM formats are always BE, so let's use the sparse annotation to catch
> any issues (and correct said issues).
>
> On LE platforms, the test was erroneously passing as with building the
> nvram-format code on LE we were produces an incorrect NVRAM image.
>
> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
> ---
>  core/nvram-format.c          | 35 ++++++++++++++++++++---------------
>  core/test/run-nvram-format.c |  6 +++---
>  2 files changed, 23 insertions(+), 18 deletions(-)

Merged to master as of 5bcb6c4ac405ab7dd5227069b5c2e686d5d087eb
diff mbox

Patch

diff --git a/core/nvram-format.c b/core/nvram-format.c
index 5c7c9fe35b06..84407fc1af71 100644
--- a/core/nvram-format.c
+++ b/core/nvram-format.c
@@ -1,4 +1,4 @@ 
-/* Copyright 2013-2014 IBM Corp.
+/* Copyright 2013-2017 IBM Corp.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ 
 struct chrp_nvram_hdr {
 	uint8_t		sig;
 	uint8_t		cksum;
-	uint16_t	len;
+	be16		len;
 	char		name[12];
 };
 
@@ -75,11 +75,13 @@  int nvram_format(void *nvram_image, uint32_t nvram_size)
 		return -1;
 	h = nvram_image + offset;
 	h->sig = NVRAM_SIG_FW_PRIV;
-	h->len = NVRAM_SIZE_FW_PRIV >> 4;
+	h->len = cpu_to_be16(NVRAM_SIZE_FW_PRIV >> 4);
 	strcpy(h->name, NVRAM_NAME_FW_PRIV);
 	h->cksum = chrp_nv_cksum(h);
-	prlog(PR_DEBUG, "NVRAM: Created '%s' partition at 0x%08x for size 0x%08x"
-			" with cksum 0x%02x\n", NVRAM_NAME_FW_PRIV, offset, h->len, h->cksum);
+	prlog(PR_DEBUG, "NVRAM: Created '%s' partition at 0x%08x"
+	      " for size 0x%08x with cksum 0x%02x\n",
+	      NVRAM_NAME_FW_PRIV, offset,
+	      be16_to_cpu(h->len), h->cksum);
 	offset += NVRAM_SIZE_FW_PRIV;
 
 	/* Create common partition */
@@ -87,11 +89,13 @@  int nvram_format(void *nvram_image, uint32_t nvram_size)
 		return -1;
 	h = nvram_image + offset;
 	h->sig = NVRAM_SIG_SYSTEM;
-	h->len = NVRAM_SIZE_COMMON >> 4;
+	h->len = cpu_to_be16(NVRAM_SIZE_COMMON >> 4);
 	strcpy(h->name, NVRAM_NAME_COMMON);
 	h->cksum = chrp_nv_cksum(h);
-	prlog(PR_DEBUG, "NVRAM: Created '%s' partition at 0x%08x for size 0x%08x"
-			" with cksum 0x%02x\n", NVRAM_NAME_COMMON, offset, h->len, h->cksum);
+	prlog(PR_DEBUG, "NVRAM: Created '%s' partition at 0x%08x"
+	      " for size 0x%08x with cksum 0x%02x\n",
+	      NVRAM_NAME_COMMON, offset,
+	      be16_to_cpu(h->len), h->cksum);
 	offset += NVRAM_SIZE_COMMON;
 
 	/* Create free space partition */
@@ -99,12 +103,13 @@  int nvram_format(void *nvram_image, uint32_t nvram_size)
 		return -1;
 	h = nvram_image + offset;
 	h->sig = NVRAM_SIG_FREE;
-	h->len = (nvram_size - offset) >> 4;
+	h->len = cpu_to_be16((nvram_size - offset) >> 4);
 	/* We have the full 12 bytes here */
 	memcpy(h->name, NVRAM_NAME_FREE, 12);
 	h->cksum = chrp_nv_cksum(h);
-	prlog(PR_DEBUG, "NVRAM: Created '%s' partition at 0x%08x for size 0x%08x"
-			" with cksum 0x%02x\n", NVRAM_NAME_FREE, offset, h->len, h->cksum);
+	prlog(PR_DEBUG, "NVRAM: Created '%s' partition at 0x%08x"
+	      " for size 0x%08x with cksum 0x%02x\n",
+	      NVRAM_NAME_FREE, offset, be16_to_cpu(h->len), h->cksum);
 	return 0;
 }
 
@@ -129,7 +134,7 @@  int nvram_check(void *nvram_image, const uint32_t nvram_size)
 				offset, h->cksum, chrp_nv_cksum(h));
 			goto failed;
 		}
-		if (h->len < 1) {
+		if (be16_to_cpu(h->len) < 1) {
 			prerror("NVRAM: Partition at offset 0x%x"
 				" has incorrect 0 length\n", offset);
 			goto failed;
@@ -143,7 +148,7 @@  int nvram_check(void *nvram_image, const uint32_t nvram_size)
 		    strcmp(h->name, NVRAM_NAME_FW_PRIV) == 0)
 			skiboot_part_hdr = h;
 
-		offset += h->len << 4;
+		offset += be16_to_cpu(h->len) << 4;
 		if (offset > nvram_size) {
 			prerror("NVRAM: Partition at offset 0x%x"
 				" extends beyond end of nvram !\n", offset);
@@ -166,7 +171,7 @@  int nvram_check(void *nvram_image, const uint32_t nvram_size)
 		 * always check.
 		 */
 		const char *last_byte = (const char *) skiboot_part_hdr +
-			skiboot_part_hdr->len * 16 - 1;
+			be16_to_cpu(skiboot_part_hdr->len) * 16 - 1;
 
 		if (*last_byte != 0) {
 			prerror("NVRAM: Skiboot private partition is not NUL terminated");
@@ -224,7 +229,7 @@  const char *nvram_query(const char *key)
 	}
 
 	part_end = (const char *) skiboot_part_hdr
-		+ skiboot_part_hdr->len * 16 - 1;
+		+ be16_to_cpu(skiboot_part_hdr->len) * 16 - 1;
 
 	start = (const char *) skiboot_part_hdr
 		+ sizeof(*skiboot_part_hdr);
diff --git a/core/test/run-nvram-format.c b/core/test/run-nvram-format.c
index 4ca2cded2a60..5bd8ea2ae6ec 100644
--- a/core/test/run-nvram-format.c
+++ b/core/test/run-nvram-format.c
@@ -69,8 +69,8 @@  int main(void)
 	nvram_image = malloc(sz);
 	assert(nvram_format(nvram_image, sz)==0);
 	assert(nvram_check(nvram_image, sz)==0);
-	assert(nvram_image[sz-13]==0);
-	assert(nvram_image[sz-14]==1);
+	assert(nvram_image[sz-14]==0);
+	assert(nvram_image[sz-13]==1);
 	h = (struct chrp_nvram_hdr*)(&nvram_image[NVRAM_SIZE_COMMON + NVRAM_SIZE_FW_PRIV]);
 	assert(memcmp(h->name, "wwwwwwwwwwww", 12)==0);
 	free(nvram_image);
@@ -87,7 +87,7 @@  int main(void)
 	/* Does our NUL checking work? */
 	assert(nvram_format(nvram_image, 128 * 1024) == 0);
 	h = (struct chrp_nvram_hdr *) nvram_image;
-	memset((char *) h + sizeof(*h), 0xFF, h->len * 16 - sizeof(*h));
+	memset((char *) h + sizeof(*h), 0xFF, be16_to_cpu(h->len) * 16 - sizeof(*h));
 	assert(nvram_check(nvram_image, 128 * 1024) != 0);
 
 	assert(nvram_format(nvram_image, 128*1024)==0);