[PATCH 4/5] pstore/ram: Set freed addresses to NULL

From: Kees Cook
Date: Tue Oct 11 2022 - 16:01:39 EST


For good measure, set all the freed addresses to NULL when managing
przs.

Cc: Anton Vorontsov <anton@xxxxxxxxxx>
Cc: Colin Cross <ccross@xxxxxxxxxxx>
Cc: Tony Luck <tony.luck@xxxxxxxxx>
Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx>
---
fs/pstore/ram.c | 13 ++++++++-----
fs/pstore/ram_core.c | 11 +++++++++--
fs/pstore/ram_internal.h | 2 +-
3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index f5bf360cf905..5da31565f93a 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -453,25 +453,27 @@ static void ramoops_free_przs(struct ramoops_context *cxt)
int i;

/* Free pmsg PRZ */
- persistent_ram_free(cxt->mprz);
+ persistent_ram_free(&cxt->mprz);

/* Free console PRZ */
- persistent_ram_free(cxt->cprz);
+ persistent_ram_free(&cxt->cprz);

/* Free dump PRZs */
if (cxt->dprzs) {
for (i = 0; i < cxt->max_dump_cnt; i++)
- persistent_ram_free(cxt->dprzs[i]);
+ persistent_ram_free(&cxt->dprzs[i]);

kfree(cxt->dprzs);
+ cxt->fprzs = NULL;
cxt->max_dump_cnt = 0;
}

/* Free ftrace PRZs */
if (cxt->fprzs) {
for (i = 0; i < cxt->max_ftrace_cnt; i++)
- persistent_ram_free(cxt->fprzs[i]);
+ persistent_ram_free(&cxt->fprzs[i]);
kfree(cxt->fprzs);
+ cxt->fprzs = NULL;
cxt->max_ftrace_cnt = 0;
}
}
@@ -555,9 +557,10 @@ static int ramoops_init_przs(const char *name,

while (i > 0) {
i--;
- persistent_ram_free(prz_ar[i]);
+ persistent_ram_free(&prz_ar[i]);
}
kfree(prz_ar);
+ prz_ar = NULL;
goto fail;
}
*paddr += zone_sz;
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index 9e1047f4316d..97dde525150a 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -544,8 +544,14 @@ static int persistent_ram_post_init(struct persistent_ram_zone *prz, u32 sig,
return 0;
}

-void persistent_ram_free(struct persistent_ram_zone *prz)
+void persistent_ram_free(struct persistent_ram_zone **_prz)
{
+ struct persistent_ram_zone *prz;
+
+ if (!_prz)
+ return;
+
+ prz = *_prz;
if (!prz)
return;

@@ -569,6 +575,7 @@ void persistent_ram_free(struct persistent_ram_zone *prz)
persistent_ram_free_old(prz);
kfree(prz->label);
kfree(prz);
+ *_prz = NULL;
}

struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
@@ -605,6 +612,6 @@ struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,

return prz;
err:
- persistent_ram_free(prz);
+ persistent_ram_free(&prz);
return ERR_PTR(ret);
}
diff --git a/fs/pstore/ram_internal.h b/fs/pstore/ram_internal.h
index 440ee7a35e10..5f694698351f 100644
--- a/fs/pstore/ram_internal.h
+++ b/fs/pstore/ram_internal.h
@@ -82,7 +82,7 @@ struct persistent_ram_zone {
struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
u32 sig, struct persistent_ram_ecc_info *ecc_info,
unsigned int memtype, u32 flags, char *label);
-void persistent_ram_free(struct persistent_ram_zone *prz);
+void persistent_ram_free(struct persistent_ram_zone **_prz);
void persistent_ram_zap(struct persistent_ram_zone *prz);

int persistent_ram_write(struct persistent_ram_zone *prz, const void *s,
--
2.34.1