mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 21:51:40 +00:00
pstore: Fix double-free in pstore_mkfile() failure path
The pstore_mkfile() function is passed a pointer to a struct pstore_record. On success it consumes this 'record' pointer and references it from the created inode. On failure, however, it may or may not free the record. There are even two different code paths which return -ENOMEM -- one of which does and the other doesn't free the record. Make the behaviour deterministic by never consuming and freeing the record when returning failure, allowing the caller to do the cleanup consistently. Signed-off-by: Norbert Manthey <nmanthey@amazon.de> Link: https://lore.kernel.org/r/1562331960-26198-1-git-send-email-nmanthey@amazon.de Fixes:83f70f0769
("pstore: Do not duplicate record metadata") Fixes:1dfff7dd67
("pstore: Pass record contents instead of copying") Cc: stable@vger.kernel.org [kees: also move "private" allocation location, rename inode cleanup label] Signed-off-by: Kees Cook <keescook@chromium.org>
This commit is contained in:
parent
fa1af7583e
commit
4c6d80e114
@ -318,22 +318,21 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record)
|
||||
goto fail;
|
||||
inode->i_mode = S_IFREG | 0444;
|
||||
inode->i_fop = &pstore_file_operations;
|
||||
private = kzalloc(sizeof(*private), GFP_KERNEL);
|
||||
if (!private)
|
||||
goto fail_alloc;
|
||||
private->record = record;
|
||||
|
||||
scnprintf(name, sizeof(name), "%s-%s-%llu%s",
|
||||
pstore_type_to_name(record->type),
|
||||
record->psi->name, record->id,
|
||||
record->compressed ? ".enc.z" : "");
|
||||
|
||||
private = kzalloc(sizeof(*private), GFP_KERNEL);
|
||||
if (!private)
|
||||
goto fail_inode;
|
||||
|
||||
dentry = d_alloc_name(root, name);
|
||||
if (!dentry)
|
||||
goto fail_private;
|
||||
|
||||
private->record = record;
|
||||
inode->i_size = private->total_size = size;
|
||||
|
||||
inode->i_private = private;
|
||||
|
||||
if (record->time.tv_sec)
|
||||
@ -349,7 +348,7 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record)
|
||||
|
||||
fail_private:
|
||||
free_pstore_private(private);
|
||||
fail_alloc:
|
||||
fail_inode:
|
||||
iput(inode);
|
||||
|
||||
fail:
|
||||
|
Loading…
Reference in New Issue
Block a user