All of lore.kernel.org
 help / color / mirror / Atom feed
* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.