All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] statmount: allow to retrieve idmappings
@ 2025-02-04 11:27 Christian Brauner
  2025-02-04 11:27 ` [PATCH v2 1/4] uidgid: add map_id_range_up() Christian Brauner
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Christian Brauner @ 2025-02-04 11:27 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Josef Bacik, Jeff Layton, Lennart Poettering, Daan De Meyer,
	Seth Forshee, Miklos Szeredi, Christian Brauner

This adds the STATMOUNT_MNT_UIDMAP and STATMOUNT_MNT_GIDMAP options.
It allows the retrieval of idmappings via statmount().

Currently it isn't possible to figure out what idmappings are applied to
an idmapped mount. This information is often crucial. Before statmount()
the only realistic options for an interface like this would have been to
add it to /proc/<pid>/fdinfo/<nr> or to expose it in
/proc/<pid>/mountinfo. Both solution would have been pretty ugly and
would've shown information that is of strong interest to some
application but not all. statmount() is perfect for this.

The idmappings applied to an idmapped mount are shown relative to the
caller's user namespace. This is the most useful solution that doesn't
risk leaking information or confuse the caller.

For example, an idmapped mount might have been created with the
following idmappings:

    mount --bind -o X-mount.idmap="0:10000:1000 2000:2000:1 3000:3000:1" /srv /opt

Listing the idmappings through statmount() in the same context shows:

    mnt_id:        2147485088
    mnt_parent_id: 2147484816
    fs_type:       btrfs
    mnt_root:      /srv
    mnt_point:     /opt
    mnt_opts:      ssd,discard=async,space_cache=v2,subvolid=5,subvol=/
    mnt_uidmap[0]: 0 10000 1000
    mnt_uidmap[1]: 2000 2000 1
    mnt_uidmap[2]: 3000 3000 1
    mnt_gidmap[0]: 0 10000 1000
    mnt_gidmap[1]: 2000 2000 1
    mnt_gidmap[2]: 3000 3000 1

But the idmappings might not always be resolvable in the caller's user
namespace. For example:

    unshare --user --map-root

In this case statmount() will skip any mappings that fil to resolve in
the caller's idmapping:

    mnt_id:        2147485087
    mnt_parent_id: 2147484016
    fs_type:       btrfs
    mnt_root:      /srv
    mnt_point:     /opt
    mnt_opts:      ssd,discard=async,space_cache=v2,subvolid=5,subvol=/

The caller can differentiate between a mount not being idmapped and a
mount that is idmapped but where all mappings fail to resolve in the
caller's idmapping by check for the STATMOUNT_MNT_{G,U}IDMAP flag being
raised but the number of mappings in ->mnt_{g,u}idmap_num being zero.

Note that statmount() requires that the whole range must be resolvable
in the caller's user namespace. If a subrange fails to map it will still
list the map as not resolvable. This is a practical compromise to avoid
having to find which subranges are resovable and wich aren't.

Idmappings are listed as a string array with each mapping separated by
zero bytes. This allows to retrieve the idmappings and immediately use
them for writing to e.g., /proc/<pid>/{g,u}id_map and it also allow for
simple iteration like:

    if (stmnt->mask & STATMOUNT_MNT_UIDMAP) {
            const char *idmap = stmnt->str + stmnt->mnt_uidmap;

            for (size_t idx = 0; idx < stmnt->mnt_uidmap_nr; idx++) {
                    printf("mnt_uidmap[%lu]: %s\n", idx, idmap);
                    idmap += strlen(idmap) + 1;
            }
    }

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
Changes in v2:
- EDITME: describe what is new in this series revision.
- EDITME: use bulletpoints and terse descriptions.
- Link to v1: https://lore.kernel.org/r/20250130-work-mnt_idmap-statmount-v1-0-d4ced5874e14@kernel.org

---
Christian Brauner (4):
      uidgid: add map_id_range_up()
      statmount: allow to retrieve idmappings
      samples/vfs: check whether flag was raised
      samples/vfs: add STATMOUNT_MNT_{G,U}IDMAP

 fs/internal.h                      |  1 +
 fs/mnt_idmapping.c                 | 51 ++++++++++++++++++++++++++++++++
 fs/namespace.c                     | 59 +++++++++++++++++++++++++++++++++++++-
 include/linux/mnt_idmapping.h      |  5 ++++
 include/linux/uidgid.h             |  6 ++++
 include/uapi/linux/mount.h         |  8 +++++-
 kernel/user_namespace.c            | 26 +++++++++++------
 samples/vfs/samples-vfs.h          | 14 ++++++++-
 samples/vfs/test-list-all-mounts.c | 35 ++++++++++++++++++----
 9 files changed, 187 insertions(+), 18 deletions(-)
---
base-commit: 2014c95afecee3e76ca4a56956a936e23283f05b
change-id: 20250129-work-mnt_idmap-statmount-e57f258fef8e


^ permalink raw reply	[flat|nested] 7+ messages in thread
* [PATCH v2 0/4] statmount: allow to retrieve idmappings
@ 2025-02-04 11:28 Christian Brauner
  0 siblings, 0 replies; 7+ messages in thread
From: Christian Brauner @ 2025-02-04 11:28 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Josef Bacik, Jeff Layton, Lennart Poettering, Daan De Meyer,
	Seth Forshee, Miklos Szeredi, Christian Brauner

This adds the STATMOUNT_MNT_UIDMAP and STATMOUNT_MNT_GIDMAP options.
It allows the retrieval of idmappings via statmount().

Currently it isn't possible to figure out what idmappings are applied to
an idmapped mount. This information is often crucial. Before statmount()
the only realistic options for an interface like this would have been to
add it to /proc/<pid>/fdinfo/<nr> or to expose it in
/proc/<pid>/mountinfo. Both solution would have been pretty ugly and
would've shown information that is of strong interest to some
application but not all. statmount() is perfect for this.

The idmappings applied to an idmapped mount are shown relative to the
caller's user namespace. This is the most useful solution that doesn't
risk leaking information or confuse the caller.

For example, an idmapped mount might have been created with the
following idmappings:

    mount --bind -o X-mount.idmap="0:10000:1000 2000:2000:1 3000:3000:1" /srv /opt

Listing the idmappings through statmount() in the same context shows:

    mnt_id:        2147485088
    mnt_parent_id: 2147484816
    fs_type:       btrfs
    mnt_root:      /srv
    mnt_point:     /opt
    mnt_opts:      ssd,discard=async,space_cache=v2,subvolid=5,subvol=/
    mnt_uidmap[0]: 0 10000 1000
    mnt_uidmap[1]: 2000 2000 1
    mnt_uidmap[2]: 3000 3000 1
    mnt_gidmap[0]: 0 10000 1000
    mnt_gidmap[1]: 2000 2000 1
    mnt_gidmap[2]: 3000 3000 1

But the idmappings might not always be resolvable in the caller's user
namespace. For example:

    unshare --user --map-root

In this case statmount() will skip any mappings that fil to resolve in
the caller's idmapping:

    mnt_id:        2147485087
    mnt_parent_id: 2147484016
    fs_type:       btrfs
    mnt_root:      /srv
    mnt_point:     /opt
    mnt_opts:      ssd,discard=async,space_cache=v2,subvolid=5,subvol=/

The caller can differentiate between a mount not being idmapped and a
mount that is idmapped but where all mappings fail to resolve in the
caller's idmapping by check for the STATMOUNT_MNT_{G,U}IDMAP flag being
raised but the number of mappings in ->mnt_{g,u}idmap_num being zero.

Note that statmount() requires that the whole range must be resolvable
in the caller's user namespace. If a subrange fails to map it will still
list the map as not resolvable. This is a practical compromise to avoid
having to find which subranges are resovable and wich aren't.

Idmappings are listed as a string array with each mapping separated by
zero bytes. This allows to retrieve the idmappings and immediately use
them for writing to e.g., /proc/<pid>/{g,u}id_map and it also allow for
simple iteration like:

    if (stmnt->mask & STATMOUNT_MNT_UIDMAP) {
            const char *idmap = stmnt->str + stmnt->mnt_uidmap;

            for (size_t idx = 0; idx < stmnt->mnt_uidmap_nr; idx++) {
                    printf("mnt_uidmap[%lu]: %s\n", idx, idmap);
                    idmap += strlen(idmap) + 1;
            }
    }

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
Changes in v2:
- EDITME: describe what is new in this series revision.
- EDITME: use bulletpoints and terse descriptions.
- Link to v1: https://lore.kernel.org/r/20250130-work-mnt_idmap-statmount-v1-0-d4ced5874e14@kernel.org

---
Christian Brauner (4):
      uidgid: add map_id_range_up()
      statmount: allow to retrieve idmappings
      samples/vfs: check whether flag was raised
      samples/vfs: add STATMOUNT_MNT_{G,U}IDMAP

 fs/internal.h                      |  1 +
 fs/mnt_idmapping.c                 | 51 ++++++++++++++++++++++++++++++++
 fs/namespace.c                     | 59 +++++++++++++++++++++++++++++++++++++-
 include/linux/mnt_idmapping.h      |  5 ++++
 include/linux/uidgid.h             |  6 ++++
 include/uapi/linux/mount.h         |  8 +++++-
 kernel/user_namespace.c            | 26 +++++++++++------
 samples/vfs/samples-vfs.h          | 14 ++++++++-
 samples/vfs/test-list-all-mounts.c | 35 ++++++++++++++++++----
 9 files changed, 187 insertions(+), 18 deletions(-)
---
base-commit: 2014c95afecee3e76ca4a56956a936e23283f05b
change-id: 20250129-work-mnt_idmap-statmount-e57f258fef8e


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-02-04 12:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-04 11:27 [PATCH v2 0/4] statmount: allow to retrieve idmappings Christian Brauner
2025-02-04 11:27 ` [PATCH v2 1/4] uidgid: add map_id_range_up() Christian Brauner
2025-02-04 11:27 ` [PATCH v2 2/4] statmount: allow to retrieve idmappings Christian Brauner
2025-02-04 11:27 ` [PATCH v2 3/4] samples/vfs: check whether flag was raised Christian Brauner
2025-02-04 11:27 ` [PATCH v2 4/4] samples/vfs: add STATMOUNT_MNT_{G,U}IDMAP Christian Brauner
2025-02-04 12:38 ` [PATCH v2 0/4] statmount: allow to retrieve idmappings Jeff Layton
  -- strict thread matches above, loose matches on Subject: below --
2025-02-04 11:28 Christian Brauner

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.