mirror of
https://github.com/systemd/systemd
synced 2025-09-19 20:04:46 +02:00
Compare commits
28 Commits
b6c8f0ec91
...
bdd8728c91
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bdd8728c91 | ||
![]() |
fbbbff01fb | ||
![]() |
542552612b | ||
![]() |
9a8f2b628d | ||
![]() |
8835034df8 | ||
![]() |
625c2e10c6 | ||
![]() |
93dea63fab | ||
![]() |
7b7f0983e0 | ||
![]() |
7d4b0df9f8 | ||
![]() |
4be269563d | ||
![]() |
ffd4b38096 | ||
![]() |
9be0a94b98 | ||
![]() |
bd610b2253 | ||
![]() |
c3b1aa6d73 | ||
![]() |
134749c1d0 | ||
![]() |
3b911434d6 | ||
![]() |
6b8dcb9853 | ||
![]() |
873a70d28a | ||
![]() |
9d05015bb9 | ||
![]() |
7ebb2b3349 | ||
![]() |
69fa2b6303 | ||
![]() |
00074c31b6 | ||
![]() |
afba4d4387 | ||
![]() |
f26a805a9f | ||
![]() |
0ba1d9f6db | ||
![]() |
96deac2bf1 | ||
![]() |
fb7151a350 | ||
![]() |
be1117f712 |
@ -52,6 +52,12 @@ predicate potentiallyDangerousFunction(Function f, string message) {
|
||||
) or (
|
||||
f.getQualifiedName() = "basename" and
|
||||
message = "Call basename() is icky. Use path_extract_filename() instead."
|
||||
) or (
|
||||
f.getQualifiedName() = "setmntent" and
|
||||
message = "Libmount parser is used instead, specifically libmount_parse_fstab()."
|
||||
) or (
|
||||
f.getQualifiedName() = "getmntent" and
|
||||
message = "Libmount parser is used instead, specifically mnt_table_next_fs()."
|
||||
)
|
||||
}
|
||||
|
||||
|
5
TODO
5
TODO
@ -522,11 +522,6 @@ Features:
|
||||
|
||||
* port copy.c over to use LabelOps for all labelling.
|
||||
|
||||
* port remaining getmntent() users over to libmount. There are subtle
|
||||
differences in the parsers (see #25371 for example), and it hence makes sense
|
||||
if we stick to one set of parsers on this, not mix both. Specifically:
|
||||
systemd-fstab-generator, cryptsetup, remount-fs.
|
||||
|
||||
* get rid of compat with libidn.so.11 (retain only for libidn.so.12)
|
||||
|
||||
* get rid of compat with libbpf.so.0 (retainly only for libbpf.so.1)
|
||||
|
@ -380,6 +380,9 @@ All tools:
|
||||
default keymap directories (/usr/share/keymaps/, /usr/share/kbd/keymaps/, and
|
||||
/usr/lib/kbd/keymaps/) will be used.
|
||||
|
||||
* `$SYSTEMD_XKB_DIRECTORY=` — The directory must be absolute and normalized.
|
||||
If unset, the default XKB directory (/usr/share/X11/xkb) will be used.
|
||||
|
||||
`systemd-resolved`:
|
||||
|
||||
* `$SYSTEMD_RESOLVED_SYNTHESIZE_HOSTNAME` — if set to "0", `systemd-resolved`
|
||||
|
@ -3915,6 +3915,13 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
|
||||
<varname>LoadCredential=</varname> and <varname>LoadCredentialEncrypted=</varname> take priority over
|
||||
credentials found by <varname>ImportCredential=</varname>.</para>
|
||||
|
||||
<para>Note that if decryption or authentication of a credential picked up as result of
|
||||
<varname>ImportCredential=</varname> fails it will be skipped gracefully (a warning is generated, but
|
||||
the credential will not be made available to the invoked service). This is different for those
|
||||
configured via
|
||||
<varname>SetCredentialEncrypted=</varname>/<varname>LoadCredentialEncrypted=</varname>, where failed
|
||||
decryption/authentication will result in service failure.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -789,14 +789,20 @@ int chase_and_open(
|
||||
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
|
||||
|
||||
XOpenFlags xopen_flags = 0;
|
||||
if (FLAGS_SET(chase_flags, CHASE_MUST_BE_DIRECTORY))
|
||||
open_flags |= O_DIRECTORY;
|
||||
if (FLAGS_SET(chase_flags, CHASE_MUST_BE_REGULAR))
|
||||
xopen_flags |= XO_REGULAR;
|
||||
|
||||
if (empty_or_root(root) && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0)
|
||||
/* Shortcut this call if none of the special features of this call are requested */
|
||||
return xopenat_full(AT_FDCWD, path,
|
||||
open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
|
||||
/* xopen_flags = */ 0,
|
||||
xopen_flags,
|
||||
MODE_INVALID);
|
||||
|
||||
r = chase(path, root, CHASE_PARENT|chase_flags, &p, &path_fd);
|
||||
r = chase(path, root, (CHASE_PARENT|chase_flags)&~CHASE_MUST_BE_REGULAR, &p, &path_fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
assert(path_fd >= 0);
|
||||
@ -808,7 +814,7 @@ int chase_and_open(
|
||||
return r;
|
||||
}
|
||||
|
||||
r = xopenat_full(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags = */ 0, MODE_INVALID);
|
||||
r = xopenat_full(path_fd, strempty(fname), open_flags|O_NOFOLLOW, xopen_flags, MODE_INVALID);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -824,7 +830,7 @@ int chase_and_opendir(const char *path, const char *root, ChaseFlags chase_flags
|
||||
DIR *d;
|
||||
int r;
|
||||
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_REGULAR)));
|
||||
assert(ret_dir);
|
||||
|
||||
if (empty_or_root(root) && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) {
|
||||
@ -837,12 +843,12 @@ int chase_and_opendir(const char *path, const char *root, ChaseFlags chase_flags
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = chase(path, root, chase_flags, ret_path ? &p : NULL, &path_fd);
|
||||
r = chase(path, root, chase_flags|CHASE_MUST_BE_DIRECTORY, ret_path ? &p : NULL, &path_fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
assert(path_fd >= 0);
|
||||
|
||||
d = xopendirat(path_fd, ".", O_NOFOLLOW);
|
||||
d = xopendirat(path_fd, /* path= */ NULL, /* flags= */ 0);
|
||||
if (!d)
|
||||
return -errno;
|
||||
|
||||
@ -922,7 +928,7 @@ int chase_and_fopen_unlocked(
|
||||
int mode_flags, r;
|
||||
|
||||
assert(path);
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_PARENT)));
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_PARENT|CHASE_MUST_BE_DIRECTORY)));
|
||||
assert(open_flags);
|
||||
assert(ret_file);
|
||||
|
||||
@ -994,14 +1000,20 @@ int chase_and_openat(
|
||||
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
|
||||
|
||||
XOpenFlags xopen_flags = 0;
|
||||
if (FLAGS_SET(chase_flags, CHASE_MUST_BE_DIRECTORY))
|
||||
open_flags |= O_DIRECTORY;
|
||||
if (FLAGS_SET(chase_flags, CHASE_MUST_BE_REGULAR))
|
||||
xopen_flags |= XO_REGULAR;
|
||||
|
||||
if (dir_fd == AT_FDCWD && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0)
|
||||
/* Shortcut this call if none of the special features of this call are requested */
|
||||
return xopenat_full(dir_fd, path,
|
||||
open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
|
||||
/* xopen_flags = */ 0,
|
||||
xopen_flags,
|
||||
MODE_INVALID);
|
||||
|
||||
r = chaseat(dir_fd, path, chase_flags|CHASE_PARENT, &p, &path_fd);
|
||||
r = chaseat(dir_fd, path, (chase_flags|CHASE_PARENT)&~CHASE_MUST_BE_REGULAR, &p, &path_fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1011,7 +1023,12 @@ int chase_and_openat(
|
||||
return r;
|
||||
}
|
||||
|
||||
r = xopenat_full(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags= */ 0, MODE_INVALID);
|
||||
r = xopenat_full(
|
||||
path_fd,
|
||||
strempty(fname),
|
||||
open_flags|O_NOFOLLOW,
|
||||
xopen_flags,
|
||||
MODE_INVALID);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1027,7 +1044,7 @@ int chase_and_opendirat(int dir_fd, const char *path, ChaseFlags chase_flags, ch
|
||||
DIR *d;
|
||||
int r;
|
||||
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
|
||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_REGULAR)));
|
||||
assert(ret_dir);
|
||||
|
||||
if (dir_fd == AT_FDCWD && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) {
|
||||
@ -1045,7 +1062,7 @@ int chase_and_opendirat(int dir_fd, const char *path, ChaseFlags chase_flags, ch
|
||||
return r;
|
||||
assert(path_fd >= 0);
|
||||
|
||||
d = xopendirat(path_fd, ".", O_NOFOLLOW);
|
||||
d = xopendirat(path_fd, /* path= */ NULL, /* flags= */ 0);
|
||||
if (!d)
|
||||
return -errno;
|
||||
|
||||
|
@ -41,7 +41,7 @@ int chattr_full(
|
||||
* drivers, where the ioctl might have different effects. Notably, DRM is using the same
|
||||
* ioctl() number. */
|
||||
|
||||
if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
|
||||
if (!inode_type_can_chattr(st.st_mode))
|
||||
return -ENOTTY;
|
||||
|
||||
if (mask == 0 && !ret_previous && !ret_final)
|
||||
@ -140,7 +140,7 @@ int read_attr_fd(int fd, unsigned *ret) {
|
||||
if (fstat(fd, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
|
||||
if (!inode_type_can_chattr(st.st_mode))
|
||||
return -ENOTTY;
|
||||
|
||||
_cleanup_close_ int fd_close = -EBADF;
|
||||
@ -248,3 +248,7 @@ int set_proj_id_recursive(int fd, uint32_t proj_id) {
|
||||
set_proj_id_cb,
|
||||
UINT32_TO_PTR(proj_id));
|
||||
}
|
||||
|
||||
bool inode_type_can_chattr(mode_t mode) {
|
||||
return IN_SET(mode & S_IFMT, S_IFREG, S_IFDIR);
|
||||
}
|
||||
|
@ -63,3 +63,5 @@ int set_proj_id_recursive(int fd, uint32_t proj_id);
|
||||
static inline int chattr_secret(int fd, ChattrApplyFlags flags) {
|
||||
return chattr_full(fd, NULL, CHATTR_SECRET_FLAGS, CHATTR_SECRET_FLAGS, NULL, NULL, flags|CHATTR_FALLBACK_BITWISE);
|
||||
}
|
||||
|
||||
bool inode_type_can_chattr(mode_t mode);
|
||||
|
@ -928,17 +928,22 @@ int get_proc_field(const char *path, const char *key, char **ret) {
|
||||
}
|
||||
}
|
||||
|
||||
DIR* xopendirat(int dir_fd, const char *name, int flags) {
|
||||
DIR* xopendirat(int dir_fd, const char *path, int flags) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
|
||||
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
|
||||
assert(name);
|
||||
assert(!(flags & (O_CREAT|O_TMPFILE)));
|
||||
|
||||
if (dir_fd == AT_FDCWD && flags == 0)
|
||||
return opendir(name);
|
||||
if ((dir_fd == AT_FDCWD || path_is_absolute(path)) &&
|
||||
(flags &~ O_DIRECTORY) == 0)
|
||||
return opendir(path);
|
||||
|
||||
fd = openat(dir_fd, name, O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags);
|
||||
if (isempty(path)) {
|
||||
path = ".";
|
||||
flags |= O_NOFOLLOW;
|
||||
}
|
||||
|
||||
fd = openat(dir_fd, path, O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
|
@ -92,7 +92,7 @@ int script_get_shebang_interpreter(const char *path, char **ret);
|
||||
|
||||
int get_proc_field(const char *path, const char *key, char **ret);
|
||||
|
||||
DIR* xopendirat(int dir_fd, const char *name, int flags);
|
||||
DIR* xopendirat(int dir_fd, const char *path, int flags);
|
||||
|
||||
typedef enum XfopenFlags {
|
||||
XFOPEN_UNLOCKED = 1 << 0, /* call __fsetlocking(FSETLOCKING_BYCALLER) after opened */
|
||||
|
@ -463,7 +463,8 @@ static int maybe_decrypt_and_write_credential(
|
||||
struct load_cred_args *args,
|
||||
const char *id,
|
||||
const char *data,
|
||||
size_t size) {
|
||||
size_t size,
|
||||
bool graceful) {
|
||||
|
||||
_cleanup_(iovec_done_erase) struct iovec plaintext = {};
|
||||
size_t add;
|
||||
@ -517,8 +518,14 @@ static int maybe_decrypt_and_write_credential(
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
if (graceful) {
|
||||
log_warning_errno(r, "Unable to decrypt credential '%s', skipping.", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
data = plaintext.iov_base;
|
||||
size = plaintext.iov_len;
|
||||
@ -607,7 +614,7 @@ static int load_credential_glob(
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to read credential '%s': %m", *p);
|
||||
|
||||
r = maybe_decrypt_and_write_credential(args, fn, data, size);
|
||||
r = maybe_decrypt_and_write_credential(args, fn, data, size, /* graceful= */ true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -732,7 +739,7 @@ static int load_credential(
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to read credential '%s': %m", path);
|
||||
|
||||
return maybe_decrypt_and_write_credential(args, id, data, size);
|
||||
return maybe_decrypt_and_write_credential(args, id, data, size, /* graceful= */ true);
|
||||
}
|
||||
|
||||
static int load_cred_recurse_dir_cb(
|
||||
@ -869,10 +876,11 @@ static int acquire_credentials(
|
||||
|
||||
args.encrypted = false;
|
||||
|
||||
r = load_credential_glob(&args,
|
||||
ic,
|
||||
search_path,
|
||||
READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER);
|
||||
r = load_credential_glob(
|
||||
&args,
|
||||
ic,
|
||||
search_path,
|
||||
READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -884,10 +892,11 @@ static int acquire_credentials(
|
||||
|
||||
args.encrypted = true;
|
||||
|
||||
r = load_credential_glob(&args,
|
||||
ic,
|
||||
search_path,
|
||||
READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER|READ_FULL_FILE_UNBASE64);
|
||||
r = load_credential_glob(
|
||||
&args,
|
||||
ic,
|
||||
search_path,
|
||||
READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER|READ_FULL_FILE_UNBASE64);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -905,7 +914,7 @@ static int acquire_credentials(
|
||||
if (errno != ENOENT)
|
||||
return log_debug_errno(errno, "Failed to test if credential %s exists: %m", sc->id);
|
||||
|
||||
r = maybe_decrypt_and_write_credential(&args, sc->id, sc->data, sc->size);
|
||||
r = maybe_decrypt_and_write_credential(&args, sc->id, sc->data, sc->size, /* graceful= */ false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
@ -1411,7 +1411,7 @@ static int vl_method_decrypt(sd_varlink *link, sd_json_variant *parameters, sd_v
|
||||
|
||||
if (r == -EBADMSG)
|
||||
return sd_varlink_error(link, "io.systemd.Credentials.BadFormat", NULL);
|
||||
if (r == -EREMOTE)
|
||||
if (r == -EDESTADDRREQ)
|
||||
return sd_varlink_error(link, "io.systemd.Credentials.NameMismatch", NULL);
|
||||
if (r == -ESTALE)
|
||||
return sd_varlink_error(link, "io.systemd.Credentials.TimeMismatch", NULL);
|
||||
@ -1419,6 +1419,16 @@ static int vl_method_decrypt(sd_varlink *link, sd_json_variant *parameters, sd_v
|
||||
return sd_varlink_error(link, "io.systemd.Credentials.NoSuchUser", NULL);
|
||||
if (r == -EMEDIUMTYPE)
|
||||
return sd_varlink_error(link, "io.systemd.Credentials.BadScope", NULL);
|
||||
if (r == -EHOSTDOWN)
|
||||
return sd_varlink_error(link, "io.systemd.Credentials.CantFindPCRSignature", NULL);
|
||||
if (r == -EHWPOISON)
|
||||
return sd_varlink_error(link, "io.systemd.Credentials.NullKeyNotAllowed", NULL);
|
||||
if (r == -EREMOTE)
|
||||
return sd_varlink_error(link, "io.systemd.Credentials.KeyBelongsToOtherTPM", NULL);
|
||||
if (r == -ENOLCK)
|
||||
return sd_varlink_error(link, "io.systemd.Credentials.TPMInDictionaryLockout", NULL);
|
||||
if (IN_SET(r, -EREMCHG, -ENOANO, -EUCLEAN, -EPERM))
|
||||
return sd_varlink_error(link, "io.systemd.Credentials.UnexpectedPCRState", NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1433,6 +1443,38 @@ static int vl_method_decrypt(sd_varlink *link, sd_json_variant *parameters, sd_v
|
||||
return sd_varlink_reply(link, reply);
|
||||
}
|
||||
|
||||
static int vl_server(void) {
|
||||
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *varlink_server = NULL;
|
||||
_cleanup_hashmap_free_ Hashmap *polkit_registry = NULL;
|
||||
int r;
|
||||
|
||||
/* Invocation as Varlink service */
|
||||
|
||||
r = varlink_server_new(
|
||||
&varlink_server,
|
||||
SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA|SD_VARLINK_SERVER_INPUT_SENSITIVE,
|
||||
&polkit_registry);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate Varlink server: %m");
|
||||
|
||||
r = sd_varlink_server_add_interface(varlink_server, &vl_interface_io_systemd_Credentials);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add Varlink interface: %m");
|
||||
|
||||
r = sd_varlink_server_bind_method_many(
|
||||
varlink_server,
|
||||
"io.systemd.Credentials.Encrypt", vl_method_encrypt,
|
||||
"io.systemd.Credentials.Decrypt", vl_method_decrypt);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind Varlink methods: %m");
|
||||
|
||||
r = sd_varlink_server_loop_auto(varlink_server);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to run Varlink event loop: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
int r;
|
||||
|
||||
@ -1442,38 +1484,8 @@ static int run(int argc, char *argv[]) {
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (arg_varlink) {
|
||||
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *varlink_server = NULL;
|
||||
_cleanup_hashmap_free_ Hashmap *polkit_registry = NULL;
|
||||
|
||||
/* Invocation as Varlink service */
|
||||
|
||||
r = varlink_server_new(
|
||||
&varlink_server,
|
||||
SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA|SD_VARLINK_SERVER_INPUT_SENSITIVE,
|
||||
NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate Varlink server: %m");
|
||||
|
||||
r = sd_varlink_server_add_interface(varlink_server, &vl_interface_io_systemd_Credentials);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add Varlink interface: %m");
|
||||
|
||||
r = sd_varlink_server_bind_method_many(
|
||||
varlink_server,
|
||||
"io.systemd.Credentials.Encrypt", vl_method_encrypt,
|
||||
"io.systemd.Credentials.Decrypt", vl_method_decrypt);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind Varlink methods: %m");
|
||||
|
||||
sd_varlink_server_set_userdata(varlink_server, &polkit_registry);
|
||||
|
||||
r = sd_varlink_server_loop_auto(varlink_server);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to run Varlink event loop: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (arg_varlink)
|
||||
return vl_server();
|
||||
|
||||
return creds_main(argc, argv);
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <mntent.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
@ -33,6 +32,7 @@
|
||||
#include "hexdecoct.h"
|
||||
#include "json-util.h"
|
||||
#include "libfido2-util.h"
|
||||
#include "libmount-util.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "memory-util.h"
|
||||
@ -732,26 +732,37 @@ static char* disk_description(const char *path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *disk_mount_point(const char *label) {
|
||||
static char* disk_mount_point(const char *label) {
|
||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
||||
_cleanup_free_ char *device = NULL;
|
||||
_cleanup_endmntent_ FILE *f = NULL;
|
||||
struct mntent *m;
|
||||
int r;
|
||||
|
||||
/* Yeah, we don't support native systemd unit files here for now */
|
||||
|
||||
assert(label);
|
||||
|
||||
device = strjoin("/dev/mapper/", label);
|
||||
if (!device)
|
||||
return NULL;
|
||||
|
||||
f = setmntent(fstab_path(), "re");
|
||||
if (!f)
|
||||
r = libmount_parse_fstab(&table, &iter);
|
||||
if (r < 0)
|
||||
return NULL;
|
||||
|
||||
while ((m = getmntent(f)))
|
||||
if (path_equal(m->mnt_fsname, device))
|
||||
return strdup(m->mnt_dir);
|
||||
for (;;) {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
return NULL;
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r != 0)
|
||||
return NULL;
|
||||
|
||||
if (path_equal(mnt_fs_get_source(fs), device)) {
|
||||
const char *target = mnt_fs_get_target(fs);
|
||||
if (target)
|
||||
return strdup(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *friendly_disk_name(const char *src, const char *vol) {
|
||||
|
@ -19,6 +19,7 @@ executables += [
|
||||
'sources' : systemd_cryptsetup_sources,
|
||||
'dependencies' : [
|
||||
libcryptsetup,
|
||||
libmount,
|
||||
libopenssl,
|
||||
libp11kit_cflags,
|
||||
],
|
||||
|
@ -24,10 +24,10 @@
|
||||
#include "generator.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "initrd-util.h"
|
||||
#include "libmount-util.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "mount-setup.h"
|
||||
#include "mount-util.h"
|
||||
#include "mountpoint-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
@ -1025,9 +1025,9 @@ static int parse_fstab_one(
|
||||
}
|
||||
|
||||
static int parse_fstab(bool prefix_sysroot) {
|
||||
_cleanup_endmntent_ FILE *f = NULL;
|
||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
||||
const char *fstab;
|
||||
struct mntent *me;
|
||||
int r, ret = 0;
|
||||
|
||||
if (prefix_sysroot)
|
||||
@ -1039,27 +1039,31 @@ static int parse_fstab(bool prefix_sysroot) {
|
||||
|
||||
log_debug("Parsing %s...", fstab);
|
||||
|
||||
f = setmntent(fstab, "re");
|
||||
if (!f) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
r = libmount_parse_full(fstab, /* source = */ NULL, &table, &iter);
|
||||
if (r == -ENOENT)
|
||||
return 0;
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse '%s': %m", fstab);
|
||||
|
||||
return log_error_errno(errno, "Failed to open %s: %m", fstab);
|
||||
}
|
||||
for (;;) {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get next entry from '%s': %m", fstab);
|
||||
if (r > 0) /* EOF */
|
||||
return ret;
|
||||
|
||||
while ((me = getmntent(f))) {
|
||||
r = parse_fstab_one(fstab,
|
||||
me->mnt_fsname, me->mnt_dir, me->mnt_type, me->mnt_opts, me->mnt_passno,
|
||||
mnt_fs_get_source(fs), mnt_fs_get_target(fs),
|
||||
mnt_fs_get_fstype(fs), mnt_fs_get_options(fs), mnt_fs_get_passno(fs),
|
||||
prefix_sysroot,
|
||||
/* accept_root = */ false,
|
||||
/* use_swap_enabled = */ true);
|
||||
if (r < 0 && ret >= 0)
|
||||
ret = r;
|
||||
if (arg_sysroot_check && r > 0)
|
||||
return true; /* We found a mount or swap that would be started… */
|
||||
RET_GATHER(ret, r);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mount_source_is_nfsroot(const char *what) {
|
||||
@ -1414,15 +1418,15 @@ static int add_mounts_from_cmdline(void) {
|
||||
|
||||
static int add_mounts_from_creds(bool prefix_sysroot) {
|
||||
_cleanup_free_ void *b = NULL;
|
||||
struct mntent *me;
|
||||
size_t bs;
|
||||
int r;
|
||||
const char *cred;
|
||||
int r, ret = 0;
|
||||
|
||||
assert(in_initrd() || !prefix_sysroot);
|
||||
|
||||
r = read_credential_with_decryption(
|
||||
in_initrd() && !prefix_sysroot ? "fstab.extra.initrd" : "fstab.extra",
|
||||
&b, &bs);
|
||||
cred = in_initrd() && !prefix_sysroot ? "fstab.extra.initrd" : "fstab.extra";
|
||||
|
||||
r = read_credential_with_decryption(cred, &b, &bs);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -1431,20 +1435,29 @@ static int add_mounts_from_creds(bool prefix_sysroot) {
|
||||
if (!f)
|
||||
return log_oom();
|
||||
|
||||
r = 0;
|
||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
||||
|
||||
while ((me = getmntent(f)))
|
||||
RET_GATHER(r, parse_fstab_one("/run/credentials",
|
||||
me->mnt_fsname,
|
||||
me->mnt_dir,
|
||||
me->mnt_type,
|
||||
me->mnt_opts,
|
||||
me->mnt_passno,
|
||||
/* prefix_sysroot = */ prefix_sysroot,
|
||||
/* accept_root = */ true,
|
||||
/* use_swap_enabled = */ true));
|
||||
r = libmount_parse_full(cred, f, &table, &iter);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse credential '%s' (as fstab): %m", cred);
|
||||
|
||||
return r;
|
||||
for (;;) {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get next fstab entry from credential '%s': %m", cred);
|
||||
if (r > 0) /* EOF */
|
||||
return ret;
|
||||
|
||||
RET_GATHER(ret, parse_fstab_one("/run/credentials",
|
||||
mnt_fs_get_source(fs), mnt_fs_get_target(fs),
|
||||
mnt_fs_get_fstype(fs), mnt_fs_get_options(fs), mnt_fs_get_passno(fs),
|
||||
prefix_sysroot,
|
||||
/* accept_root = */ true,
|
||||
/* use_swap_enabled = */ true));
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
|
||||
|
@ -4,6 +4,7 @@ executables += [
|
||||
generator_template + {
|
||||
'name' : 'systemd-fstab-generator',
|
||||
'sources' : files('fstab-generator.c'),
|
||||
'dependencies' : libmount,
|
||||
},
|
||||
]
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "format-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "import-common.h"
|
||||
#include "log.h"
|
||||
#include "pretty-print.h"
|
||||
#include "ratelimit.h"
|
||||
@ -20,8 +21,6 @@
|
||||
#include "time-util.h"
|
||||
#include "tmpfile-util.h"
|
||||
|
||||
#define COPY_BUFFER_SIZE (16*1024)
|
||||
|
||||
typedef struct RawExport {
|
||||
sd_event *event;
|
||||
|
||||
@ -161,7 +160,7 @@ static int raw_export_process(RawExport *e) {
|
||||
|
||||
if (!e->tried_sendfile && e->compress.type == IMPORT_COMPRESS_UNCOMPRESSED) {
|
||||
|
||||
l = sendfile(e->output_fd, e->input_fd, NULL, COPY_BUFFER_SIZE);
|
||||
l = sendfile(e->output_fd, e->input_fd, NULL, IMPORT_BUFFER_SIZE);
|
||||
if (l < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return 0;
|
||||
@ -181,7 +180,7 @@ static int raw_export_process(RawExport *e) {
|
||||
}
|
||||
|
||||
while (e->buffer_size <= 0) {
|
||||
uint8_t input[COPY_BUFFER_SIZE];
|
||||
uint8_t input[IMPORT_BUFFER_SIZE];
|
||||
|
||||
if (e->eof) {
|
||||
r = 0;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "format-util.h"
|
||||
#include "import-common.h"
|
||||
#include "log.h"
|
||||
#include "pidref.h"
|
||||
#include "pretty-print.h"
|
||||
#include "process-util.h"
|
||||
#include "ratelimit.h"
|
||||
@ -20,8 +21,6 @@
|
||||
#include "time-util.h"
|
||||
#include "tmpfile-util.h"
|
||||
|
||||
#define COPY_BUFFER_SIZE (16*1024)
|
||||
|
||||
typedef struct TarExport {
|
||||
sd_event *event;
|
||||
|
||||
@ -45,7 +44,7 @@ typedef struct TarExport {
|
||||
uint64_t written_compressed;
|
||||
uint64_t written_uncompressed;
|
||||
|
||||
pid_t tar_pid;
|
||||
PidRef tar_pid;
|
||||
|
||||
struct stat st;
|
||||
uint64_t quota_referenced;
|
||||
@ -63,8 +62,7 @@ TarExport *tar_export_unref(TarExport *e) {
|
||||
|
||||
sd_event_source_unref(e->output_event_source);
|
||||
|
||||
if (e->tar_pid > 1)
|
||||
sigkill_wait(e->tar_pid);
|
||||
pidref_done_sigkill_wait(&e->tar_pid);
|
||||
|
||||
if (e->temp_path) {
|
||||
(void) btrfs_subvol_remove(e->temp_path, BTRFS_REMOVE_QUOTA);
|
||||
@ -105,6 +103,7 @@ int tar_export_new(
|
||||
.quota_referenced = UINT64_MAX,
|
||||
.last_percent = UINT_MAX,
|
||||
.progress_ratelimit = { 100 * USEC_PER_MSEC, 1 },
|
||||
.tar_pid = PIDREF_NULL,
|
||||
};
|
||||
|
||||
if (event)
|
||||
@ -160,10 +159,13 @@ static int tar_export_finish(TarExport *e) {
|
||||
assert(e);
|
||||
assert(e->tar_fd >= 0);
|
||||
|
||||
if (e->tar_pid > 0) {
|
||||
r = wait_for_terminate_and_check("tar", TAKE_PID(e->tar_pid), WAIT_LOG);
|
||||
if (pidref_is_set(&e->tar_pid)) {
|
||||
r = pidref_wait_for_terminate_and_check("tar", &e->tar_pid, WAIT_LOG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
pidref_done(&e->tar_pid);
|
||||
|
||||
if (r != EXIT_SUCCESS)
|
||||
return -EPROTO;
|
||||
}
|
||||
@ -181,7 +183,7 @@ static int tar_export_process(TarExport *e) {
|
||||
|
||||
if (!e->tried_splice && e->compress.type == IMPORT_COMPRESS_UNCOMPRESSED) {
|
||||
|
||||
l = splice(e->tar_fd, NULL, e->output_fd, NULL, COPY_BUFFER_SIZE, 0);
|
||||
l = splice(e->tar_fd, NULL, e->output_fd, NULL, IMPORT_BUFFER_SIZE, 0);
|
||||
if (l < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return 0;
|
||||
@ -201,7 +203,7 @@ static int tar_export_process(TarExport *e) {
|
||||
}
|
||||
|
||||
while (e->buffer_size <= 0) {
|
||||
uint8_t input[COPY_BUFFER_SIZE];
|
||||
uint8_t input[IMPORT_BUFFER_SIZE];
|
||||
|
||||
if (e->eof) {
|
||||
r = tar_export_finish(e);
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "runtime-scope.h"
|
||||
#include "signal-util.h"
|
||||
#include "string-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "verbs.h"
|
||||
|
||||
static ImportCompressType arg_compress = IMPORT_COMPRESS_UNKNOWN;
|
||||
@ -93,6 +94,9 @@ static int export_tar(int argc, char *argv[], void *userdata) {
|
||||
} else {
|
||||
_cleanup_free_ char *pretty = NULL;
|
||||
|
||||
if (isatty_safe(STDOUT_FILENO))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EBADF), "Refusing to write archive to TTY.");
|
||||
|
||||
fd = STDOUT_FILENO;
|
||||
|
||||
(void) fd_get_path(fd, &pretty);
|
||||
|
@ -15,15 +15,16 @@
|
||||
#include "import-common.h"
|
||||
#include "log.h"
|
||||
#include "os-util.h"
|
||||
#include "pidref.h"
|
||||
#include "process-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "tmpfile-util.h"
|
||||
|
||||
int import_fork_tar_x(const char *path, pid_t *ret) {
|
||||
int import_fork_tar_x(const char *path, PidRef *ret) {
|
||||
_cleanup_(pidref_done) PidRef pid = PIDREF_NULL;
|
||||
_cleanup_close_pair_ int pipefd[2] = EBADF_PAIR;
|
||||
bool use_selinux;
|
||||
pid_t pid;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
@ -32,12 +33,16 @@ int import_fork_tar_x(const char *path, pid_t *ret) {
|
||||
if (pipe2(pipefd, O_CLOEXEC) < 0)
|
||||
return log_error_errno(errno, "Failed to create pipe for tar: %m");
|
||||
|
||||
(void) fcntl(pipefd[0], F_SETPIPE_SZ, IMPORT_BUFFER_SIZE);
|
||||
|
||||
use_selinux = mac_selinux_use();
|
||||
|
||||
r = safe_fork_full("(tar)",
|
||||
(int[]) { pipefd[0], -EBADF, STDERR_FILENO },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
|
||||
r = pidref_safe_fork_full(
|
||||
"(tar)",
|
||||
(int[]) { pipefd[0], -EBADF, STDERR_FILENO },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG,
|
||||
&pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
@ -84,15 +89,15 @@ int import_fork_tar_x(const char *path, pid_t *ret) {
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
*ret = pid;
|
||||
*ret = TAKE_PIDREF(pid);
|
||||
|
||||
return TAKE_FD(pipefd[1]);
|
||||
}
|
||||
|
||||
int import_fork_tar_c(const char *path, pid_t *ret) {
|
||||
int import_fork_tar_c(const char *path, PidRef *ret) {
|
||||
_cleanup_close_pair_ int pipefd[2] = EBADF_PAIR;
|
||||
_cleanup_(pidref_done) PidRef pid = PIDREF_NULL;
|
||||
bool use_selinux;
|
||||
pid_t pid;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
@ -101,12 +106,16 @@ int import_fork_tar_c(const char *path, pid_t *ret) {
|
||||
if (pipe2(pipefd, O_CLOEXEC) < 0)
|
||||
return log_error_errno(errno, "Failed to create pipe for tar: %m");
|
||||
|
||||
(void) fcntl(pipefd[0], F_SETPIPE_SZ, IMPORT_BUFFER_SIZE);
|
||||
|
||||
use_selinux = mac_selinux_use();
|
||||
|
||||
r = safe_fork_full("(tar)",
|
||||
(int[]) { -EBADF, pipefd[1], STDERR_FILENO },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
|
||||
r = pidref_safe_fork_full(
|
||||
"(tar)",
|
||||
(int[]) { -EBADF, pipefd[1], STDERR_FILENO },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG,
|
||||
&pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
@ -139,7 +148,7 @@ int import_fork_tar_c(const char *path, pid_t *ret) {
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
*ret = pid;
|
||||
*ret = TAKE_PIDREF(pid);
|
||||
|
||||
return TAKE_FD(pipefd[0]);
|
||||
}
|
||||
|
@ -33,11 +33,13 @@ typedef enum ImportFlags {
|
||||
_IMPORT_FLAGS_INVALID = -EINVAL,
|
||||
} ImportFlags;
|
||||
|
||||
int import_fork_tar_c(const char *path, pid_t *ret);
|
||||
int import_fork_tar_x(const char *path, pid_t *ret);
|
||||
int import_fork_tar_c(const char *path, PidRef *ret);
|
||||
int import_fork_tar_x(const char *path, PidRef *ret);
|
||||
|
||||
int import_mangle_os_tree(const char *path);
|
||||
|
||||
bool import_validate_local(const char *name, ImportFlags flags);
|
||||
|
||||
int import_allocate_event_with_signals(sd_event **ret);
|
||||
|
||||
#define IMPORT_BUFFER_SIZE (128U*1024U)
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "import-common.h"
|
||||
#include "import-compress.h"
|
||||
#include "log.h"
|
||||
#include "string-table.h"
|
||||
@ -148,7 +149,7 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo
|
||||
c->xz.avail_in = size;
|
||||
|
||||
while (c->xz.avail_in > 0) {
|
||||
uint8_t buffer[16 * 1024];
|
||||
uint8_t buffer[IMPORT_BUFFER_SIZE];
|
||||
lzma_ret lzr;
|
||||
|
||||
c->xz.next_out = buffer;
|
||||
@ -172,7 +173,7 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo
|
||||
c->gzip.avail_in = size;
|
||||
|
||||
while (c->gzip.avail_in > 0) {
|
||||
uint8_t buffer[16 * 1024];
|
||||
uint8_t buffer[IMPORT_BUFFER_SIZE];
|
||||
|
||||
c->gzip.next_out = buffer;
|
||||
c->gzip.avail_out = sizeof(buffer);
|
||||
@ -196,7 +197,7 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo
|
||||
c->bzip2.avail_in = size;
|
||||
|
||||
while (c->bzip2.avail_in > 0) {
|
||||
uint8_t buffer[16 * 1024];
|
||||
uint8_t buffer[IMPORT_BUFFER_SIZE];
|
||||
|
||||
c->bzip2.next_out = (char*) buffer;
|
||||
c->bzip2.avail_out = sizeof(buffer);
|
||||
@ -222,7 +223,7 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo
|
||||
};
|
||||
|
||||
while (input.pos < input.size) {
|
||||
uint8_t buffer[16 * 1024];
|
||||
uint8_t buffer[IMPORT_BUFFER_SIZE];
|
||||
ZSTD_outBuffer output = {
|
||||
.dst = buffer,
|
||||
.size = sizeof(buffer),
|
||||
@ -320,7 +321,7 @@ static int enlarge_buffer(void **buffer, size_t *buffer_size, size_t *buffer_all
|
||||
if (*buffer_allocated > *buffer_size)
|
||||
return 0;
|
||||
|
||||
l = MAX(16*1024U, (*buffer_size * 2));
|
||||
l = MAX(IMPORT_BUFFER_SIZE, (*buffer_size * 2));
|
||||
p = realloc(*buffer, l);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
@ -47,7 +47,7 @@ typedef struct RawImport {
|
||||
|
||||
sd_event_source *input_event_source;
|
||||
|
||||
uint8_t buffer[16*1024];
|
||||
uint8_t buffer[IMPORT_BUFFER_SIZE];
|
||||
size_t buffer_size;
|
||||
|
||||
uint64_t written_compressed;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "log.h"
|
||||
#include "mkdir-label.h"
|
||||
#include "path-util.h"
|
||||
#include "pidref.h"
|
||||
#include "pretty-print.h"
|
||||
#include "process-util.h"
|
||||
#include "ratelimit.h"
|
||||
@ -49,7 +50,7 @@ typedef struct TarImport {
|
||||
|
||||
sd_event_source *input_event_source;
|
||||
|
||||
uint8_t buffer[16*1024];
|
||||
uint8_t buffer[IMPORT_BUFFER_SIZE];
|
||||
size_t buffer_size;
|
||||
|
||||
uint64_t written_compressed;
|
||||
@ -57,7 +58,7 @@ typedef struct TarImport {
|
||||
|
||||
struct stat input_stat;
|
||||
|
||||
pid_t tar_pid;
|
||||
PidRef tar_pid;
|
||||
|
||||
unsigned last_percent;
|
||||
RateLimit progress_ratelimit;
|
||||
@ -69,8 +70,7 @@ TarImport* tar_import_unref(TarImport *i) {
|
||||
|
||||
sd_event_source_unref(i->input_event_source);
|
||||
|
||||
if (i->tar_pid > 1)
|
||||
sigkill_wait(i->tar_pid);
|
||||
pidref_done_sigkill_wait(&i->tar_pid);
|
||||
|
||||
rm_rf_subvolume_and_free(i->temp_path);
|
||||
|
||||
@ -116,6 +116,7 @@ int tar_import_new(
|
||||
.last_percent = UINT_MAX,
|
||||
.image_root = TAKE_PTR(root),
|
||||
.progress_ratelimit = { 100 * USEC_PER_MSEC, 1 },
|
||||
.tar_pid = PIDREF_NULL,
|
||||
};
|
||||
|
||||
if (event)
|
||||
@ -174,10 +175,13 @@ static int tar_import_finish(TarImport *i) {
|
||||
|
||||
i->tar_fd = safe_close(i->tar_fd);
|
||||
|
||||
if (i->tar_pid > 0) {
|
||||
r = wait_for_terminate_and_check("tar", TAKE_PID(i->tar_pid), WAIT_LOG);
|
||||
if (pidref_is_set(&i->tar_pid)) {
|
||||
r = pidref_wait_for_terminate_and_check("tar", &i->tar_pid, WAIT_LOG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
pidref_done(&i->tar_pid);
|
||||
|
||||
if (r != EXIT_SUCCESS)
|
||||
return -EPROTO;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "log.h"
|
||||
#include "mkdir-label.h"
|
||||
#include "path-util.h"
|
||||
#include "pidref.h"
|
||||
#include "process-util.h"
|
||||
#include "pull-common.h"
|
||||
#include "pull-job.h"
|
||||
@ -51,7 +52,7 @@ typedef struct TarPull {
|
||||
|
||||
char *local;
|
||||
|
||||
pid_t tar_pid;
|
||||
PidRef tar_pid;
|
||||
|
||||
char *final_path;
|
||||
char *temp_path;
|
||||
@ -66,8 +67,7 @@ TarPull* tar_pull_unref(TarPull *i) {
|
||||
if (!i)
|
||||
return NULL;
|
||||
|
||||
if (i->tar_pid > 1)
|
||||
sigkill_wait(i->tar_pid);
|
||||
pidref_done_sigkill_wait(&i->tar_pid);
|
||||
|
||||
pull_job_unref(i->tar_job);
|
||||
pull_job_unref(i->checksum_job);
|
||||
@ -131,6 +131,7 @@ int tar_pull_new(
|
||||
.image_root = TAKE_PTR(root),
|
||||
.event = TAKE_PTR(e),
|
||||
.glue = TAKE_PTR(g),
|
||||
.tar_pid = PIDREF_NULL,
|
||||
};
|
||||
|
||||
i->glue->on_finished = pull_job_curl_on_finished;
|
||||
@ -377,10 +378,11 @@ static void tar_pull_job_on_finished(PullJob *j) {
|
||||
pull_job_close_disk_fd(i->tar_job);
|
||||
pull_job_close_disk_fd(i->settings_job);
|
||||
|
||||
if (i->tar_pid > 0) {
|
||||
r = wait_for_terminate_and_check("tar", TAKE_PID(i->tar_pid), WAIT_LOG);
|
||||
if (pidref_is_set(&i->tar_pid)) {
|
||||
r = pidref_wait_for_terminate_and_check("tar", &i->tar_pid, WAIT_LOG);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
pidref_done(&i->tar_pid);
|
||||
if (r != EXIT_SUCCESS) {
|
||||
r = -EIO;
|
||||
goto finish;
|
||||
@ -509,7 +511,7 @@ static int tar_pull_job_on_open_disk_tar(PullJob *j) {
|
||||
|
||||
i = j->userdata;
|
||||
assert(i->tar_job == j);
|
||||
assert(i->tar_pid <= 0);
|
||||
assert(!pidref_is_set(&i->tar_pid));
|
||||
|
||||
if (i->flags & IMPORT_DIRECT)
|
||||
where = i->local;
|
||||
|
@ -136,7 +136,6 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
||||
}
|
||||
|
||||
int id128_get_machine_at(int rfd, sd_id128_t *ret) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||
@ -147,7 +146,8 @@ int id128_get_machine_at(int rfd, sd_id128_t *ret) {
|
||||
if (r > 0)
|
||||
return sd_id128_get_machine(ret);
|
||||
|
||||
fd = chase_and_openat(rfd, "/etc/machine-id", CHASE_AT_RESOLVE_IN_ROOT, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL);
|
||||
_cleanup_close_ int fd =
|
||||
chase_and_openat(rfd, "/etc/machine-id", CHASE_AT_RESOLVE_IN_ROOT|CHASE_MUST_BE_REGULAR, O_RDONLY|O_CLOEXEC|O_NOCTTY, /* ret_path= */ NULL);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
@ -155,12 +155,11 @@ int id128_get_machine_at(int rfd, sd_id128_t *ret) {
|
||||
}
|
||||
|
||||
int id128_get_machine(const char *root, sd_id128_t *ret) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
|
||||
if (empty_or_root(root))
|
||||
return sd_id128_get_machine(ret);
|
||||
|
||||
fd = chase_and_open("/etc/machine-id", root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL);
|
||||
_cleanup_close_ int fd =
|
||||
chase_and_open("/etc/machine-id", root, CHASE_PREFIX_ROOT|CHASE_MUST_BE_REGULAR, O_RDONLY|O_CLOEXEC|O_NOCTTY, /* ret_path= */ NULL);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "memory-util.h"
|
||||
#include "pager.h"
|
||||
#include "parse-argument.h"
|
||||
#include "path-util.h"
|
||||
#include "polkit-agent.h"
|
||||
#include "pretty-print.h"
|
||||
#include "runtime-scope.h"
|
||||
@ -290,6 +291,14 @@ static int set_x11_keymap(int argc, char **argv, void *userdata) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* xkb_directory(void) {
|
||||
static const char *cached = NULL;
|
||||
|
||||
if (!cached)
|
||||
cached = secure_getenv("SYSTEMD_XKB_DIRECTORY") ?: "/usr/share/X11/xkb";
|
||||
return cached;
|
||||
}
|
||||
|
||||
static int list_x11_keymaps(int argc, char **argv, void *userdata) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
_cleanup_strv_free_ char **list = NULL;
|
||||
@ -302,9 +311,15 @@ static int list_x11_keymaps(int argc, char **argv, void *userdata) {
|
||||
} state = NONE, look_for;
|
||||
int r;
|
||||
|
||||
f = fopen("/usr/share/X11/xkb/rules/base.lst", "re");
|
||||
_cleanup_free_ char *xkb_base = path_join(xkb_directory(), "rules/base.lst");
|
||||
if (!xkb_base)
|
||||
return log_oom();
|
||||
|
||||
f = fopen(xkb_base, "re");
|
||||
if (!f)
|
||||
return log_error_errno(errno, "Failed to open keyboard mapping list: %m");
|
||||
return log_error_errno(errno,
|
||||
"Failed to open keyboard mapping list %s: %m",
|
||||
xkb_base);
|
||||
|
||||
if (streq(argv[0], "list-x11-keymap-models"))
|
||||
look_for = MODELS;
|
||||
@ -323,7 +338,9 @@ static int list_x11_keymaps(int argc, char **argv, void *userdata) {
|
||||
|
||||
r = read_stripped_line(f, LONG_LINE_MAX, &line);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read keyboard mapping list: %m");
|
||||
return log_error_errno(r,
|
||||
"Failed to read keyboard mapping list %s: %m",
|
||||
xkb_base);
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
@ -377,7 +394,8 @@ static int list_x11_keymaps(int argc, char **argv, void *userdata) {
|
||||
|
||||
if (strv_isempty(list))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
|
||||
"Couldn't find any entries.");
|
||||
"Couldn't find any entries in keyboard mapping list %s.",
|
||||
xkb_base);
|
||||
|
||||
strv_sort_uniq(list);
|
||||
|
||||
|
@ -4,5 +4,6 @@ executables += [
|
||||
libexec_template + {
|
||||
'name' : 'systemd-remount-fs',
|
||||
'sources' : files('remount-fs.c'),
|
||||
'dependencies' : libmount,
|
||||
},
|
||||
]
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <mntent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
@ -11,6 +10,7 @@
|
||||
#include "format-util.h"
|
||||
#include "fstab-util.h"
|
||||
#include "hashmap.h"
|
||||
#include "libmount-util.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "mount-setup.h"
|
||||
@ -35,10 +35,8 @@ static int track_pid(Hashmap **h, const char *path, pid_t pid) {
|
||||
return log_oom();
|
||||
|
||||
r = hashmap_ensure_put(h, &trivial_hash_ops_value_free, PID_TO_PTR(pid), c);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to store pid " PID_FMT, pid);
|
||||
return log_error_errno(r, "Failed to store pid " PID_FMT " for mount '%s': %m", pid, path);
|
||||
|
||||
TAKE_PTR(c);
|
||||
return 0;
|
||||
@ -48,6 +46,8 @@ static int do_remount(const char *path, bool force_rw, Hashmap **pids) {
|
||||
pid_t pid;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
|
||||
log_debug("Remounting %s...", path);
|
||||
|
||||
r = safe_fork(force_rw ? "(remount-rw)" : "(remount)",
|
||||
@ -70,10 +70,10 @@ static int do_remount(const char *path, bool force_rw, Hashmap **pids) {
|
||||
}
|
||||
|
||||
static int remount_by_fstab(Hashmap **ret_pids) {
|
||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
||||
_cleanup_hashmap_free_ Hashmap *pids = NULL;
|
||||
_cleanup_endmntent_ FILE *f = NULL;
|
||||
bool has_root = false;
|
||||
struct mntent* me;
|
||||
int r;
|
||||
|
||||
assert(ret_pids);
|
||||
@ -81,24 +81,33 @@ static int remount_by_fstab(Hashmap **ret_pids) {
|
||||
if (!fstab_enabled())
|
||||
return 0;
|
||||
|
||||
f = setmntent(fstab_path(), "re");
|
||||
if (!f) {
|
||||
if (errno != ENOENT)
|
||||
return log_error_errno(errno, "Failed to open %s: %m", fstab_path());
|
||||
|
||||
r = libmount_parse_fstab(&table, &iter);
|
||||
if (r == -ENOENT)
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse fstab: %m");
|
||||
|
||||
while ((me = getmntent(f))) {
|
||||
/* Remount the root fs, /usr, and all API VFSs */
|
||||
if (!mount_point_is_api(me->mnt_dir) &&
|
||||
!PATH_IN_SET(me->mnt_dir, "/", "/usr"))
|
||||
for (;;) {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get next entry from fstab: %m");
|
||||
if (r > 0) /* EOF */
|
||||
break;
|
||||
|
||||
const char *target = mnt_fs_get_target(fs);
|
||||
if (!target)
|
||||
continue;
|
||||
|
||||
if (path_equal(me->mnt_dir, "/"))
|
||||
has_root = true;
|
||||
/* Remount the root fs, /usr/, and all API VFSs */
|
||||
|
||||
r = do_remount(me->mnt_dir, false, &pids);
|
||||
if (path_equal(target, "/"))
|
||||
has_root = true;
|
||||
else if (!path_equal(target, "/usr") && !mount_point_is_api(target))
|
||||
continue;
|
||||
|
||||
r = do_remount(target, /* force_rw = */ false, &pids);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -132,7 +141,7 @@ static int run(int argc, char *argv[]) {
|
||||
log_warning_errno(r, "Failed to parse $SYSTEMD_REMOUNT_ROOT_RW, ignoring: %m");
|
||||
|
||||
if (r > 0) {
|
||||
r = do_remount("/", true, &pids);
|
||||
r = do_remount("/", /* force_rw = */ true, &pids);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
@ -648,3 +648,7 @@ int fd_acl_make_writable_fallback(int fd) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int inode_type_can_acl(mode_t mode) {
|
||||
return IN_SET(mode & S_IFMT, S_IFSOCK, S_IFREG, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO);
|
||||
}
|
||||
|
@ -53,3 +53,5 @@ static inline int fd_acl_make_writable(int fd) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int inode_type_can_acl(mode_t mode);
|
||||
|
@ -1201,6 +1201,19 @@ int decrypt_credential_and_warn(
|
||||
assert(iovec_is_valid(input));
|
||||
assert(ret);
|
||||
|
||||
/* Relevant error codes:
|
||||
*
|
||||
* -EBADMSG → Corrupted file
|
||||
* -EOPNOTSUPP → Unsupported file type (could be: requires TPM but we have no TPM)
|
||||
* -EHOSTDOWN → Need PCR signature file, but couldn't find it
|
||||
* -EHWPOISON → Attempt to decode NULL key (and CREDENTIAL_ALLOW_NULL is off), but the system has a TPM and SecureBoot is on
|
||||
* -EMEDIUMTYPE → File has unexpected scope, i.e. user-scoped credential is attempted to be unlocked in system scope, or vice versa
|
||||
* -EDESTADDRREQ → Credential is incorrectly named (i.e. the authenticated name does not match the actual name)
|
||||
* -ESTALE → Credential's valdity has passed
|
||||
* -ESRCH → User specified for scope does not exist on this system
|
||||
*
|
||||
* (plus the various error codes tpm2_unseal() returns) */
|
||||
|
||||
h = (struct encrypted_credential_header*) input->iov_base;
|
||||
|
||||
/* The ID must fit in, for the current and all future formats */
|
||||
@ -1218,8 +1231,10 @@ int decrypt_credential_and_warn(
|
||||
|
||||
if (with_tpm2_pk) {
|
||||
r = tpm2_load_pcr_signature(tpm2_signature_path, &signature_json);
|
||||
if (r == -ENOENT)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EHOSTDOWN), "Couldn't find PCR signature file: %m");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to load pcr signature: %m");
|
||||
return log_error_errno(r, "Failed to load PCR signature: %m");
|
||||
}
|
||||
|
||||
if (with_null && !FLAGS_SET(flags, CREDENTIAL_ALLOW_NULL)) {
|
||||
@ -1234,7 +1249,7 @@ int decrypt_credential_and_warn(
|
||||
|
||||
if (efi_has_tpm2()) {
|
||||
if (is_efi_secure_boot())
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG),
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EHWPOISON),
|
||||
"Credential uses fixed key for fallback use when TPM2 is absent — but TPM2 is present, and SecureBoot is enabled, refusing.");
|
||||
|
||||
log_warning("Credential uses fixed key for use when TPM2 is absent, but TPM2 is present! Accepting anyway, since SecureBoot is disabled.");
|
||||
@ -1354,7 +1369,7 @@ int decrypt_credential_and_warn(
|
||||
/* srk= */ NULL,
|
||||
&tpm2_key);
|
||||
if (r == -EREMOTE)
|
||||
return log_error_errno(r, "TPM key integrity check failed. Key enrolled in superblock most likely does not belong to this TPM.");
|
||||
return log_error_errno(r, "TPM key integrity check failed. Key most likely does not belong to this TPM.");
|
||||
if (ERRNO_IS_NEG_TPM2_UNSEAL_BAD_PCR(r))
|
||||
return log_error_errno(r, "TPM policy does not match current system state. Either system has been tempered with or policy out-of-date: %m");
|
||||
if (r < 0)
|
||||
@ -1486,7 +1501,7 @@ int decrypt_credential_and_warn(
|
||||
if (r < 0 && r != -ENXIO)
|
||||
log_debug_errno(r, "Failed to parse $SYSTEMD_CREDENTIAL_VALIDATE_NAME: %m");
|
||||
if (r != 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EREMOTE), "Embedded credential name '%s' does not match filename '%s', refusing.", embedded_name, validate_name);
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EDESTADDRREQ), "Embedded credential name '%s' does not match filename '%s', refusing.", embedded_name, validate_name);
|
||||
|
||||
log_debug("Embedded credential name '%s' does not match expected name '%s', but configured to use credential anyway.", embedded_name, validate_name);
|
||||
}
|
||||
@ -1637,16 +1652,26 @@ int ipc_decrypt_credential(const char *validate_name, usec_t validate_timestamp,
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to call Decrypt() varlink call.");
|
||||
if (!isempty(error_id)) {
|
||||
if (streq(error_id, "io.systemd.Credentials.BadFormat"))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Bad credential format.");
|
||||
if (streq(error_id, "io.systemd.Credentials.NameMismatch"))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EREMOTE), "Name in credential doesn't match expectations.");
|
||||
if (streq(error_id, "io.systemd.Credentials.TimeMismatch"))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ESTALE), "Outside of credential validity time window.");
|
||||
if (streq(error_id, "io.systemd.Credentials.NoSuchUser"))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "No such user.");
|
||||
if (streq(error_id, "io.systemd.Credentials.BadScope"))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Scope mismtach.");
|
||||
static struct {
|
||||
const char *id;
|
||||
int errnum;
|
||||
const char *msg;
|
||||
} table[] = {
|
||||
{ "io.systemd.Credentials.BadFormat", EBADMSG, "Bad credential format." },
|
||||
{ "io.systemd.Credentials.NameMismatch", EDESTADDRREQ, "Name in credential doesn't match expectations." },
|
||||
{ "io.systemd.Credentials.TimeMismatch", ESTALE, "Outside of credential validity time window." },
|
||||
{ "io.systemd.Credentials.NoSuchUser", ESRCH, "No such user." },
|
||||
{ "io.systemd.Credentials.BadScope", EMEDIUMTYPE, "Scope mismatch." },
|
||||
{ "io.systemd.Credentials.CantFindPCRSignature", EHOSTDOWN, "PCR signature required for decryption, but could not be found." },
|
||||
{ "io.systemd.Credentials.NullKeyNotAllowed", EHWPOISON, "The key was encrypted with a null key, but that's now allowed during decryption." },
|
||||
{ "io.systemd.Credentials.KeyBelongsToOtherTPM", EREMOTE, "The TPM integrity check for this key failed, key probably belongs to another TPM, or was corrupted." },
|
||||
{ "io.systemd.Credentials.TPMInDictionaryLockout", ENOLCK, "The TPM is in dictionary lockout mode, cannot operate." },
|
||||
{ "io.systemd.Credentials.UnexpectedPCRState" , EUCLEAN, "Unexpected TPM PCR state of the system." },
|
||||
};
|
||||
|
||||
FOREACH_ELEMENT(i, table)
|
||||
if (streq(i->id, error_id))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(i->errnum), "%s", i->msg);
|
||||
|
||||
return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to decrypt: %s", error_id);
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <mntent.h>
|
||||
|
||||
#include "forward.h"
|
||||
|
||||
typedef struct SubMount {
|
||||
@ -37,9 +35,6 @@ static inline int mount_switch_root(const char *path, unsigned long mount_propag
|
||||
return mount_switch_root_full(path, mount_propagation_flag, false);
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(FILE*, endmntent, NULL);
|
||||
#define _cleanup_endmntent_ _cleanup_(endmntentp)
|
||||
|
||||
int mount_verbose_full(
|
||||
int error_log_level,
|
||||
const char *what,
|
||||
|
@ -161,7 +161,7 @@ static int patch_acls(int fd, const char *name, const struct stat *st, uid_t shi
|
||||
assert(st);
|
||||
|
||||
/* ACLs are not supported on symlinks, there's no point in trying */
|
||||
if (S_ISLNK(st->st_mode))
|
||||
if (!inode_type_can_acl(st->st_mode))
|
||||
return 0;
|
||||
|
||||
r = get_acl(fd, name, ACL_TYPE_ACCESS, &acl);
|
||||
|
@ -44,6 +44,11 @@ static SD_VARLINK_DEFINE_ERROR(NameMismatch);
|
||||
static SD_VARLINK_DEFINE_ERROR(TimeMismatch);
|
||||
static SD_VARLINK_DEFINE_ERROR(NoSuchUser);
|
||||
static SD_VARLINK_DEFINE_ERROR(BadScope);
|
||||
static SD_VARLINK_DEFINE_ERROR(CantFindPCRSignature);
|
||||
static SD_VARLINK_DEFINE_ERROR(NullKeyNotAllowed);
|
||||
static SD_VARLINK_DEFINE_ERROR(KeyBelongsToOtherTPM);
|
||||
static SD_VARLINK_DEFINE_ERROR(TPMInDictionaryLockout);
|
||||
static SD_VARLINK_DEFINE_ERROR(UnexpectedPCRState);
|
||||
|
||||
SD_VARLINK_DEFINE_INTERFACE(
|
||||
io_systemd_Credentials,
|
||||
@ -62,4 +67,14 @@ SD_VARLINK_DEFINE_INTERFACE(
|
||||
SD_VARLINK_SYMBOL_COMMENT("The specified user does not exist."),
|
||||
&vl_error_NoSuchUser,
|
||||
SD_VARLINK_SYMBOL_COMMENT("The credential does not match the selected scope."),
|
||||
&vl_error_BadScope);
|
||||
&vl_error_BadScope,
|
||||
SD_VARLINK_SYMBOL_COMMENT("PCR signature required for decryption, but not found."),
|
||||
&vl_error_CantFindPCRSignature,
|
||||
SD_VARLINK_SYMBOL_COMMENT("The key was encrypted with a null key, but that's now allowed during decryption."),
|
||||
&vl_error_NullKeyNotAllowed,
|
||||
SD_VARLINK_SYMBOL_COMMENT("The TPM integrity check for this key failed, key probably belongs to another TPM, or was corrupted."),
|
||||
&vl_error_KeyBelongsToOtherTPM,
|
||||
SD_VARLINK_SYMBOL_COMMENT("The TPM is in dictionary lockout mode, cannot operate."),
|
||||
&vl_error_TPMInDictionaryLockout,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Unexpected TPM PCR state of the system."),
|
||||
&vl_error_UnexpectedPCRState);
|
||||
|
@ -164,7 +164,7 @@ static void test_encrypt_decrypt_with(sd_id128_t mode, uid_t uid) {
|
||||
&encrypted,
|
||||
CREDENTIAL_ALLOW_NULL,
|
||||
&decrypted);
|
||||
ASSERT_ERROR(r, EREMOTE); /* name didn't match */
|
||||
ASSERT_ERROR(r, EDESTADDRREQ); /* name didn't match */
|
||||
|
||||
r = decrypt_credential_and_warn(
|
||||
"foo",
|
||||
|
@ -1459,8 +1459,8 @@ static int fd_set_acls(
|
||||
"Refusing to set ACLs on hardlinked file %s while the fs.protected_hardlinks sysctl is turned off.",
|
||||
path);
|
||||
|
||||
if (S_ISLNK(st->st_mode)) {
|
||||
log_debug("Skipping ACL fix for symlink %s.", path);
|
||||
if (!inode_type_can_acl(st->st_mode)) {
|
||||
log_debug("Skipping ACL fix for '%s' (inode type does not support ACLs).", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,7 @@ static int stack_directory_find_prioritized_devnode(sd_device *dev, int dirfd, b
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dir = xopendirat(dirfd, ".", O_NOFOLLOW);
|
||||
dir = xopendirat(dirfd, /* path= */ NULL, /* flags= */ 0);
|
||||
if (!dir)
|
||||
return -errno;
|
||||
|
||||
|
@ -49,10 +49,9 @@ FSTAB_GENERAL=(
|
||||
"/dev/test25 /x-systemd.validatefs xfs x-systemd.validatefs 0 0"
|
||||
|
||||
# Incomplete, but valid entries
|
||||
"/dev/incomplete1 /incomplete1"
|
||||
"/dev/incomplete2 /incomplete2 ext4"
|
||||
"/dev/incomplete3 /incomplete3 ext4 defaults"
|
||||
"/dev/incomplete4 /incomplete4 ext4 defaults 0"
|
||||
"/dev/incomplete1 /incomplete1 ext4"
|
||||
"/dev/incomplete2 /incomplete2 ext4 defaults"
|
||||
"/dev/incomplete3 /incomplete3 ext4 defaults 0"
|
||||
|
||||
# Remote filesystems
|
||||
"/dev/remote1 /nfs nfs bg 0 0"
|
||||
|
Loading…
x
Reference in New Issue
Block a user