Re: Regression: Missing check in nfsd_permission() causes -ENOLCK No locks available

Sasha Levin
2026-03-04T15:44:35Z

This response was AI-generated by bug-bot. The analysis may contain errors — please verify independently.

---

Bug Summary

Commit 4cc9b9f2bf4d ("nfsd: refine and rename NFSD_MAY_LOCK"),
backported to v6.12.54 as 18744bc56b0ec, removed a critical
permission downgrade from nfsd_permission() that affects NLM lock
requests. This is a severity: functional regression -- exclusive
(and shared) file locking via NLM fails with ENOLCK on files where
the requesting user lacks write permission on the inode, such as
read-only ISO images served over NFSv3.

Stack Trace Analysis

No stack trace was included in the report; the failure is a
user-visible ENOLCK error, not a kernel crash or warning.

Root Cause Analysis

The bug is in the interaction between nlm_fopen() in
fs/nfsd/lockd.c and nfsd_permission() in fs/nfsd/vfs.c.

Before 4cc9b9f2bf4d, nfsd_permission() contained this block:

if (acc & NFSD_MAY_LOCK) {
if (exp->ex_flags & NFSEXP_NOAUTHNLM)
return 0;
else
acc = NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE;
}

This downgraded the permission check for lock requests from
MAY_WRITE to MAY_READ, because file locks do not require write
access to the file data -- only read access is needed.

Commit 4cc9b9f2bf4d correctly moved the NFSEXP_NOAUTHNLM bypass
into __fh_verify() (fs/nfsd/nfsfh.c, line 377) and added explicit
NFSD_MAY_OWNER_OVERRIDE and NFSD_MAY_BYPASS_GSS flags in
nlm_fopen(). However, it dropped the permission downgrade (the
"else" branch) entirely.

The call chain for an exclusive NLM lock is:

nlm_fopen() [fs/nfsd/lockd.c:50]
access = NFSD_MAY_WRITE | NFSD_MAY_NLM | NFSD_MAY_OWNER_OVERRIDE
| NFSD_MAY_BYPASS_GSS
-> nfsd_open()
-> __fh_verify() -> nfsd_permission()
-> inode_permission(inode, MAY_WRITE) <-- FAILS with -EACCES
-> nfsd_open() returns nfserr
-> nlm_fopen() default case returns nlm_failed
-> client sees ENOLCK

For files like ISO images (typically mode 0444 or 0644 owned by
root), the requesting NFS user does not have write permission, so
inode_permission(MAY_WRITE) fails. Previously, the downgrade to
MAY_READ would have allowed this to succeed.

The NFSD_MAY_OWNER_OVERRIDE added in nlm_fopen() only helps when
the NFS credential matches the file owner (checked at
fs/nfsd/vfs.c:2858), which is not the case for files owned by
root when accessed by non-root NFS users.

Affected Versions

This is a regression introduced by:
4cc9b9f2bf4d ("nfsd: refine and rename NFSD_MAY_LOCK")

Mainline: affected since v6.13-rc1
Stable: v6.12.54+ (backport 18744bc56b0ec)

Any kernel version >= v6.13 or v6.12.54 is affected. Versions
prior to v6.12.54 in the 6.12.y series are not affected.

Relevant Commits and Fixes

Introducing commit (mainline):
4cc9b9f2bf4d nfsd: refine and rename NFSD_MAY_LOCK

Stable backport:
18744bc56b0ec nfsd: refine and rename NFSD_MAY_LOCK (v6.12.54)

Predecessor commit that removed NFSD_MAY_LOCK from NFSv4:
6640556b0c80 NFSD: Replace use of NFSD_MAY_LOCK in nfsd4_lock()

Existing partial fix for a different aspect of the same regression:
0813c5f01249 nfsd: fix access checking for NLM under XPRTSEC policies
(Fixes: 4cc9b9f2bf4d, by Olga Kornievskaia -- addresses only the
XPRTSEC policy bypass, NOT the permission downgrade issue)

No existing mainline fix for the permission downgrade regression
was found.

Prior Discussions

No prior reports of this specific NLM permission downgrade
regression were found on lore.kernel.org. The only related
discussion is the XPRTSEC fix by Olga Kornievskaia (commit
0813c5f01249), which addresses a different facet of the same
4cc9b9f2bf4d refactoring.

The original bug was also reported via Debian bug #1128861.

Adding Neil Brown who authored the original commit 4cc9b9f2bf4d.
Adding Chuck Lever and Jeff Layton as NFSD maintainers.
Adding Olga Kornievskaia who authored the related XPRTSEC fix
(0813c5f01249) and is an NFSD reviewer.
Adding Dai Ngo and Tom Talpey as NFSD reviewers.
CC'ing stable@vger.kernel.org as the regression affects v6.12.y.

Suggested Actions

The fix is to restore the permission downgrade for NFSD_MAY_NLM
in nfsd_permission() (fs/nfsd/vfs.c). The following patch should
resolve the issue:

--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ nfsd_permission(...)
if ((acc & NFSD_MAY_TRUNC) && IS_APPEND(inode))
return nfserr_perm;

+ if (acc & NFSD_MAY_NLM)
+ acc = NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE;
+
/*
* The file owner always gets access permission for accesses that

This restores the "else" branch behavior that was lost in
4cc9b9f2bf4d: for NLM lock requests, the inode permission check
is downgraded from MAY_WRITE to MAY_READ, since file locks do not
require write access to the file data.

The reporter's workaround of keeping the check in nfsd_permission()
while also having the copy in __fh_verify() confirms this analysis.

For immediate relief, the reporter can either:
1. Apply the above one-line fix and rebuild the kernel
2. Downgrade to v6.12.48 or earlier in the 6.12.y series

Neil, could you review whether restoring just the permission
downgrade (without the NFSEXP_NOAUTHNLM check, which is now
correctly handled in __fh_verify) is the right approach?