aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--core/nvram-format.c10
-rw-r--r--core/test/run-nvram-format.c87
-rw-r--r--include/nvram-format.h2
4 files changed, 96 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
index 6d60219..7ce2bfb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,6 +40,7 @@ core/test/run-mem_region_init
core/test/run-mem_region_release_unused
core/test/run-mem_region_release_unused_noalloc
core/test/run-msg
+core/test/run-nvram-format
core/test/run-pel
core/test/run-pool
core/test/run-trace
diff --git a/core/nvram-format.c b/core/nvram-format.c
index 3ec0db2..fc2ddef 100644
--- a/core/nvram-format.c
+++ b/core/nvram-format.c
@@ -60,7 +60,7 @@ static uint8_t chrp_nv_cksum(struct chrp_nvram_hdr *hdr)
return c_sum;
}
-void nvram_format(void *nvram_image, uint32_t nvram_size)
+int nvram_format(void *nvram_image, uint32_t nvram_size)
{
struct chrp_nvram_hdr *h;
unsigned int offset = 0;
@@ -69,6 +69,8 @@ void nvram_format(void *nvram_image, uint32_t nvram_size)
memset(nvram_image, 0, nvram_size);
/* Create private partition */
+ if (nvram_size - offset < NVRAM_SIZE_FW_PRIV)
+ return -1;
h = nvram_image + offset;
h->sig = NVRAM_SIG_FW_PRIV;
h->len = NVRAM_SIZE_FW_PRIV >> 4;
@@ -77,6 +79,8 @@ void nvram_format(void *nvram_image, uint32_t nvram_size)
offset += NVRAM_SIZE_FW_PRIV;
/* Create common partition */
+ if (nvram_size - offset < NVRAM_SIZE_COMMON)
+ return -1;
h = nvram_image + offset;
h->sig = NVRAM_SIG_SYSTEM;
h->len = NVRAM_SIZE_COMMON >> 4;
@@ -85,11 +89,15 @@ void nvram_format(void *nvram_image, uint32_t nvram_size)
offset += NVRAM_SIZE_COMMON;
/* Create free space partition */
+ if (nvram_size - offset < sizeof(struct chrp_nvram_hdr))
+ return -1;
h = nvram_image + offset;
h->sig = NVRAM_SIG_FREE;
h->len = (nvram_size - offset) >> 4;
strncpy(h->name, NVRAM_NAME_FREE, 12);
h->cksum = chrp_nv_cksum(h);
+
+ return 0;
}
/*
diff --git a/core/test/run-nvram-format.c b/core/test/run-nvram-format.c
index 7fb4217..77b759b 100644
--- a/core/test/run-nvram-format.c
+++ b/core/test/run-nvram-format.c
@@ -21,11 +21,94 @@
int main(void)
{
char *nvram_image = malloc(0x100000);
+ size_t sz;
+ struct chrp_nvram_hdr *h;
- nvram_format(nvram_image, 0x100000);
-
+ assert(nvram_format(nvram_image, 0x100000) == 0);
assert(nvram_check(nvram_image, 0x100000) == 0);
free(nvram_image);
+
+ /* 1024 bytes is too small for our NVRAM */
+ nvram_image = malloc(1024);
+ assert(nvram_format(nvram_image, 1024)!=0);
+ free(nvram_image);
+
+ /* 4096 bytes is too small for our NVRAM */
+ nvram_image = malloc(4096);
+ assert(nvram_format(nvram_image, 4096)!=0);
+ free(nvram_image);
+
+ /* 64k is too small for our NVRAM */
+ nvram_image = malloc(0x10000);
+ assert(nvram_format(nvram_image, 0x10000)!=0);
+ free(nvram_image);
+
+ /* 68k is too small for our NVRAM */
+ nvram_image = malloc(68*1024);
+ assert(nvram_format(nvram_image, 68*1024)!=0);
+ free(nvram_image);
+
+ /* 68k+16 bytes (nvram header) should generate empty free space */
+ sz = NVRAM_SIZE_COMMON + NVRAM_SIZE_FW_PRIV
+ + sizeof(struct chrp_nvram_hdr);
+ 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);
+ free(nvram_image);
+
+ /* 128k NVRAM check */
+ nvram_image = malloc(128*1024);
+ assert(nvram_format(nvram_image, 128*1024)==0);
+ assert(nvram_check(nvram_image,128*1024)==0);
+
+ /* Now, we corrupt it */
+ nvram_image[0] = 0;
+ assert(nvram_check(nvram_image,128*1024) != 0);
+
+ assert(nvram_format(nvram_image, 128*1024)==0);
+ /* corrupt the length of the partition */
+ nvram_image[2] = 0;
+ nvram_image[3] = 0;
+ assert(nvram_check(nvram_image,128*1024) != 0);
+
+ assert(nvram_format(nvram_image, 128*1024)==0);
+ /* corrupt the length of the partition */
+ nvram_image[2] = 0;
+ nvram_image[3] = 0;
+ /* but reset checksum! */
+ h = (struct chrp_nvram_hdr*)nvram_image;
+ h->cksum = chrp_nv_cksum(h);
+ assert(nvram_check(nvram_image,128*1024) != 0);
+
+ assert(nvram_format(nvram_image, 128*1024)==0);
+ /* make the length insanely beyond end of nvram */
+ nvram_image[2] = 42;
+ nvram_image[3] = 32;
+ /* but reset checksum! */
+ h = (struct chrp_nvram_hdr*)nvram_image;
+ h->cksum = chrp_nv_cksum(h);
+ assert(nvram_check(nvram_image,128*1024) != 0);
+
+ assert(nvram_format(nvram_image, 128*1024)==0);
+ /* remove skiboot partition */
+ nvram_image[12] = '\0';
+ /* but reset checksum! */
+ h = (struct chrp_nvram_hdr*)nvram_image;
+ h->cksum = chrp_nv_cksum(h);
+ assert(nvram_check(nvram_image,128*1024) != 0);
+
+ assert(nvram_format(nvram_image, 128*1024)==0);
+ /* remove common partition */
+ nvram_image[NVRAM_SIZE_FW_PRIV+5] = '\0';
+ /* but reset checksum! */
+ h = (struct chrp_nvram_hdr*)(&nvram_image[NVRAM_SIZE_FW_PRIV]);
+ h->cksum = chrp_nv_cksum(h);
+ assert(nvram_check(nvram_image,128*1024) != 0);
+
+ free(nvram_image);
+
return 0;
}
diff --git a/include/nvram-format.h b/include/nvram-format.h
index 693f0bd..d7432a7 100644
--- a/include/nvram-format.h
+++ b/include/nvram-format.h
@@ -17,7 +17,7 @@
#ifndef __NVRAM_FORMAT_H
#define __NVRAM_FORMAT_H
-void nvram_format(void *nvram_image, uint32_t nvram_size);
+int nvram_format(void *nvram_image, uint32_t nvram_size);
int nvram_check(void *nvram_image, uint32_t nvram_size);
#endif /* __NVRAM_FORMAT_H */