mntfsd: add api to mount dirs for containers
systemd-mountfsd so far provided a MountImage() API call for mounting a disk image and returning a set of mount fds. This complements the API with a new MountDirectory() API call, that operates on a directory instead of an image file. Now, what makes this interesting is that it applies an idmapping from the foreign UID range to the provided target userns – and in which case unpriveleged operation is allowed (well, under some conditions: in particular the client must own a parent dir of the provided path). This allows container managers to run fully unprivileged from directories – as long as those directories are owned by the foreign UID range. Basic operation is like this: 1. acquire a transient userns from systemd-nsresourced with 64K users 2. ask systemd-mountfsd for an idmapped mount of the container dir matching that userns 3. join the userns and bind the mount fd as root. Note that we have to drop various sandboxing knobs from the mountfsd service file for this to work, since the kernel's security checks that try to ensure than an obstructed /proc/ cannot be circumvented via mounting a new procfs will otherwise prohibit mountfsd to duplicate the mounts properly.
This commit is contained in:
@@ -49,6 +49,31 @@ static SD_VARLINK_DEFINE_METHOD(
|
||||
SD_VARLINK_DEFINE_OUTPUT(imageName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_DEFINE_OUTPUT(imageUuid, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_ENUM_TYPE(
|
||||
MountMapMode,
|
||||
SD_VARLINK_FIELD_COMMENT("Map the caller's UID to root in the user namespace, do not map anything else."),
|
||||
SD_VARLINK_DEFINE_ENUM_VALUE(root),
|
||||
SD_VARLINK_FIELD_COMMENT("Map the foreign UID range to the base UID range in the user namespace (i.e. UID zero and above), covering 64K users."),
|
||||
SD_VARLINK_DEFINE_ENUM_VALUE(foreign),
|
||||
SD_VARLINK_FIELD_COMMENT("Apply an identity (1:1) mapping, but limit it to 64K users."),
|
||||
SD_VARLINK_DEFINE_ENUM_VALUE(identity),
|
||||
SD_VARLINK_FIELD_COMMENT("Determine automatically based on provided directory and caller."),
|
||||
SD_VARLINK_DEFINE_ENUM_VALUE(auto));
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
MountDirectory,
|
||||
SD_VARLINK_FIELD_COMMENT("Directory file descriptor of the directory to assign to the user namespace. Must be a regular, i.e. non-O_PATH file descriptor."),
|
||||
SD_VARLINK_DEFINE_INPUT(directoryFileDescriptor, SD_VARLINK_INT, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("File descriptor to the user namespace to assign this directory to. If not specified uses the host user namespace."),
|
||||
SD_VARLINK_DEFINE_INPUT(userNamespaceFileDescriptor, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether to mark the resulting mount file descriptor as read-only. If not specified defaults to false."),
|
||||
SD_VARLINK_DEFINE_INPUT(readOnly, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Which kinda of UID/GID mapping to apply to the resulting mount file descriptor."),
|
||||
SD_VARLINK_DEFINE_INPUT_BY_TYPE(mode, MountMapMode, SD_VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_POLKIT_INPUT,
|
||||
SD_VARLINK_FIELD_COMMENT("The freshly allocated mount file descriptor for the mount."),
|
||||
SD_VARLINK_DEFINE_OUTPUT(mountFileDescriptor, SD_VARLINK_INT, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_ERROR(IncompatibleImage);
|
||||
static SD_VARLINK_DEFINE_ERROR(MultipleRootPartitionsFound);
|
||||
static SD_VARLINK_DEFINE_ERROR(RootPartitionNotFound);
|
||||
@@ -59,9 +84,17 @@ static SD_VARLINK_DEFINE_ERROR(VerityFailure);
|
||||
SD_VARLINK_DEFINE_INTERFACE(
|
||||
io_systemd_MountFileSystem,
|
||||
"io.systemd.MountFileSystem",
|
||||
SD_VARLINK_INTERFACE_COMMENT("APIs for unpriviliged mounting."),
|
||||
SD_VARLINK_SYMBOL_COMMENT("Encodes the designated purpose of a partition."),
|
||||
&vl_type_PartitionDesignator,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Information about a specific partition."),
|
||||
&vl_type_PartitionInfo,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Selects the type of UID/GID mapping to apply."),
|
||||
&vl_type_MountMapMode,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Takes a disk image file descriptor as input, returns a set of mount file descriptors for it."),
|
||||
&vl_method_MountImage,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Takes a directory file descriptor as input, returns a mount file descriptor."),
|
||||
&vl_method_MountDirectory,
|
||||
&vl_error_IncompatibleImage,
|
||||
&vl_error_MultipleRootPartitionsFound,
|
||||
&vl_error_RootPartitionNotFound,
|
||||
|
||||
Reference in New Issue
Block a user