From: Chuck Lever Date: Thu, 14 May 2026 20:56:06 +0000 (-0400) Subject: lockd: Plug nlm_file refcount leak on cached nlm_do_fopen() failure X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=70a38f87bed7f0694fd07988b47b2db1e10d8df3;p=thirdparty%2Flinux.git lockd: Plug nlm_file refcount leak on cached nlm_do_fopen() failure The cached-file path in nlm_lookup_file() reaches the found: label unconditionally, even when nlm_do_fopen() fails. At that label *result and file->f_count are updated before the error is returned. The wrappers nlm3svc_lookup_file() and nlm4svc_lookup_file() then bail out of their switch without copying *result back to their caller, so the proc handler's local nlm_file pointer remains NULL and the cleanup path skips nlm_release_file(). The f_count increment is never released, and nlm_traverse_files() can no longer reap the file because its refcount never returns to zero between requests. Short-circuit the cached path so neither *result nor f_count is touched when nlm_do_fopen() fails on a hashed nlm_file. Fixes: 7f024fcd5c97 ("Keep read and write fds with each nlm_file") Cc: stable@vger.kernel.org Signed-off-by: Chuck Lever --- diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 0b81d8db09191..58b87ec529308 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c @@ -150,6 +150,8 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, mutex_lock(&file->f_mutex); nfserr = nlm_do_fopen(rqstp, file, mode); mutex_unlock(&file->f_mutex); + if (nfserr) + goto out_unlock; goto found; } nlm_debug_print_fh("creating file for", &lock->fh);