mirror of
https://github.com/systemd/systemd
synced 2026-03-17 02:24:48 +01:00
Compare commits
8 Commits
399c8152ae
...
465f6a6284
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
465f6a6284 | ||
|
|
6b3c289406 | ||
|
|
a91bb7459b | ||
|
|
64d0c3cf2c | ||
|
|
64a2712db5 | ||
|
|
bbce82dfab | ||
|
|
417a8223af | ||
|
|
c02f81cb2d |
@ -4,6 +4,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <spawn.h>
|
#include <spawn.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/personality.h>
|
#include <sys/personality.h>
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
@ -20,6 +21,7 @@
|
|||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "architecture.h"
|
#include "architecture.h"
|
||||||
#include "argv-util.h"
|
#include "argv-util.h"
|
||||||
|
#include "capability-util.h"
|
||||||
#include "cgroup-util.h"
|
#include "cgroup-util.h"
|
||||||
#include "dirent-util.h"
|
#include "dirent-util.h"
|
||||||
#include "dlfcn-util.h"
|
#include "dlfcn-util.h"
|
||||||
@ -2227,6 +2229,26 @@ int proc_dir_read_pidref(DIR *d, PidRef *ret) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int safe_mlockall(int flags) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* When dealing with sensitive data, let's lock ourselves into memory. We do this only when
|
||||||
|
* privileged however, as otherwise the amount of lockable memory that RLIMIT_MEMLOCK grants us is
|
||||||
|
* frequently too low to make this work. The resource limit has no effect on CAP_IPC_LOCK processes,
|
||||||
|
* hence that's the capability we check for. */
|
||||||
|
r = have_effective_cap(CAP_IPC_LOCK);
|
||||||
|
if (r < 0)
|
||||||
|
return log_debug_errno(r, "Failed to determine if we have CAP_IPC_LOCK: %m");
|
||||||
|
if (r == 0)
|
||||||
|
return log_debug_errno(SYNTHETIC_ERRNO(EPERM), "Lacking CAP_IPC_LOCK, skipping mlockall().");
|
||||||
|
|
||||||
|
if (mlockall(flags) < 0)
|
||||||
|
return log_debug_errno(errno, "Failed to call mlockall(): %m");
|
||||||
|
|
||||||
|
log_debug("Successfully called mlockall().");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *const sigchld_code_table[] = {
|
static const char *const sigchld_code_table[] = {
|
||||||
[CLD_EXITED] = "exited",
|
[CLD_EXITED] = "exited",
|
||||||
[CLD_KILLED] = "killed",
|
[CLD_KILLED] = "killed",
|
||||||
|
|||||||
@ -257,5 +257,7 @@ int proc_dir_open(DIR **ret);
|
|||||||
int proc_dir_read(DIR *d, pid_t *ret);
|
int proc_dir_read(DIR *d, pid_t *ret);
|
||||||
int proc_dir_read_pidref(DIR *d, PidRef *ret);
|
int proc_dir_read_pidref(DIR *d, PidRef *ret);
|
||||||
|
|
||||||
|
int safe_mlockall(int flags);
|
||||||
|
|
||||||
_noreturn_ void report_errno_and_exit(int errno_fd, int error);
|
_noreturn_ void report_errno_and_exit(int errno_fd, int error);
|
||||||
int read_errno(int errno_fd);
|
int read_errno(int errno_fd);
|
||||||
|
|||||||
@ -1325,7 +1325,7 @@ static void cgroup_apply_firewall(Unit *u) {
|
|||||||
(void) bpf_firewall_install(u);
|
(void) bpf_firewall_install(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unit_modify_nft_set(Unit *u, bool add) {
|
static void unit_modify_nft_set(Unit *u, bool add) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
|
|||||||
@ -379,8 +379,6 @@ int cgroup_context_add_device_allow(CGroupContext *c, const char *dev, CGroupDev
|
|||||||
int cgroup_context_add_or_update_device_allow(CGroupContext *c, const char *dev, CGroupDevicePermissions p);
|
int cgroup_context_add_or_update_device_allow(CGroupContext *c, const char *dev, CGroupDevicePermissions p);
|
||||||
int cgroup_context_add_bpf_foreign_program(CGroupContext *c, uint32_t attach_type, const char *path);
|
int cgroup_context_add_bpf_foreign_program(CGroupContext *c, uint32_t attach_type, const char *path);
|
||||||
|
|
||||||
void unit_modify_nft_set(Unit *u, bool add);
|
|
||||||
|
|
||||||
CGroupMask unit_get_own_mask(Unit *u);
|
CGroupMask unit_get_own_mask(Unit *u);
|
||||||
CGroupMask unit_get_delegate_mask(Unit *u);
|
CGroupMask unit_get_delegate_mask(Unit *u);
|
||||||
CGroupMask unit_get_members_mask(Unit *u);
|
CGroupMask unit_get_members_mask(Unit *u);
|
||||||
|
|||||||
@ -1837,11 +1837,11 @@ static BUS_DEFINE_SET_TRANSIENT_PARSE(keyring_mode, ExecKeyringMode, exec_keyrin
|
|||||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_proc, ProtectProc, protect_proc_from_string);
|
static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_proc, ProtectProc, protect_proc_from_string);
|
||||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(proc_subset, ProcSubset, proc_subset_from_string);
|
static BUS_DEFINE_SET_TRANSIENT_PARSE(proc_subset, ProcSubset, proc_subset_from_string);
|
||||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(private_bpf, PrivateBPF, private_bpf_from_string);
|
static BUS_DEFINE_SET_TRANSIENT_PARSE(private_bpf, PrivateBPF, private_bpf_from_string);
|
||||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(memory_thp, MemoryTHP, memory_thp_from_string);
|
|
||||||
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(bpf_delegate_commands, uint64_t, bpf_delegate_commands_from_string);
|
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(bpf_delegate_commands, uint64_t, bpf_delegate_commands_from_string);
|
||||||
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(bpf_delegate_maps, uint64_t, bpf_delegate_maps_from_string);
|
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(bpf_delegate_maps, uint64_t, bpf_delegate_maps_from_string);
|
||||||
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(bpf_delegate_programs, uint64_t, bpf_delegate_programs_from_string);
|
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(bpf_delegate_programs, uint64_t, bpf_delegate_programs_from_string);
|
||||||
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(bpf_delegate_attachments, uint64_t, bpf_delegate_attachments_from_string);
|
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(bpf_delegate_attachments, uint64_t, bpf_delegate_attachments_from_string);
|
||||||
|
static BUS_DEFINE_SET_TRANSIENT_PARSE(memory_thp, MemoryTHP, memory_thp_from_string);
|
||||||
BUS_DEFINE_SET_TRANSIENT_PARSE(exec_preserve_mode, ExecPreserveMode, exec_preserve_mode_from_string);
|
BUS_DEFINE_SET_TRANSIENT_PARSE(exec_preserve_mode, ExecPreserveMode, exec_preserve_mode_from_string);
|
||||||
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(personality, unsigned long, parse_personality);
|
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(personality, unsigned long, parse_personality);
|
||||||
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(secure_bits, "i", int32_t, int, "%" PRIi32, secure_bits_to_string_alloc_with_check);
|
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(secure_bits, "i", int32_t, int, "%" PRIi32, secure_bits_to_string_alloc_with_check);
|
||||||
|
|||||||
@ -310,50 +310,6 @@ int exec_context_destroy_credentials(const ExecContext *c, const char *runtime_p
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_credential(
|
|
||||||
int dfd,
|
|
||||||
const char *id,
|
|
||||||
const void *data,
|
|
||||||
size_t size,
|
|
||||||
uid_t uid,
|
|
||||||
gid_t gid,
|
|
||||||
bool ownership_ok) {
|
|
||||||
|
|
||||||
_cleanup_close_ int fd = -EBADF;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(dfd >= 0);
|
|
||||||
assert(id);
|
|
||||||
assert(data || size == 0);
|
|
||||||
|
|
||||||
fd = openat(dfd, id, O_CREAT|O_EXCL|O_WRONLY|O_CLOEXEC, 0600);
|
|
||||||
if (fd < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
r = loop_write(fd, data, size);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = RET_NERRNO(fchmod(fd, 0400)); /* Take away "w" bit */
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (uid_is_valid(uid) && uid != getuid()) {
|
|
||||||
r = fd_add_uid_acl_permission(fd, uid, ACL_READ);
|
|
||||||
/* Ideally we use ACLs, since we can neatly express what we want to express:
|
|
||||||
* the user gets read access and nothing else. But if the backing fs can't
|
|
||||||
* support that (e.g. ramfs), then we can use file ownership instead. But that's
|
|
||||||
* only safe if we can then re-mount the whole thing read-only, so that the user
|
|
||||||
* can no longer chmod() the file to gain write access. */
|
|
||||||
if ((ERRNO_IS_NEG_NOT_SUPPORTED(r) || ERRNO_IS_NEG_PRIVILEGE(r)) && ownership_ok)
|
|
||||||
r = RET_NERRNO(fchown(fd, uid, gid));
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef enum CredentialSearchPath {
|
typedef enum CredentialSearchPath {
|
||||||
CREDENTIAL_SEARCH_PATH_TRUSTED,
|
CREDENTIAL_SEARCH_PATH_TRUSTED,
|
||||||
CREDENTIAL_SEARCH_PATH_ENCRYPTED,
|
CREDENTIAL_SEARCH_PATH_ENCRYPTED,
|
||||||
@ -430,6 +386,50 @@ struct load_cred_args {
|
|||||||
uint64_t left;
|
uint64_t left;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int write_credential(
|
||||||
|
int dfd,
|
||||||
|
const char *id,
|
||||||
|
const void *data,
|
||||||
|
size_t size,
|
||||||
|
uid_t uid,
|
||||||
|
gid_t gid,
|
||||||
|
bool ownership_ok) {
|
||||||
|
|
||||||
|
_cleanup_close_ int fd = -EBADF;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(dfd >= 0);
|
||||||
|
assert(id);
|
||||||
|
assert(data || size == 0);
|
||||||
|
|
||||||
|
fd = openat(dfd, id, O_CREAT|O_EXCL|O_WRONLY|O_CLOEXEC, 0600);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
r = loop_write(fd, data, size);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = RET_NERRNO(fchmod(fd, 0400)); /* Take away "w" bit */
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (uid_is_valid(uid) && uid != getuid()) {
|
||||||
|
r = fd_add_uid_acl_permission(fd, uid, ACL_READ);
|
||||||
|
/* Ideally we use ACLs, since we can neatly express what we want to express:
|
||||||
|
* the user gets read access and nothing else. But if the backing fs can't
|
||||||
|
* support that (e.g. ramfs), then we can use file ownership instead. But that's
|
||||||
|
* only safe if we can then re-mount the whole thing read-only, so that the user
|
||||||
|
* can no longer chmod() the file to gain write access. */
|
||||||
|
if ((ERRNO_IS_NEG_NOT_SUPPORTED(r) || ERRNO_IS_NEG_PRIVILEGE(r)) && ownership_ok)
|
||||||
|
r = RET_NERRNO(fchown(fd, uid, gid));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int maybe_decrypt_and_write_credential(
|
static int maybe_decrypt_and_write_credential(
|
||||||
struct load_cred_args *args,
|
struct load_cred_args *args,
|
||||||
const char *id,
|
const char *id,
|
||||||
|
|||||||
@ -4752,6 +4752,33 @@ static int setup_delegated_namespaces(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_memory_thp(MemoryTHP thp) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
switch (thp) {
|
||||||
|
|
||||||
|
case MEMORY_THP_INHERIT:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case MEMORY_THP_DISABLE:
|
||||||
|
r = RET_NERRNO(prctl(PR_SET_THP_DISABLE, 1, 0, 0, 0));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MEMORY_THP_MADVISE:
|
||||||
|
r = RET_NERRNO(prctl(PR_SET_THP_DISABLE, 1, PR_THP_DISABLE_EXCEPT_ADVISED, 0, 0));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MEMORY_THP_SYSTEM:
|
||||||
|
r = RET_NERRNO(prctl(PR_SET_THP_DISABLE, 0, 0, 0, 0));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert_not_reached();
|
||||||
|
}
|
||||||
|
|
||||||
|
return r == -EINVAL ? -EOPNOTSUPP : r;
|
||||||
|
}
|
||||||
|
|
||||||
static bool exec_context_shall_confirm_spawn(const ExecContext *context) {
|
static bool exec_context_shall_confirm_spawn(const ExecContext *context) {
|
||||||
assert(context);
|
assert(context);
|
||||||
|
|
||||||
@ -4868,32 +4895,6 @@ static int exec_fd_mark_hot(
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_memory_thp(MemoryTHP thp) {
|
|
||||||
switch (thp) {
|
|
||||||
|
|
||||||
case MEMORY_THP_INHERIT:
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case MEMORY_THP_DISABLE:
|
|
||||||
if (prctl(PR_SET_THP_DISABLE, 1, 0, 0, 0) < 0)
|
|
||||||
return errno == EINVAL ? -EOPNOTSUPP : -errno;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case MEMORY_THP_MADVISE:
|
|
||||||
if (prctl(PR_SET_THP_DISABLE, 1, PR_THP_DISABLE_EXCEPT_ADVISED, 0, 0) < 0)
|
|
||||||
return errno == EINVAL ? -EOPNOTSUPP : -errno;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case MEMORY_THP_SYSTEM:
|
|
||||||
if (prctl(PR_SET_THP_DISABLE, 0, 0, 0, 0) < 0)
|
|
||||||
return errno == EINVAL ? -EOPNOTSUPP : -errno;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert_not_reached();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int send_handoff_timestamp(
|
static int send_handoff_timestamp(
|
||||||
const ExecContext *c,
|
const ExecContext *c,
|
||||||
ExecParameters *p,
|
ExecParameters *p,
|
||||||
@ -5580,7 +5581,7 @@ int exec_invoke(
|
|||||||
|
|
||||||
r = set_memory_thp(context->memory_thp);
|
r = set_memory_thp(context->memory_thp);
|
||||||
if (r == -EOPNOTSUPP)
|
if (r == -EOPNOTSUPP)
|
||||||
log_debug_errno(r, "Setting MemoryTHP=%s is not supported, ignoring: %m",
|
log_debug_errno(r, "Setting MemoryTHP=%s is not supported, ignoring.",
|
||||||
memory_thp_to_string(context->memory_thp));
|
memory_thp_to_string(context->memory_thp));
|
||||||
else if (r < 0) {
|
else if (r < 0) {
|
||||||
*exit_status = EXIT_MEMORY_THP;
|
*exit_status = EXIT_MEMORY_THP;
|
||||||
|
|||||||
@ -1117,8 +1117,8 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
|
|||||||
"%sProtectHostname: %s%s%s\n"
|
"%sProtectHostname: %s%s%s\n"
|
||||||
"%sProtectProc: %s\n"
|
"%sProtectProc: %s\n"
|
||||||
"%sProcSubset: %s\n"
|
"%sProcSubset: %s\n"
|
||||||
"%sPrivateBPF: %s\n"
|
"%sMemoryTHP: %s\n"
|
||||||
"%sMemoryTHP: %s\n",
|
"%sPrivateBPF: %s\n",
|
||||||
prefix, c->umask,
|
prefix, c->umask,
|
||||||
prefix, empty_to_root(c->working_directory),
|
prefix, empty_to_root(c->working_directory),
|
||||||
prefix, empty_to_root(c->root_directory),
|
prefix, empty_to_root(c->root_directory),
|
||||||
@ -1146,8 +1146,8 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
|
|||||||
prefix, protect_hostname_to_string(c->protect_hostname), c->private_hostname ? ":" : "", strempty(c->private_hostname),
|
prefix, protect_hostname_to_string(c->protect_hostname), c->private_hostname ? ":" : "", strempty(c->private_hostname),
|
||||||
prefix, protect_proc_to_string(c->protect_proc),
|
prefix, protect_proc_to_string(c->protect_proc),
|
||||||
prefix, proc_subset_to_string(c->proc_subset),
|
prefix, proc_subset_to_string(c->proc_subset),
|
||||||
prefix, private_bpf_to_string(c->private_bpf),
|
prefix, memory_thp_to_string(c->memory_thp),
|
||||||
prefix, memory_thp_to_string(c->memory_thp));
|
prefix, private_bpf_to_string(c->private_bpf));
|
||||||
|
|
||||||
if (c->private_bpf == PRIVATE_BPF_YES) {
|
if (c->private_bpf == PRIVATE_BPF_YES) {
|
||||||
_cleanup_free_ char
|
_cleanup_free_ char
|
||||||
@ -3128,3 +3128,12 @@ static const char* const exec_keyring_mode_table[_EXEC_KEYRING_MODE_MAX] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_STRING_TABLE_LOOKUP(exec_keyring_mode, ExecKeyringMode);
|
DEFINE_STRING_TABLE_LOOKUP(exec_keyring_mode, ExecKeyringMode);
|
||||||
|
|
||||||
|
static const char* const memory_thp_table[_MEMORY_THP_MAX] = {
|
||||||
|
[MEMORY_THP_INHERIT] = "inherit",
|
||||||
|
[MEMORY_THP_DISABLE] = "disable",
|
||||||
|
[MEMORY_THP_MADVISE] = "madvise",
|
||||||
|
[MEMORY_THP_SYSTEM] = "system",
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP(memory_thp, MemoryTHP);
|
||||||
|
|||||||
@ -73,6 +73,24 @@ typedef enum ExecKeyringMode {
|
|||||||
_EXEC_KEYRING_MODE_INVALID = -EINVAL,
|
_EXEC_KEYRING_MODE_INVALID = -EINVAL,
|
||||||
} ExecKeyringMode;
|
} ExecKeyringMode;
|
||||||
|
|
||||||
|
typedef enum MemoryTHP {
|
||||||
|
/*
|
||||||
|
* Inherit default from process that starts systemd, i.e. do not make
|
||||||
|
* any PR_SET_THP_DISABLE call.
|
||||||
|
*/
|
||||||
|
MEMORY_THP_INHERIT,
|
||||||
|
MEMORY_THP_DISABLE, /* Disable THPs completely for the process */
|
||||||
|
MEMORY_THP_MADVISE, /* Disable THPs for the process except when madvised */
|
||||||
|
/*
|
||||||
|
* Use system default THP setting. this can be used when the process that
|
||||||
|
* starts systemd has already disabled THPs via PR_SET_THP_DISABLE, and we
|
||||||
|
* want to restore the system default THP setting at process invocation time.
|
||||||
|
*/
|
||||||
|
MEMORY_THP_SYSTEM,
|
||||||
|
_MEMORY_THP_MAX,
|
||||||
|
_MEMORY_THP_INVALID = -EINVAL,
|
||||||
|
} MemoryTHP;
|
||||||
|
|
||||||
/* Contains start and exit information about an executed command. */
|
/* Contains start and exit information about an executed command. */
|
||||||
typedef struct ExecStatus {
|
typedef struct ExecStatus {
|
||||||
dual_timestamp start_timestamp;
|
dual_timestamp start_timestamp;
|
||||||
@ -600,9 +618,8 @@ bool exec_directory_is_private(const ExecContext *context, ExecDirectoryType typ
|
|||||||
|
|
||||||
DECLARE_STRING_TABLE_LOOKUP_FROM_STRING(exec_clean_mask, ExecCleanMask);
|
DECLARE_STRING_TABLE_LOOKUP_FROM_STRING(exec_clean_mask, ExecCleanMask);
|
||||||
|
|
||||||
DECLARE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);
|
|
||||||
|
|
||||||
DECLARE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
|
DECLARE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
|
||||||
|
DECLARE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);
|
||||||
|
|
||||||
DECLARE_STRING_TABLE_LOOKUP(exec_utmp_mode, ExecUtmpMode);
|
DECLARE_STRING_TABLE_LOOKUP(exec_utmp_mode, ExecUtmpMode);
|
||||||
|
|
||||||
@ -611,11 +628,12 @@ DECLARE_STRING_TABLE_LOOKUP(exec_preserve_mode, ExecPreserveMode);
|
|||||||
DECLARE_STRING_TABLE_LOOKUP(exec_keyring_mode, ExecKeyringMode);
|
DECLARE_STRING_TABLE_LOOKUP(exec_keyring_mode, ExecKeyringMode);
|
||||||
|
|
||||||
DECLARE_STRING_TABLE_LOOKUP(exec_directory_type_symlink, ExecDirectoryType);
|
DECLARE_STRING_TABLE_LOOKUP(exec_directory_type_symlink, ExecDirectoryType);
|
||||||
|
|
||||||
DECLARE_STRING_TABLE_LOOKUP(exec_directory_type_mode, ExecDirectoryType);
|
DECLARE_STRING_TABLE_LOOKUP(exec_directory_type_mode, ExecDirectoryType);
|
||||||
|
|
||||||
DECLARE_STRING_TABLE_LOOKUP(exec_resource_type, ExecDirectoryType);
|
DECLARE_STRING_TABLE_LOOKUP(exec_resource_type, ExecDirectoryType);
|
||||||
|
|
||||||
|
DECLARE_STRING_TABLE_LOOKUP(memory_thp, MemoryTHP);
|
||||||
|
|
||||||
bool exec_needs_mount_namespace(const ExecContext *context, const ExecParameters *params, const ExecRuntime *runtime);
|
bool exec_needs_mount_namespace(const ExecContext *context, const ExecParameters *params, const ExecRuntime *runtime);
|
||||||
bool exec_needs_network_namespace(const ExecContext *context);
|
bool exec_needs_network_namespace(const ExecContext *context);
|
||||||
bool exec_needs_ipc_namespace(const ExecContext *context);
|
bool exec_needs_ipc_namespace(const ExecContext *context);
|
||||||
|
|||||||
@ -4039,15 +4039,6 @@ DEFINE_STRING_TABLE_LOOKUP(bpf_delegate_map_type, uint64_t);
|
|||||||
DEFINE_STRING_TABLE_LOOKUP(bpf_delegate_prog_type, uint64_t);
|
DEFINE_STRING_TABLE_LOOKUP(bpf_delegate_prog_type, uint64_t);
|
||||||
DEFINE_STRING_TABLE_LOOKUP(bpf_delegate_attach_type, uint64_t);
|
DEFINE_STRING_TABLE_LOOKUP(bpf_delegate_attach_type, uint64_t);
|
||||||
|
|
||||||
static const char* const memory_thp_table[_MEMORY_THP_MAX] = {
|
|
||||||
[MEMORY_THP_INHERIT] = "inherit",
|
|
||||||
[MEMORY_THP_DISABLE] = "disable",
|
|
||||||
[MEMORY_THP_MADVISE] = "madvise",
|
|
||||||
[MEMORY_THP_SYSTEM] = "system",
|
|
||||||
};
|
|
||||||
|
|
||||||
DEFINE_STRING_TABLE_LOOKUP(memory_thp, MemoryTHP);
|
|
||||||
|
|
||||||
char* bpf_delegate_to_string(uint64_t u, const char * (*parser)(uint64_t) _const_ ) {
|
char* bpf_delegate_to_string(uint64_t u, const char * (*parser)(uint64_t) _const_ ) {
|
||||||
assert(parser);
|
assert(parser);
|
||||||
|
|
||||||
|
|||||||
@ -90,24 +90,6 @@ typedef enum PrivatePIDs {
|
|||||||
_PRIVATE_PIDS_INVALID = -EINVAL,
|
_PRIVATE_PIDS_INVALID = -EINVAL,
|
||||||
} PrivatePIDs;
|
} PrivatePIDs;
|
||||||
|
|
||||||
typedef enum MemoryTHP {
|
|
||||||
/*
|
|
||||||
* Inherit default from process that starts systemd, i.e. do not make
|
|
||||||
* any PR_SET_THP_DISABLE call.
|
|
||||||
*/
|
|
||||||
MEMORY_THP_INHERIT,
|
|
||||||
MEMORY_THP_DISABLE, /* Disable THPs completely for the process */
|
|
||||||
MEMORY_THP_MADVISE, /* Disable THPs for the process except when madvised */
|
|
||||||
/*
|
|
||||||
* Use system default THP setting. this can be used when the process that
|
|
||||||
* starts systemd has already disabled THPs via PR_SET_THP_DISABLE, and we
|
|
||||||
* want to restore the system default THP setting at process invocation time.
|
|
||||||
*/
|
|
||||||
MEMORY_THP_SYSTEM,
|
|
||||||
_MEMORY_THP_MAX,
|
|
||||||
_MEMORY_THP_INVALID = -EINVAL,
|
|
||||||
} MemoryTHP;
|
|
||||||
|
|
||||||
typedef struct BindMount {
|
typedef struct BindMount {
|
||||||
char *source;
|
char *source;
|
||||||
char *destination;
|
char *destination;
|
||||||
@ -250,8 +232,6 @@ DECLARE_STRING_TABLE_LOOKUP(proc_subset, ProcSubset);
|
|||||||
|
|
||||||
DECLARE_STRING_TABLE_LOOKUP(private_bpf, PrivateBPF);
|
DECLARE_STRING_TABLE_LOOKUP(private_bpf, PrivateBPF);
|
||||||
|
|
||||||
DECLARE_STRING_TABLE_LOOKUP(memory_thp, MemoryTHP);
|
|
||||||
|
|
||||||
DECLARE_STRING_TABLE_LOOKUP(bpf_delegate_cmd, uint64_t);
|
DECLARE_STRING_TABLE_LOOKUP(bpf_delegate_cmd, uint64_t);
|
||||||
|
|
||||||
DECLARE_STRING_TABLE_LOOKUP(bpf_delegate_map_type, uint64_t);
|
DECLARE_STRING_TABLE_LOOKUP(bpf_delegate_map_type, uint64_t);
|
||||||
|
|||||||
@ -3801,7 +3801,6 @@ int unit_coldplug(Unit *u) {
|
|||||||
if (u->nop_job)
|
if (u->nop_job)
|
||||||
RET_GATHER(r, job_coldplug(u->nop_job));
|
RET_GATHER(r, job_coldplug(u->nop_job));
|
||||||
|
|
||||||
unit_modify_nft_set(u, /* add= */ true);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -865,6 +865,9 @@ int unit_exec_context_build_json(sd_json_variant **ret, const char *name, void *
|
|||||||
SD_JSON_BUILD_PAIR_CALLBACK("IOSchedulingClass", ioprio_class_build_json, c),
|
SD_JSON_BUILD_PAIR_CALLBACK("IOSchedulingClass", ioprio_class_build_json, c),
|
||||||
SD_JSON_BUILD_PAIR_INTEGER("IOSchedulingPriority", ioprio_prio_data(exec_context_get_effective_ioprio(c))),
|
SD_JSON_BUILD_PAIR_INTEGER("IOSchedulingPriority", ioprio_prio_data(exec_context_get_effective_ioprio(c))),
|
||||||
|
|
||||||
|
JSON_BUILD_PAIR_TRISTATE_NON_NULL("MemoryKSM", c->memory_ksm),
|
||||||
|
SD_JSON_BUILD_PAIR_STRING("MemoryTHP", memory_thp_to_string(c->memory_thp)),
|
||||||
|
|
||||||
/* Sandboxing */
|
/* Sandboxing */
|
||||||
SD_JSON_BUILD_PAIR_STRING("ProtectSystem", protect_system_to_string(c->protect_system)),
|
SD_JSON_BUILD_PAIR_STRING("ProtectSystem", protect_system_to_string(c->protect_system)),
|
||||||
SD_JSON_BUILD_PAIR_STRING("ProtectHome", protect_home_to_string(c->protect_home)),
|
SD_JSON_BUILD_PAIR_STRING("ProtectHome", protect_home_to_string(c->protect_home)),
|
||||||
@ -888,7 +891,6 @@ int unit_exec_context_build_json(sd_json_variant **ret, const char *name, void *
|
|||||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("NetworkNamespacePath", c->network_namespace_path),
|
JSON_BUILD_PAIR_STRING_NON_EMPTY("NetworkNamespacePath", c->network_namespace_path),
|
||||||
JSON_BUILD_PAIR_YES_NO("PrivateIPC", c->private_ipc),
|
JSON_BUILD_PAIR_YES_NO("PrivateIPC", c->private_ipc),
|
||||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("IPCNamespacePath", c->ipc_namespace_path),
|
JSON_BUILD_PAIR_STRING_NON_EMPTY("IPCNamespacePath", c->ipc_namespace_path),
|
||||||
JSON_BUILD_PAIR_TRISTATE_NON_NULL("MemoryKSM", c->memory_ksm),
|
|
||||||
SD_JSON_BUILD_PAIR_STRING("PrivatePIDs", private_pids_to_string(c->private_pids)),
|
SD_JSON_BUILD_PAIR_STRING("PrivatePIDs", private_pids_to_string(c->private_pids)),
|
||||||
SD_JSON_BUILD_PAIR_STRING("PrivateUsers", private_users_to_string(c->private_users)),
|
SD_JSON_BUILD_PAIR_STRING("PrivateUsers", private_users_to_string(c->private_users)),
|
||||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("UserNamespacePath", c->user_namespace_path),
|
JSON_BUILD_PAIR_STRING_NON_EMPTY("UserNamespacePath", c->user_namespace_path),
|
||||||
@ -914,7 +916,6 @@ int unit_exec_context_build_json(sd_json_variant **ret, const char *name, void *
|
|||||||
SD_JSON_BUILD_PAIR_BOOLEAN("RemoveIPC", c->remove_ipc),
|
SD_JSON_BUILD_PAIR_BOOLEAN("RemoveIPC", c->remove_ipc),
|
||||||
JSON_BUILD_PAIR_TRISTATE_NON_NULL("PrivateMounts", c->private_mounts),
|
JSON_BUILD_PAIR_TRISTATE_NON_NULL("PrivateMounts", c->private_mounts),
|
||||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("MountFlags", mount_propagation_flag_to_string(c->mount_propagation_flag)),
|
JSON_BUILD_PAIR_STRING_NON_EMPTY("MountFlags", mount_propagation_flag_to_string(c->mount_propagation_flag)),
|
||||||
SD_JSON_BUILD_PAIR_STRING("MemoryTHP", memory_thp_to_string(c->memory_thp)),
|
|
||||||
|
|
||||||
/* System Call Filtering */
|
/* System Call Filtering */
|
||||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("SystemCallFilter", syscall_filter_build_json, c),
|
JSON_BUILD_PAIR_CALLBACK_NON_NULL("SystemCallFilter", syscall_filter_build_json, c),
|
||||||
|
|||||||
@ -27,6 +27,7 @@
|
|||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "pkcs11-util.h"
|
#include "pkcs11-util.h"
|
||||||
#include "pretty-print.h"
|
#include "pretty-print.h"
|
||||||
|
#include "process-util.h"
|
||||||
#include "string-table.h"
|
#include "string-table.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "tpm2-pcr.h"
|
#include "tpm2-pcr.h"
|
||||||
@ -850,7 +851,7 @@ static int run(int argc, char *argv[]) {
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* A delicious drop of snake oil */
|
/* A delicious drop of snake oil */
|
||||||
(void) mlockall(MCL_CURRENT|MCL_FUTURE|MCL_ONFAULT);
|
(void) safe_mlockall(MCL_CURRENT|MCL_FUTURE|MCL_ONFAULT);
|
||||||
|
|
||||||
cryptsetup_enable_logging(NULL);
|
cryptsetup_enable_logging(NULL);
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,7 @@
|
|||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "pkcs11-util.h"
|
#include "pkcs11-util.h"
|
||||||
#include "pretty-print.h"
|
#include "pretty-print.h"
|
||||||
|
#include "process-util.h"
|
||||||
#include "random-util.h"
|
#include "random-util.h"
|
||||||
#include "string-table.h"
|
#include "string-table.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
@ -2582,7 +2583,7 @@ static int verb_attach(int argc, char *argv[], void *userdata) {
|
|||||||
volume, source, strempty(arg_type), strempty(arg_cipher));
|
volume, source, strempty(arg_type), strempty(arg_cipher));
|
||||||
|
|
||||||
/* A delicious drop of snake oil */
|
/* A delicious drop of snake oil */
|
||||||
(void) mlockall(MCL_CURRENT|MCL_FUTURE|MCL_ONFAULT);
|
(void) safe_mlockall(MCL_CURRENT|MCL_FUTURE|MCL_ONFAULT);
|
||||||
|
|
||||||
if (key_file && arg_keyfile_erase)
|
if (key_file && arg_keyfile_erase)
|
||||||
destroy_key_file = key_file; /* let's get this baby erased when we leave */
|
destroy_key_file = key_file; /* let's get this baby erased when we leave */
|
||||||
|
|||||||
@ -891,6 +891,7 @@
|
|||||||
|
|
||||||
#define ABS_VOLUME 0x20
|
#define ABS_VOLUME 0x20
|
||||||
#define ABS_PROFILE 0x21
|
#define ABS_PROFILE 0x21
|
||||||
|
#define ABS_SND_PROFILE 0x22
|
||||||
|
|
||||||
#define ABS_MISC 0x28
|
#define ABS_MISC 0x28
|
||||||
|
|
||||||
@ -1000,4 +1001,12 @@
|
|||||||
#define SND_MAX 0x07
|
#define SND_MAX 0x07
|
||||||
#define SND_CNT (SND_MAX+1)
|
#define SND_CNT (SND_MAX+1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ABS_SND_PROFILE values
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SND_PROFILE_SILENT 0x00
|
||||||
|
#define SND_PROFILE_VIBRATE 0x01
|
||||||
|
#define SND_PROFILE_RING 0x02
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -2455,6 +2455,7 @@ static const BusProperty execute_properties[] = {
|
|||||||
{ "CPUSchedulingResetOnFork", bus_append_parse_boolean },
|
{ "CPUSchedulingResetOnFork", bus_append_parse_boolean },
|
||||||
{ "LockPersonality", bus_append_parse_boolean },
|
{ "LockPersonality", bus_append_parse_boolean },
|
||||||
{ "MemoryKSM", bus_append_parse_boolean },
|
{ "MemoryKSM", bus_append_parse_boolean },
|
||||||
|
{ "MemoryTHP", bus_append_string },
|
||||||
{ "RestrictSUIDSGID", bus_append_parse_boolean },
|
{ "RestrictSUIDSGID", bus_append_parse_boolean },
|
||||||
{ "RootEphemeral", bus_append_parse_boolean },
|
{ "RootEphemeral", bus_append_parse_boolean },
|
||||||
{ "SetLoginEnvironment", bus_append_parse_boolean },
|
{ "SetLoginEnvironment", bus_append_parse_boolean },
|
||||||
@ -2494,7 +2495,6 @@ static const BusProperty execute_properties[] = {
|
|||||||
{ "LogRateLimitBurst", bus_append_safe_atou },
|
{ "LogRateLimitBurst", bus_append_safe_atou },
|
||||||
{ "TTYRows", bus_append_safe_atou },
|
{ "TTYRows", bus_append_safe_atou },
|
||||||
{ "TTYColumns", bus_append_safe_atou },
|
{ "TTYColumns", bus_append_safe_atou },
|
||||||
{ "MemoryTHP", bus_append_string },
|
|
||||||
{ "MountFlags", bus_append_mount_propagation_flag_from_string },
|
{ "MountFlags", bus_append_mount_propagation_flag_from_string },
|
||||||
{ "Environment", bus_append_strv_cunescape },
|
{ "Environment", bus_append_strv_cunescape },
|
||||||
{ "UnsetEnvironment", bus_append_strv_cunescape },
|
{ "UnsetEnvironment", bus_append_strv_cunescape },
|
||||||
|
|||||||
@ -530,6 +530,11 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
|||||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#IOSchedulingPriority="),
|
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#IOSchedulingPriority="),
|
||||||
SD_VARLINK_DEFINE_FIELD(IOSchedulingPriority, SD_VARLINK_INT, 0),
|
SD_VARLINK_DEFINE_FIELD(IOSchedulingPriority, SD_VARLINK_INT, 0),
|
||||||
|
|
||||||
|
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#MemoryKSM="),
|
||||||
|
SD_VARLINK_DEFINE_FIELD(MemoryKSM, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||||
|
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#MemoryTHP="),
|
||||||
|
SD_VARLINK_DEFINE_FIELD(MemoryTHP, SD_VARLINK_STRING, 0),
|
||||||
|
|
||||||
/* Sandboxing
|
/* Sandboxing
|
||||||
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#Sandboxing */
|
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#Sandboxing */
|
||||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ProtectSystem="),
|
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ProtectSystem="),
|
||||||
@ -574,8 +579,6 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
|||||||
SD_VARLINK_DEFINE_FIELD(PrivateIPC, SD_VARLINK_STRING, 0),
|
SD_VARLINK_DEFINE_FIELD(PrivateIPC, SD_VARLINK_STRING, 0),
|
||||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#IPCNamespacePath="),
|
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#IPCNamespacePath="),
|
||||||
SD_VARLINK_DEFINE_FIELD(IPCNamespacePath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
SD_VARLINK_DEFINE_FIELD(IPCNamespacePath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#MemoryKSM="),
|
|
||||||
SD_VARLINK_DEFINE_FIELD(MemoryKSM, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
|
||||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PrivatePIDs="),
|
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PrivatePIDs="),
|
||||||
SD_VARLINK_DEFINE_FIELD(PrivatePIDs, SD_VARLINK_STRING, 0),
|
SD_VARLINK_DEFINE_FIELD(PrivatePIDs, SD_VARLINK_STRING, 0),
|
||||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PrivateUsers="),
|
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PrivateUsers="),
|
||||||
@ -626,8 +629,6 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
|||||||
SD_VARLINK_DEFINE_FIELD(PrivateMounts, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
SD_VARLINK_DEFINE_FIELD(PrivateMounts, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#MountFlags="),
|
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#MountFlags="),
|
||||||
SD_VARLINK_DEFINE_FIELD(MountFlags, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
SD_VARLINK_DEFINE_FIELD(MountFlags, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#MemoryTHP="),
|
|
||||||
SD_VARLINK_DEFINE_FIELD(MemoryTHP, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
|
||||||
|
|
||||||
/* System Call Filtering
|
/* System Call Filtering
|
||||||
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#System%20Call%20Filtering */
|
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#System%20Call%20Filtering */
|
||||||
|
|||||||
@ -401,8 +401,8 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
init_watchdog();
|
init_watchdog();
|
||||||
|
|
||||||
/* Lock us into memory */
|
/* Lock us into memory. If the first mlockall call fails, don't attempt it again. */
|
||||||
(void) mlockall(MCL_FUTURE|MCL_ONFAULT);
|
if (safe_mlockall(MCL_FUTURE|MCL_ONFAULT) >= 0)
|
||||||
(void) mlockall(MCL_CURRENT);
|
(void) mlockall(MCL_CURRENT);
|
||||||
|
|
||||||
/* We need to make mounts private so that we can MS_MOVE in unmount_all(). Kernel does not allow
|
/* We need to make mounts private so that we can MS_MOVE in unmount_all(). Kernel does not allow
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user