Skip to content

Commit

Permalink
pstore/ram: Regularize prz label allocation lifetime
Browse files Browse the repository at this point in the history
In my attempt to fix a memory leak, I introduced a double-free in the
pstore error path. Instead of trying to manage the allocation lifetime
between persistent_ram_new() and its callers, adjust the logic so
persistent_ram_new() always takes a kstrdup() copy, and leaves the
caller's allocation lifetime up to the caller. Therefore callers are
_always_ responsible for freeing their label. Before, it only needed
freeing when the prz itself failed to allocate, and not in any of the
other prz failure cases, which callers would have no visibility into,
which is the root design problem that lead to both the leak and now
double-free bugs.

Reported-by: Cengiz Can <cengiz@kernel.wtf>
Link: https://lore.kernel.org/lkml/d4ec59002ede4aaf9928c7f7526da87c@kernel.wtf
Fixes: 8df955a ("pstore/ram: Fix error-path memory leak in persistent_ram_new() callers")
Cc: stable@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
  • Loading branch information
Kees Cook committed Jan 9, 2020
1 parent 9e5f1c1 commit e163fdb
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 3 deletions.
4 changes: 2 additions & 2 deletions fs/pstore/ram.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,12 +583,12 @@ static int ramoops_init_przs(const char *name,
prz_ar[i] = persistent_ram_new(*paddr, zone_sz, sig,
&cxt->ecc_info,
cxt->memtype, flags, label);
kfree(label);
if (IS_ERR(prz_ar[i])) {
err = PTR_ERR(prz_ar[i]);
dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n",
name, record_size,
(unsigned long long)*paddr, err);
kfree(label);

while (i > 0) {
i--;
Expand Down Expand Up @@ -629,12 +629,12 @@ static int ramoops_init_prz(const char *name,
label = kasprintf(GFP_KERNEL, "ramoops:%s", name);
*prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info,
cxt->memtype, PRZ_FLAG_ZAP_OLD, label);
kfree(label);
if (IS_ERR(*prz)) {
int err = PTR_ERR(*prz);

dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n",
name, sz, (unsigned long long)*paddr, err);
kfree(label);
return err;
}

Expand Down
2 changes: 1 addition & 1 deletion fs/pstore/ram_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
/* Initialize general buffer state. */
raw_spin_lock_init(&prz->buffer_lock);
prz->flags = flags;
prz->label = label;
prz->label = kstrdup(label, GFP_KERNEL);

ret = persistent_ram_buffer_map(start, size, prz, memtype);
if (ret)
Expand Down

0 comments on commit e163fdb

Please sign in to comment.