Re: [PATCH] ubifs: fix fscrypt_name leak when purging xattrs fails

From: Zhihao Cheng

Date: Thu Oct 29 2026 - 04:55:49 EST


在 2026/10/29 16:45, shao.mingyin@xxxxxxxxxx 写道:
From: Shao Mingyin <shao.mingyin@xxxxxxxxxx>

ubifs_unlink() and ubifs_rmdir() call fscrypt_setup_filename() and
then ubifs_purge_xattrs(). For an encrypted directory the former
allocates the buffer holding the encrypted on-disk name, and every
later error path of both functions releases it through the out_fname
label. The purge failure path returns directly instead, so that
buffer is leaked.

ubifs_purge_xattrs() only does real work when the inode claims more
xattrs than UBIFS allows, in which case it deletes them one by one.
That can fail, for example with -ENOSPC from ubifs_budget_space() or
with an I/O error. Every such failed unlink() or rmdir() then leaks
one buffer of up to NAME_MAX bytes, so repeated attempts leak memory
without bound.

Jump to the existing cleanup label instead. do_rename() is not
affected: it purges the xattrs before it calls
fscrypt_setup_filename().

Fixes: 9ca2d7326444 ("ubifs: Limit number of xattrs per inode")
Signed-off-by: Shao Mingyin <shao.mingyin@xxxxxxxxxx>

Reviewed-by: Zhihao Cheng <chengzhihao1@xxxxxxxxxx>
---
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index c67954f6bee0..73594d476fe3 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -846,7 +846,7 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)

err = ubifs_purge_xattrs(inode);
if (err)
- return err;
+ goto out_fname;

sz_change = CALC_DENT_SIZE(fname_len(&nm));

@@ -955,7 +955,7 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)

err = ubifs_purge_xattrs(inode);
if (err)
- return err;
+ goto out_fname;

sz_change = CALC_DENT_SIZE(fname_len(&nm));
.