From: Josef Bacik <josef@toxicpanda.com>
bpf_token_create() allocates a bpffs inode and hands it to
alloc_file_pseudo(). The inode reference only moves to the new file when
that call succeeds: alloc_file_pseudo() leaves the caller's reference alone
on failure, and FD_PREPARE() does not even evaluate the file expression
when it cannot get a descriptor.
Before the conversion to FD_PREPARE() the error path did iput(inode). The
conversion dropped it, so each BPF_TOKEN_CREATE that fails with -EMFILE,
-ENFILE or -ENOMEM at this point leaks an inode. A task that is allowed to
create tokens can hit this at will by lowering RLIMIT_NOFILE, and the
leaked inodes make umount of that bpffs instance complain about busy
inodes.
Put the inode again if no file was created.
Fixes: 981bec8f698b ("bpf: convert bpf_token_create() to FD_PREPARE()")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
---
kernel/bpf/token.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/token.c b/kernel/bpf/token.c
index e85a179523f0..19660ef95ddb 100644
--- a/kernel/bpf/token.c
+++ b/kernel/bpf/token.c
@@ -169,8 +169,11 @@ int bpf_token_create(union bpf_attr *attr)
FD_PREPARE(fdf, O_CLOEXEC,
alloc_file_pseudo(inode, path.mnt, BPF_TOKEN_INODE_NAME,
O_RDWR, &bpf_token_fops));
- if (fdf.err)
+ if (fdf.err) {
+ /* no file took over the inode reference */
+ iput(inode);
return fdf.err;
+ }
token = kzalloc_obj(*token, GFP_USER);
if (!token)--
2.55.0