On Wed, 25 Nov 2020 at 11:27, Oleksandr Natalenko <oleksandr@xxxxxxxxxxxxxx> wrote: > > On 25.11.2020 08:53, Ard Biesheuvel wrote: > > The memory leak addressed by commit fe5186cf12e3 is a false positive: > > all allocations are recorded in a linked list, and freed when the > > filesystem is unmounted. This leads to double frees, and as reported > > by David, leads to crashes if SLUB is configured to self destruct when > > double frees occur. > > > > So drop the redundant kfree() again, and instead, mark the offending > > pointer variable so the allocation is ignored by kmemleak. > > > > Cc: Vamshi K Sthambamkadi <vamshi.k.sthambamkadi@xxxxxxxxx> > > Fixes: fe5186cf12e3 ("efivarfs: fix memory leak in efivarfs_create()") > > Reported-by: David Laight <David.Laight@xxxxxxxxxx> > > Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx> > > --- > > fs/efivarfs/inode.c | 1 + > > fs/efivarfs/super.c | 1 - > > 2 files changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/fs/efivarfs/inode.c b/fs/efivarfs/inode.c > > index 96c0c86f3fff..38324427a2b3 100644 > > --- a/fs/efivarfs/inode.c > > +++ b/fs/efivarfs/inode.c > > @@ -103,6 +103,7 @@ static int efivarfs_create(struct inode *dir, > > struct dentry *dentry, > > var->var.VariableName[i] = '\0'; > > > > inode->i_private = var; > > + kmemleak_ignore(var); > > Do we need to do this as well: > > #include <linux/kmemleak.h> > > ? > > Because otherwise for 5.9 I get: > > [ 148s] fs/efivarfs/inode.c: In function 'efivarfs_create': > [ 148s] fs/efivarfs/inode.c:106:2: error: implicit declaration of > function 'kmemleak_ignore' [-Werror=implicit-function-declaration] > [ 148s] 106 | kmemleak_ignore(var); > [ 148s] | ^~~~~~~~~~~~~~~ > Ah yes, thanks for the report. I will add the include to the patch. > > > > err = efivar_entry_add(var, &efivarfs_list); > > if (err) > > diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c > > index f943fd0b0699..15880a68faad 100644 > > --- a/fs/efivarfs/super.c > > +++ b/fs/efivarfs/super.c > > @@ -21,7 +21,6 @@ LIST_HEAD(efivarfs_list); > > static void efivarfs_evict_inode(struct inode *inode) > > { > > clear_inode(inode); > > - kfree(inode->i_private); > > } > > > > static const struct super_operations efivarfs_ops = { > > -- > Oleksandr Natalenko (post-factum)