Messages in this thread Patch in this message | | | Date | Mon, 5 Aug 2019 10:34:04 -0700 | From | Tejun Heo <> | Subject | [PATCH] kernfs: fix memleak in kernel_ops_readdir() |
| |
From: Andrea Arcangeli <aarcange@redhat.com>
If getdents64 is killed or hits on segfault, it'll leave cgroups directories in sysfs pinned leaking memory because the kernfs node won't be freed on rmdir and the parent neither.
Repro:
# for i in `seq 1000`; do mkdir $i; done # rmdir * # for i in `seq 1000`; do mkdir $i; done # rmdir *
# for i in `seq 1000`; do while :; do ls $i/ >/dev/null; done & done # while :; do killall ls; done
kernfs_node_cache in /proc/slabinfo keeps going up as expected.
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Signed-off-by: Tejun Heo <tj@kernel.org> Cc: stable@vger.kernel.org # goes way back to original sysfs days --- fs/kernfs/dir.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 1e7a74b8e064..82b6c699fa34 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1683,11 +1683,14 @@ static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx) kernfs_get(pos); mutex_unlock(&kernfs_mutex); - if (!dir_emit(ctx, name, len, ino, type)) - return 0; + if (unlikely(!dir_emit(ctx, name, len, ino, type))) { + kernfs_put(pos); + goto out; + } mutex_lock(&kernfs_mutex); } mutex_unlock(&kernfs_mutex); +out: file->private_data = NULL; ctx->pos = INT_MAX; return 0;
| |