1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-03 05:18:09 +03:00

dissect-image: add client side API wrapper for MountDirectory() varlink call

This commit is contained in:
Lennart Poettering 2024-11-11 17:45:18 +01:00
parent 6e50124e24
commit 1703d200f8
2 changed files with 87 additions and 0 deletions

View File

@ -2170,6 +2170,9 @@ int dissected_image_mount(
assert(m);
if (FLAGS_SET(flags, DISSECT_IMAGE_FOREIGN_UID)) /* For image based mounts we currently require an identity mapping */
return -EOPNOTSUPP;
/* If 'where' is NULL then we'll use the new mount API to create fsmount() fds for the mounts and
* store them in DissectedPartition.fsmount_fd.
*
@ -4406,3 +4409,84 @@ int mountfsd_mount_image(
return -EOPNOTSUPP;
#endif
}
typedef struct MountDirectoryReplyParameters {
unsigned fsmount_fd_idx;
} MountDirectoryReplyParameters;
int mountfsd_mount_directory(
const char *path,
int userns_fd,
DissectImageFlags flags,
int *ret_mount_fd) {
MountDirectoryReplyParameters p = {
.fsmount_fd_idx = UINT_MAX,
};
static const sd_json_dispatch_field dispatch_table[] = {
{ "mountFileDescriptor", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint, offsetof(struct MountDirectoryReplyParameters, fsmount_fd_idx), SD_JSON_MANDATORY },
{}
};
int r;
/* Pick one identity, not both, that makes no sense. */
assert(!FLAGS_SET(flags, DISSECT_IMAGE_FOREIGN_UID|DISSECT_IMAGE_IDENTITY_UID));
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.MountFileSystem");
if (r < 0)
return log_error_errno(r, "Failed to connect to mountfsd: %m");
r = sd_varlink_set_allow_fd_passing_input(vl, true);
if (r < 0)
return log_error_errno(r, "Failed to enable varlink fd passing for read: %m");
r = sd_varlink_set_allow_fd_passing_output(vl, true);
if (r < 0)
return log_error_errno(r, "Failed to enable varlink fd passing for write: %m");
_cleanup_close_ int directory_fd = open(path, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
if (directory_fd < 0)
return log_error_errno(errno, "Failed to open '%s': %m", path);
r = sd_varlink_push_dup_fd(vl, directory_fd);
if (r < 0)
return log_error_errno(r, "Failed to push image fd into varlink connection: %m");
if (userns_fd >= 0) {
r = sd_varlink_push_dup_fd(vl, userns_fd);
if (r < 0)
return log_error_errno(r, "Failed to push image fd into varlink connection: %m");
}
sd_json_variant *reply = NULL;
const char *error_id = NULL;
r = sd_varlink_callbo(
vl,
"io.systemd.MountFileSystem.MountDirectory",
&reply,
&error_id,
SD_JSON_BUILD_PAIR_UNSIGNED("directoryFileDescriptor", 0),
SD_JSON_BUILD_PAIR_CONDITION(userns_fd >= 0, "userNamespaceFileDescriptor", SD_JSON_BUILD_UNSIGNED(1)),
SD_JSON_BUILD_PAIR_BOOLEAN("readOnly", FLAGS_SET(flags, DISSECT_IMAGE_MOUNT_READ_ONLY)),
SD_JSON_BUILD_PAIR_STRING("mode", FLAGS_SET(flags, DISSECT_IMAGE_FOREIGN_UID) ? "foreign" :
FLAGS_SET(flags, DISSECT_IMAGE_IDENTITY_UID) ? "identity" : "auto"),
SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", FLAGS_SET(flags, DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH)));
if (r < 0)
return log_error_errno(r, "Failed to call MountDirectory() varlink call: %m");
if (!isempty(error_id))
return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to call MountDirectory() varlink call: %s", error_id);
r = sd_json_dispatch(reply, dispatch_table, SD_JSON_ALLOW_EXTENSIONS, &p);
if (r < 0)
return log_error_errno(r, "Failed to parse MountImage() reply: %m");
_cleanup_close_ int fsmount_fd = sd_varlink_take_fd(vl, p.fsmount_fd_idx);
if (fsmount_fd < 0)
return log_error_errno(fsmount_fd, "Failed to take mount fd from Varlink connection: %m");
*ret_mount_fd = TAKE_FD(fsmount_fd);
return 0;
}

View File

@ -89,6 +89,8 @@ typedef enum DissectImageFlags {
DISSECT_IMAGE_TRY_ATOMIC_MOUNT_EXCHANGE = 1 << 25, /* Try to mount the image beneath the specified mountpoint, rather than on top of it, and then umount the top */
DISSECT_IMAGE_ALLOW_USERSPACE_VERITY = 1 << 26, /* Allow userspace verity keyring in /etc/verity.d/ and related dirs */
DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH = 1 << 27, /* Allow interactive authorization when going through mountfsd */
DISSECT_IMAGE_FOREIGN_UID = 1 << 28, /* Request a foreign UID range mapping */
DISSECT_IMAGE_IDENTITY_UID = 1 << 29, /* Explicitly request an identity UID range mapping */
} DissectImageFlags;
struct DissectedImage {
@ -244,3 +246,4 @@ static inline const char* dissected_partition_fstype(const DissectedPartition *m
int get_common_dissect_directory(char **ret);
int mountfsd_mount_image(const char *path, int userns_fd, const ImagePolicy *image_policy, DissectImageFlags flags, DissectedImage **ret);
int mountfsd_mount_directory(const char *path, int userns_fd, DissectImageFlags flags, int *ret_mount_fd);