mirror of
https://github.com/systemd/systemd
synced 2025-11-23 10:44:45 +01:00
Compare commits
6 Commits
de425dc72c
...
2c4263f987
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c4263f987 | ||
|
|
015025cba2 | ||
|
|
ece4df0293 | ||
|
|
1a00afe0ff | ||
|
|
e77566fbca | ||
|
|
ec3139db8b |
@ -1157,7 +1157,7 @@ static const char* skip_user_prefix(const char *path) {
|
||||
return skip_session(e);
|
||||
}
|
||||
|
||||
int cg_path_get_user_unit(const char *path, char **ret) {
|
||||
int cg_path_get_user_unit_full(const char *path, char **ret_unit, char **ret_subgroup) {
|
||||
const char *t;
|
||||
|
||||
assert(path);
|
||||
@ -1168,18 +1168,42 @@ int cg_path_get_user_unit(const char *path, char **ret) {
|
||||
|
||||
/* And from here on it looks pretty much the same as for a system unit, hence let's use the same
|
||||
* parser. */
|
||||
return cg_path_get_unit(t, ret);
|
||||
return cg_path_get_unit_full(t, ret_unit, ret_subgroup);
|
||||
}
|
||||
|
||||
int cg_pid_get_user_unit(pid_t pid, char **ret_unit) {
|
||||
_cleanup_free_ char *cgroup = NULL;
|
||||
int cg_pid_get_user_unit_full(pid_t pid, char **ret_unit, char **ret_subgroup) {
|
||||
int r;
|
||||
|
||||
_cleanup_free_ char *cgroup = NULL;
|
||||
r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return cg_path_get_user_unit(cgroup, ret_unit);
|
||||
return cg_path_get_user_unit_full(cgroup, ret_unit, ret_subgroup);
|
||||
}
|
||||
|
||||
int cg_pidref_get_user_unit_full(const PidRef *pidref, char **ret_unit, char **ret_subgroup) {
|
||||
int r;
|
||||
|
||||
if (!pidref_is_set(pidref))
|
||||
return -ESRCH;
|
||||
if (pidref_is_remote(pidref))
|
||||
return -EREMOTE;
|
||||
|
||||
_cleanup_free_ char *unit = NULL, *subgroup = NULL;
|
||||
r = cg_pid_get_user_unit_full(pidref->pid, &unit, &subgroup);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = pidref_verify(pidref);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (ret_unit)
|
||||
*ret_unit = TAKE_PTR(unit);
|
||||
if (ret_subgroup)
|
||||
*ret_subgroup = TAKE_PTR(subgroup);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cg_path_get_machine_name(const char *path, char **ret_machine) {
|
||||
|
||||
@ -208,7 +208,10 @@ static inline int cg_path_get_unit(const char *path, char **ret_unit) {
|
||||
return cg_path_get_unit_full(path, ret_unit, NULL);
|
||||
}
|
||||
int cg_path_get_unit_path(const char *path, char **ret_unit);
|
||||
int cg_path_get_user_unit(const char *path, char **ret_unit);
|
||||
int cg_path_get_user_unit_full(const char *path, char **ret_unit, char **ret_subgroup);
|
||||
static inline int cg_path_get_user_unit(const char *path, char **ret_unit) {
|
||||
return cg_path_get_user_unit_full(path, ret_unit, NULL);
|
||||
}
|
||||
int cg_path_get_machine_name(const char *path, char **ret_machine);
|
||||
int cg_path_get_slice(const char *path, char **ret_slice);
|
||||
int cg_path_get_user_slice(const char *path, char **ret_slice);
|
||||
@ -228,7 +231,14 @@ int cg_pidref_get_unit_full(const PidRef *pidref, char **ret_unit, char **ret_su
|
||||
static inline int cg_pidref_get_unit(const PidRef *pidref, char **ret_unit) {
|
||||
return cg_pidref_get_unit_full(pidref, ret_unit, NULL);
|
||||
}
|
||||
int cg_pid_get_user_unit(pid_t pid, char **ret_unit);
|
||||
int cg_pid_get_user_unit_full(pid_t pid, char **ret_unit, char **ret_subgroup);
|
||||
static inline int cg_pid_get_user_unit(pid_t pid, char **ret_unit) {
|
||||
return cg_pid_get_unit_full(pid, ret_unit, NULL);
|
||||
}
|
||||
int cg_pidref_get_user_unit_full(const PidRef *pidref, char **ret_unit, char **ret_subgroup);
|
||||
static inline int cg_pidref_get_user_unit(const PidRef *pidref, char **ret_unit) {
|
||||
return cg_pidref_get_user_unit_full(pidref, ret_unit, NULL);
|
||||
}
|
||||
int cg_pid_get_machine_name(pid_t pid, char **ret_machine);
|
||||
int cg_pid_get_slice(pid_t pid, char **ret_slice);
|
||||
int cg_pid_get_user_slice(pid_t pid, char **ret_slice);
|
||||
|
||||
@ -250,8 +250,7 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) {
|
||||
}
|
||||
|
||||
int open_tmpfile_unlinkable(const char *directory, int flags) {
|
||||
char *p;
|
||||
int fd, r;
|
||||
int r;
|
||||
|
||||
if (!directory) {
|
||||
r = tmp_dir(&directory);
|
||||
@ -263,12 +262,14 @@ int open_tmpfile_unlinkable(const char *directory, int flags) {
|
||||
/* Returns an unlinked temporary file that cannot be linked into the file system anymore */
|
||||
|
||||
/* Try O_TMPFILE first, if it is supported */
|
||||
fd = open(directory, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
|
||||
int fd = open(directory, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
|
||||
/* Fall back to unguessable name + unlinking */
|
||||
p = strjoina(directory, "/systemd-tmp-XXXXXX");
|
||||
_cleanup_free_ char *p = path_join(directory, "/systemd-tmp-XXXXXX");
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
fd = mkostemp_safe(p);
|
||||
if (fd < 0)
|
||||
@ -280,8 +281,7 @@ int open_tmpfile_unlinkable(const char *directory, int flags) {
|
||||
}
|
||||
|
||||
int open_tmpfile_linkable_at(int dir_fd, const char *target, int flags, char **ret_path) {
|
||||
_cleanup_free_ char *tmp = NULL;
|
||||
int r, fd;
|
||||
int r;
|
||||
|
||||
assert(target);
|
||||
assert(ret_path);
|
||||
@ -293,7 +293,7 @@ int open_tmpfile_linkable_at(int dir_fd, const char *target, int flags, char **r
|
||||
* which case "ret_path" will be returned as NULL. If not possible the temporary path name used is returned in
|
||||
* "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
|
||||
|
||||
fd = open_parent_at(dir_fd, target, O_TMPFILE|flags, 0640);
|
||||
int fd = open_parent_at(dir_fd, target, O_TMPFILE|flags, 0640);
|
||||
if (fd >= 0) {
|
||||
*ret_path = NULL;
|
||||
return fd;
|
||||
@ -301,6 +301,7 @@ int open_tmpfile_linkable_at(int dir_fd, const char *target, int flags, char **r
|
||||
|
||||
log_debug_errno(fd, "Failed to use O_TMPFILE for %s: %m", target);
|
||||
|
||||
_cleanup_free_ char *tmp = NULL;
|
||||
r = tempfn_random(target, NULL, &tmp);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1483,7 +1483,7 @@ static int gather_pid_metadata_from_procfs(struct iovec_wrapper *iovw, Context *
|
||||
if (cg_pidref_get_unit(&context->pidref, &t) >= 0)
|
||||
(void) iovw_put_string_field_free(iovw, "COREDUMP_UNIT=", t);
|
||||
|
||||
if (cg_pid_get_user_unit(pid, &t) >= 0)
|
||||
if (cg_pidref_get_user_unit(&context->pidref, &t) >= 0)
|
||||
(void) iovw_put_string_field_free(iovw, "COREDUMP_USER_UNIT=", t);
|
||||
|
||||
if (cg_pidref_get_session(&context->pidref, &t) >= 0)
|
||||
|
||||
@ -134,6 +134,7 @@ static int probe_file_system_by_fd(
|
||||
char **ret_fstype,
|
||||
sd_id128_t *ret_uuid) {
|
||||
|
||||
#if HAVE_BLKID
|
||||
_cleanup_(blkid_free_probep) blkid_probe b = NULL;
|
||||
const char *fstype = NULL;
|
||||
sd_id128_t id;
|
||||
@ -183,6 +184,9 @@ static int probe_file_system_by_fd(
|
||||
return r;
|
||||
*ret_uuid = id;
|
||||
return 0;
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int probe_file_system_by_path(const char *path, char **ret_fstype, sd_id128_t *ret_uuid) {
|
||||
@ -663,6 +667,7 @@ static int luks_validate(
|
||||
uint64_t *ret_offset,
|
||||
uint64_t *ret_size) {
|
||||
|
||||
#if HAVE_BLKID
|
||||
_cleanup_(blkid_free_probep) blkid_probe b = NULL;
|
||||
sd_id128_t found_partition_uuid = SD_ID128_NULL;
|
||||
const char *fstype = NULL, *pttype = NULL;
|
||||
@ -775,6 +780,9 @@ static int luks_validate(
|
||||
*ret_partition_uuid = found_partition_uuid;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int crypt_device_to_evp_cipher(struct crypt_device *cd, const EVP_CIPHER **ret) {
|
||||
|
||||
@ -659,7 +659,7 @@ static DirectoryOwnership validate_directory_fd(int fd, uid_t peer_uid) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fl = fd_verify_safe_flags_full(fd, O_DIRECTORY);
|
||||
fl = fd_verify_safe_flags_full(fd, O_DIRECTORY|O_PATH);
|
||||
if (fl < 0)
|
||||
return log_debug_errno(fl, "Directory file descriptor has unsafe flags set: %m");
|
||||
|
||||
|
||||
@ -4271,6 +4271,7 @@ static bool context_changed(const Context *context) {
|
||||
}
|
||||
|
||||
static int context_wipe_range(Context *context, uint64_t offset, uint64_t size) {
|
||||
#if HAVE_BLKID
|
||||
_cleanup_(blkid_free_probep) blkid_probe probe = NULL;
|
||||
int r;
|
||||
|
||||
@ -4312,6 +4313,10 @@ static int context_wipe_range(Context *context, uint64_t offset, uint64_t size)
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Cannot wipe partition signatures, libblkid support is not compiled in.");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int context_wipe_partition(Context *context, Partition *p) {
|
||||
@ -7361,6 +7366,7 @@ static int resolve_copy_blocks_auto_candidate(
|
||||
dev_t restrict_devno,
|
||||
sd_id128_t *ret_uuid) {
|
||||
|
||||
#if HAVE_BLKID
|
||||
_cleanup_(blkid_free_probep) blkid_probe b = NULL;
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
@ -7473,6 +7479,10 @@ static int resolve_copy_blocks_auto_candidate(
|
||||
*ret_uuid = u;
|
||||
|
||||
return true;
|
||||
#else
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Cannot check partition type UUID and device location, libblkid support is not compiled in.");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int resolve_copy_blocks_auto_candidate_harder(
|
||||
|
||||
@ -1440,23 +1440,31 @@ static int dissect_image(
|
||||
}
|
||||
}
|
||||
|
||||
/* Verity found but no matching rootfs? Something is off, refuse. */
|
||||
if (!m->partitions[PARTITION_ROOT].found &&
|
||||
(m->partitions[PARTITION_ROOT_VERITY].found ||
|
||||
m->partitions[PARTITION_ROOT_VERITY_SIG].found))
|
||||
return -EADDRNOTAVAIL; /* Verity found but no matching rootfs? Something is off, refuse. */
|
||||
return log_debug_errno(
|
||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||
"Found root verity hash partition without matching root data partition");
|
||||
|
||||
/* Hmm, we found a signature partition but no Verity data? Something is off. */
|
||||
if (m->partitions[PARTITION_ROOT_VERITY_SIG].found && !m->partitions[PARTITION_ROOT_VERITY].found)
|
||||
return -EADDRNOTAVAIL;
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||
"Found root verity signature partition without matching root verity hash partition");
|
||||
|
||||
/* as above */
|
||||
if (!m->partitions[PARTITION_USR].found &&
|
||||
(m->partitions[PARTITION_USR_VERITY].found ||
|
||||
m->partitions[PARTITION_USR_VERITY_SIG].found))
|
||||
return -EADDRNOTAVAIL; /* as above */
|
||||
return log_debug_errno(
|
||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||
"Found usr verity hash partition without matching usr data partition");
|
||||
|
||||
/* as above */
|
||||
if (m->partitions[PARTITION_USR_VERITY_SIG].found && !m->partitions[PARTITION_USR_VERITY].found)
|
||||
return -EADDRNOTAVAIL;
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||
"Found usr verity signature partition without matching usr verity hash partition");
|
||||
|
||||
/* If root and /usr are combined then insist that the architecture matches */
|
||||
if (m->partitions[PARTITION_ROOT].found &&
|
||||
@ -1464,7 +1472,10 @@ static int dissect_image(
|
||||
(m->partitions[PARTITION_ROOT].architecture >= 0 &&
|
||||
m->partitions[PARTITION_USR].architecture >= 0 &&
|
||||
m->partitions[PARTITION_ROOT].architecture != m->partitions[PARTITION_USR].architecture))
|
||||
return -EADDRNOTAVAIL;
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EREMOTE),
|
||||
"Found root and usr partitions with different architectures (%s vs %s)",
|
||||
architecture_to_string(m->partitions[PARTITION_ROOT].architecture),
|
||||
architecture_to_string(m->partitions[PARTITION_USR].architecture));
|
||||
|
||||
if (!m->partitions[PARTITION_ROOT].found &&
|
||||
!m->partitions[PARTITION_USR].found &&
|
||||
@ -1532,39 +1543,58 @@ static int dissect_image(
|
||||
/* Check if we have a root fs if we are told to do check. /usr alone is fine too, but only if appropriate flag for that is set too */
|
||||
if (FLAGS_SET(flags, DISSECT_IMAGE_REQUIRE_ROOT) &&
|
||||
!(m->partitions[PARTITION_ROOT].found || (m->partitions[PARTITION_USR].found && FLAGS_SET(flags, DISSECT_IMAGE_USR_NO_ROOT))))
|
||||
return -ENXIO;
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Root or usr partition requested but found neither");
|
||||
|
||||
if (m->partitions[PARTITION_ROOT_VERITY].found) {
|
||||
/* We only support one verity partition per image, i.e. can't do for both /usr and root fs */
|
||||
if (m->partitions[PARTITION_USR_VERITY].found)
|
||||
return -ENOTUNIQ;
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOTUNIQ), "Found both root and usr verity enabled partitions which is not supported");
|
||||
|
||||
/* We don't support verity enabled root with a split out /usr. Neither with nor without
|
||||
* verity there. (Note that we do support verity-less root with verity-full /usr, though.) */
|
||||
if (m->partitions[PARTITION_USR].found)
|
||||
return -EADDRNOTAVAIL;
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL), "Found verity enabled root partition with split usr partition which is not supported");
|
||||
}
|
||||
|
||||
if (verity) {
|
||||
/* If a verity designator is specified, then insist that the matching partition exists */
|
||||
if (verity->designator >= 0 && !m->partitions[verity->designator].found)
|
||||
return -EADDRNOTAVAIL;
|
||||
return log_debug_errno(
|
||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||
"Explicit %s verity designator was specified but did not find %s partition",
|
||||
partition_designator_to_string(verity->designator),
|
||||
partition_designator_to_string(verity->designator));
|
||||
|
||||
if (verity->root_hash) {
|
||||
/* If we have an explicit root hash and found the partitions for it, then we are ready to use
|
||||
* Verity, set things up for it */
|
||||
|
||||
if (verity->designator < 0 || verity->designator == PARTITION_ROOT) {
|
||||
if (!m->partitions[PARTITION_ROOT_VERITY].found || !m->partitions[PARTITION_ROOT].found)
|
||||
return -EADDRNOTAVAIL;
|
||||
if (!m->partitions[PARTITION_ROOT].found)
|
||||
return log_debug_errno(
|
||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||
"Verity enabled root partition was requested but did not find a root data partition");
|
||||
|
||||
if (!m->partitions[PARTITION_ROOT_VERITY].found)
|
||||
return log_debug_errno(
|
||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||
"Verity enabled root partition was requested but did not find a root verity hash partition");
|
||||
|
||||
/* If we found a verity setup, then the root partition is necessarily read-only. */
|
||||
m->partitions[PARTITION_ROOT].rw = false;
|
||||
} else {
|
||||
assert(verity->designator == PARTITION_USR);
|
||||
|
||||
if (!m->partitions[PARTITION_USR_VERITY].found || !m->partitions[PARTITION_USR].found)
|
||||
return -EADDRNOTAVAIL;
|
||||
if (!m->partitions[PARTITION_USR].found)
|
||||
return log_debug_errno(
|
||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||
"Verity enabled usr partition was requested but did not find a usr data partition");
|
||||
|
||||
if (!m->partitions[PARTITION_USR_VERITY].found)
|
||||
return log_debug_errno(
|
||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||
"Verity enabled usr partition was requested but did not find a usr verity hash partition");
|
||||
|
||||
|
||||
m->partitions[PARTITION_USR].rw = false;
|
||||
}
|
||||
@ -1697,7 +1727,10 @@ int dissect_log_error(int log_level, int r, const char *name, const VeritySettin
|
||||
return log_full_errno(log_level, r, "%s: The image does not pass os-release/extension-release validation.", name);
|
||||
|
||||
case -EADDRNOTAVAIL:
|
||||
return log_full_errno(log_level, r, "%s: No root partition for specified root hash found.", name);
|
||||
return log_full_errno(log_level, r, "%s: No root/usr partition for specified root/usr hash found.", name);
|
||||
|
||||
case -EREMOTE:
|
||||
return log_full_errno(log_level, r, "%s: Found root and usr partitions with different architectures", name);
|
||||
|
||||
case -ENOTUNIQ:
|
||||
return log_full_errno(log_level, r, "%s: Multiple suitable root partitions found in image.", name);
|
||||
@ -4750,7 +4783,7 @@ int mountfsd_mount_directory(
|
||||
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);
|
||||
_cleanup_close_ int directory_fd = open(path, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_PATH);
|
||||
if (directory_fd < 0)
|
||||
return log_error_errno(errno, "Failed to open '%s': %m", path);
|
||||
|
||||
|
||||
@ -1064,9 +1064,8 @@ int loop_device_refresh_size(LoopDevice *d, uint64_t offset, uint64_t size) {
|
||||
VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
|
||||
#endif
|
||||
|
||||
if (size == UINT64_MAX && offset == UINT64_MAX)
|
||||
return 0;
|
||||
if (info.lo_sizelimit == size && info.lo_offset == offset)
|
||||
if ((size == UINT64_MAX || info.lo_sizelimit == size) &&
|
||||
(offset == UINT64_MAX || info.lo_offset == offset))
|
||||
return 0;
|
||||
|
||||
if (size != UINT64_MAX)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user