* [PATCH v1 0/2] User namespaces for NFSD's NFS_ACL implementation
@ 2026-10-27 13:51 Chuck Lever
2026-10-27 13:51 ` [PATCH v1 1/2] NFSD: Map NFS_ACLv2 entry IDs through the request's user namespace Chuck Lever
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Chuck Lever @ 2026-10-27 13:51 UTC (permalink / raw)
To: NeilBrown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey; +Cc: linux-nfs
Interpret NFS_ACL UIDs and GIDs within the server's user namespace.
This matches the way NFSv2 and NFSv3 handle UIDs and GIDs.
The NFS_ACLv2 support is probably never going to be used at this
point, but it is harmless to keep feature parity with v3.
Chuck Lever (2):
NFSD: Map NFS_ACLv2 entry IDs through the request's user namespace
NFSD: Map NFS_ACLv3 entry IDs through the request's user namespace
fs/nfsd/nfs2acl.c | 14 ++++++++------
fs/nfsd/nfs3acl.c | 14 ++++++++------
2 files changed, 16 insertions(+), 12 deletions(-)
--
2.56.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v1 1/2] NFSD: Map NFS_ACLv2 entry IDs through the request's user namespace
2026-10-27 13:51 [PATCH v1 0/2] User namespaces for NFSD's NFS_ACL implementation Chuck Lever
@ 2026-10-27 13:51 ` Chuck Lever
2026-10-27 13:51 ` [PATCH v1 2/2] NFSD: Map NFS_ACLv3 " Chuck Lever
2026-10-27 14:07 ` [PATCH v1 0/2] User namespaces for NFSD's NFS_ACL implementation Jeff Layton
2 siblings, 0 replies; 4+ messages in thread
From: Chuck Lever @ 2026-10-27 13:51 UTC (permalink / raw)
To: NeilBrown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey; +Cc: linux-nfs
The NFS_ACLv2 GETACL encoder and SETACL decoder translate each ACL
entry's ID with init_user_ns, while the fattr in the same reply goes
through nfsd_user_namespace(). When the transport's credential comes
from a non-initial user namespace, GETACL reports host-global IDs
beside namespace-relative ownership attributes, and SETACL installs
named entries for whichever host-global principals share the wire
IDs. The fs/nfs_common/nfsacl.c helpers these codecs replaced had
the same mismatch.
Translate every entry ID in the request's user namespace. On encode,
use the munged variants so an ID with no mapping in that namespace is
reported as overflowuid, as nfsd_stat_to_fattr() already does. On
decode, an ID with no mapping fails the existing uid_valid() and
gid_valid() checks, and the decoder reports the ACL as invalid.
Signed-off-by: Chuck Lever <cel@kernel.org>
---
fs/nfsd/nfs2acl.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index b846624dfe82..8b6e3d717217 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -510,6 +510,7 @@ bool nfs_acl2_secattr_encode(struct xdrgen_aggregate_cursor *c,
struct aclent *out)
{
struct svc_rqst *rqstp = c->ctx;
+ struct user_namespace *userns = nfsd_user_namespace(rqstp);
struct GETACL2res_wrapper *resp = rqstp->rq_resp;
bool dfacl = c->member_id == NFS_ACL2_SECATTR_DFACLENT;
struct posix_acl *acl = dfacl ? resp->acl_default : resp->acl_access;
@@ -536,16 +537,16 @@ bool nfs_acl2_secattr_encode(struct xdrgen_aggregate_cursor *c,
out->type = tag | typeflag;
switch (tag) {
case ACL_USER_OBJ:
- out->id = from_kuid(&init_user_ns, resp->stat.uid);
+ out->id = from_kuid_munged(userns, resp->stat.uid);
break;
case ACL_GROUP_OBJ:
- out->id = from_kgid(&init_user_ns, resp->stat.gid);
+ out->id = from_kgid_munged(userns, resp->stat.gid);
break;
case ACL_USER:
- out->id = from_kuid(&init_user_ns, entry->e_uid);
+ out->id = from_kuid_munged(userns, entry->e_uid);
break;
case ACL_GROUP:
- out->id = from_kgid(&init_user_ns, entry->e_gid);
+ out->id = from_kgid_munged(userns, entry->e_gid);
break;
default:
/*
@@ -632,6 +633,7 @@ bool nfs_acl2_secattr_decode(struct xdrgen_aggregate_cursor *c,
const struct aclent *in)
{
struct svc_rqst *rqstp = c->ctx;
+ struct user_namespace *userns = nfsd_user_namespace(rqstp);
struct SETACL2args_wrapper *argp = rqstp->rq_argp;
bool dfacl = c->member_id == NFS_ACL2_SECATTR_DFACLENT;
struct posix_acl *acl = dfacl ? argp->acl_default : argp->acl_access;
@@ -651,14 +653,14 @@ bool nfs_acl2_secattr_decode(struct xdrgen_aggregate_cursor *c,
switch (in->type & ~NA_ACL_DEFAULT) {
case ACL_USER:
/* An id with no kernel mapping makes the ACL invalid. */
- entry->e_uid = make_kuid(&init_user_ns, in->id);
+ entry->e_uid = make_kuid(userns, in->id);
if (!uid_valid(entry->e_uid)) {
argp->invalid = true;
return true;
}
break;
case ACL_GROUP:
- entry->e_gid = make_kgid(&init_user_ns, in->id);
+ entry->e_gid = make_kgid(userns, in->id);
if (!gid_valid(entry->e_gid)) {
argp->invalid = true;
return true;
--
2.56.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v1 2/2] NFSD: Map NFS_ACLv3 entry IDs through the request's user namespace
2026-10-27 13:51 [PATCH v1 0/2] User namespaces for NFSD's NFS_ACL implementation Chuck Lever
2026-10-27 13:51 ` [PATCH v1 1/2] NFSD: Map NFS_ACLv2 entry IDs through the request's user namespace Chuck Lever
@ 2026-10-27 13:51 ` Chuck Lever
2026-10-27 14:07 ` [PATCH v1 0/2] User namespaces for NFSD's NFS_ACL implementation Jeff Layton
2 siblings, 0 replies; 4+ messages in thread
From: Chuck Lever @ 2026-10-27 13:51 UTC (permalink / raw)
To: NeilBrown, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey; +Cc: linux-nfs
The NFS_ACLv3 GETACL encoder and SETACL decoder translate each ACL
entry's ID with init_user_ns, while the fattr3 in the same reply goes
through nfsd_user_namespace(). When the transport's credential comes
from a non-initial user namespace, GETACL reports host-global IDs
beside namespace-relative ownership attributes, and SETACL installs
named entries for whichever host-global principals share the wire
IDs. The fs/nfs_common/nfsacl.c helpers these codecs replaced had
the same mismatch.
Translate every entry ID in the request's user namespace. On encode,
use the munged variants so an ID with no mapping in that namespace is
reported as overflowuid, as nfsd3_fill_post_op_attr() already does.
On decode, an ID with no mapping fails the existing uid_valid() and
gid_valid() checks, and the decoder reports the ACL as invalid.
Signed-off-by: Chuck Lever <cel@kernel.org>
---
fs/nfsd/nfs3acl.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index 70e685ba1167..b426b3e64df8 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -378,6 +378,7 @@ bool nfs_acl3_secattr_encode(struct xdrgen_aggregate_cursor *c,
struct aclent *out)
{
struct svc_rqst *rqstp = c->ctx;
+ struct user_namespace *userns = nfsd_user_namespace(rqstp);
struct GETACL3res_wrapper *resp = rqstp->rq_resp;
bool dfacl = c->member_id == NFS_ACL3_SECATTR_DFACLENT;
struct posix_acl *acl = dfacl ? resp->acl_default : resp->acl_access;
@@ -404,16 +405,16 @@ bool nfs_acl3_secattr_encode(struct xdrgen_aggregate_cursor *c,
out->type = tag | typeflag;
switch (tag) {
case ACL_USER_OBJ:
- out->id = from_kuid(&init_user_ns, resp->uid);
+ out->id = from_kuid_munged(userns, resp->uid);
break;
case ACL_GROUP_OBJ:
- out->id = from_kgid(&init_user_ns, resp->gid);
+ out->id = from_kgid_munged(userns, resp->gid);
break;
case ACL_USER:
- out->id = from_kuid(&init_user_ns, entry->e_uid);
+ out->id = from_kuid_munged(userns, entry->e_uid);
break;
case ACL_GROUP:
- out->id = from_kgid(&init_user_ns, entry->e_gid);
+ out->id = from_kgid_munged(userns, entry->e_gid);
break;
default:
/*
@@ -500,6 +501,7 @@ bool nfs_acl3_secattr_decode(struct xdrgen_aggregate_cursor *c,
const struct aclent *in)
{
struct svc_rqst *rqstp = c->ctx;
+ struct user_namespace *userns = nfsd_user_namespace(rqstp);
struct SETACL3args_wrapper *argp = rqstp->rq_argp;
bool dfacl = c->member_id == NFS_ACL3_SECATTR_DFACLENT;
struct posix_acl *acl = dfacl ? argp->acl_default : argp->acl_access;
@@ -528,14 +530,14 @@ bool nfs_acl3_secattr_decode(struct xdrgen_aggregate_cursor *c,
switch (entry->e_tag) {
case ACL_USER:
/* An id with no kernel mapping makes the ACL invalid. */
- entry->e_uid = make_kuid(&init_user_ns, in->id);
+ entry->e_uid = make_kuid(userns, in->id);
if (!uid_valid(entry->e_uid)) {
argp->invalid = true;
return true;
}
break;
case ACL_GROUP:
- entry->e_gid = make_kgid(&init_user_ns, in->id);
+ entry->e_gid = make_kgid(userns, in->id);
if (!gid_valid(entry->e_gid)) {
argp->invalid = true;
return true;
--
2.56.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v1 0/2] User namespaces for NFSD's NFS_ACL implementation
2026-10-27 13:51 [PATCH v1 0/2] User namespaces for NFSD's NFS_ACL implementation Chuck Lever
2026-10-27 13:51 ` [PATCH v1 1/2] NFSD: Map NFS_ACLv2 entry IDs through the request's user namespace Chuck Lever
2026-10-27 13:51 ` [PATCH v1 2/2] NFSD: Map NFS_ACLv3 " Chuck Lever
@ 2026-10-27 14:07 ` Jeff Layton
2 siblings, 0 replies; 4+ messages in thread
From: Jeff Layton @ 2026-10-27 14:07 UTC (permalink / raw)
To: Chuck Lever, NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey; +Cc: linux-nfs
On Tue, 2026-10-27 at 09:51 -0400, Chuck Lever wrote:
> Interpret NFS_ACL UIDs and GIDs within the server's user namespace.
> This matches the way NFSv2 and NFSv3 handle UIDs and GIDs.
>
> The NFS_ACLv2 support is probably never going to be used at this
> point, but it is harmless to keep feature parity with v3.
>
> Chuck Lever (2):
> NFSD: Map NFS_ACLv2 entry IDs through the request's user namespace
> NFSD: Map NFS_ACLv3 entry IDs through the request's user namespace
>
> fs/nfsd/nfs2acl.c | 14 ++++++++------
> fs/nfsd/nfs3acl.c | 14 ++++++++------
> 2 files changed, 16 insertions(+), 12 deletions(-)
Seems like the correct thing to do.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-27 14:07 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-27 13:51 [PATCH v1 0/2] User namespaces for NFSD's NFS_ACL implementation Chuck Lever
2026-10-27 13:51 ` [PATCH v1 1/2] NFSD: Map NFS_ACLv2 entry IDs through the request's user namespace Chuck Lever
2026-10-27 13:51 ` [PATCH v1 2/2] NFSD: Map NFS_ACLv3 " Chuck Lever
2026-10-27 14:07 ` [PATCH v1 0/2] User namespaces for NFSD's NFS_ACL implementation Jeff Layton
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox