1
0
mirror of https://github.com/systemd/systemd synced 2026-04-08 08:04:50 +02:00

Compare commits

...

11 Commits

Author SHA1 Message Date
Dominique Martinet
7a8288f6ed build: fix build without seccomp
- execute.c: bpf functions were in the middle of an #if HAVE_SECCOMP
  block for no reason
- test-fd-util.c: make seccomp-util.h includable without depending on
  <seccomp.h>, and make is_seccomp_available() hardcoded to returning
  false in this case.
  Also fix a stray DEFINED() -- HAVE_SECCOMP is defined as 0, so normal
  #if should be used like everywhere else.
2021-11-25 13:22:32 +09:00
dependabot[bot]
68181cf8a7 build(deps): bump github/codeql-action from 1.0.23 to 1.0.24
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1.0.23 to 1.0.24.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](a627e9fa50...e095058bfa)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-25 05:13:11 +03:00
Daan De Meyer
bc6b326d48 journal: Don't allow creating invalid objects
Let's not allow creating empty entry or data objects. Let's also
not allow creating data objects from data without an embedded '='
character.
2021-11-24 22:14:36 +01:00
Lennart Poettering
f7e910733c
Merge pull request #21502 from keszybz/os-release-debugging
Additional debugging info to make release-extension easier to introspect
2021-11-24 22:00:02 +01:00
Zbigniew Jędrzejewski-Szmek
f6048e5e56 dissect-image: always say "file of image" when reporting about the image
We give a path, but the path is only meaningful inside of the image.
Some messages made it clear that it's a path in the image, let's make
them all do that.
2021-11-24 17:43:01 +01:00
Zbigniew Jędrzejewski-Szmek
ed15f8bceb Add debug logs of extension-release scanning 2021-11-24 17:43:01 +01:00
Zbigniew Jędrzejewski-Szmek
48084df6ed dissect-image: provide a more useful message when ENOMEDIUM is returned 2021-11-24 17:43:01 +01:00
Zbigniew Jędrzejewski-Szmek
2284750820 dissect-image: do not enable "verification" when trying to acquire metadata
The whole point of acquiring metadata is quite often to figure out why the
image does not pass verification. Refusing to provide metadata is just being
hostile to the user.

When called from other places (e.g. image_read_metadata()), verification is
still performed.
2021-11-24 17:42:19 +01:00
Zbigniew Jędrzejewski-Szmek
03ae68f419 dissect-image: reuse common exit path 2021-11-24 15:55:58 +01:00
Zbigniew Jędrzejewski-Szmek
73c2c5255d shared/format-table: drop unnecessary _cleanup_ 2021-11-24 15:55:58 +01:00
Zbigniew Jędrzejewski-Szmek
9fa94e0753 test-pretty-print: spelling nitpick
The antonym of "nay" is usually spelled as "yea" (and pronouced as yā, so it
rhymes with "nay"), see e.g. https://www.cop.senate.gov/general/Features/votes.htm
2021-11-24 15:55:58 +01:00
13 changed files with 127 additions and 104 deletions

View File

@ -38,14 +38,14 @@ jobs:
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Initialize CodeQL
uses: github/codeql-action/init@a627e9fa504113bfa8e90a9b429b157a38b1cdbd
uses: github/codeql-action/init@e095058bfa09de8070f94e98f5dc059531bc6235
with:
languages: ${{ matrix.language }}
- run: sudo -E .github/workflows/unit_tests.sh SETUP
- name: Autobuild
uses: github/codeql-action/autobuild@a627e9fa504113bfa8e90a9b429b157a38b1cdbd
uses: github/codeql-action/autobuild@e095058bfa09de8070f94e98f5dc059531bc6235
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@a627e9fa504113bfa8e90a9b429b157a38b1cdbd
uses: github/codeql-action/analyze@e095058bfa09de8070f94e98f5dc059531bc6235

View File

@ -72,6 +72,8 @@ int open_extension_release(const char *root, const char *extension, char **ret_p
r = chase_symlinks(extension_full_path, root, CHASE_PREFIX_ROOT,
ret_path ? &q : NULL,
ret_fd ? &fd : NULL);
log_full_errno_zerook(LOG_DEBUG, MIN(r, 0), "Checking for %s: %m", extension_full_path);
/* Cannot find the expected extension-release file? The image filename might have been
* mangled on deployment, so fallback to checking for any file in the extension-release.d
* directory, and return the first one with a user.extension-release xattr instead.
@ -84,7 +86,7 @@ int open_extension_release(const char *root, const char *extension, char **ret_p
r = chase_symlinks_and_opendir("/usr/lib/extension-release.d/", root, CHASE_PREFIX_ROOT,
&extension_release_dir_path, &extension_release_dir);
if (r < 0)
return r;
return log_debug_errno(r, "Cannot open %s/usr/lib/extension-release.d/, ignoring: %m", root);
r = -ENOENT;
struct dirent *de;
@ -98,8 +100,11 @@ int open_extension_release(const char *root, const char *extension, char **ret_p
if (!image_name)
continue;
if (!image_name_is_valid(image_name))
if (!image_name_is_valid(image_name)) {
log_debug("%s/%s is not a valid extension-release file name, ignoring.",
extension_release_dir_path, de->d_name);
continue;
}
/* We already chased the directory, and checked that
* this is a real file, so we shouldn't fail to open it. */
@ -113,30 +118,38 @@ int open_extension_release(const char *root, const char *extension, char **ret_p
de->d_name);
/* Really ensure it is a regular file after we open it. */
if (fd_verify_regular(extension_release_fd) < 0)
if (fd_verify_regular(extension_release_fd) < 0) {
log_debug("%s/%s is not a regular file, ignoring.", extension_release_dir_path, de->d_name);
continue;
}
/* No xattr or cannot parse it? Then skip this. */
_cleanup_free_ char *extension_release_xattr = NULL;
k = fgetxattr_malloc(extension_release_fd, "user.extension-release.strict", &extension_release_xattr);
if (k < 0 && !ERRNO_IS_NOT_SUPPORTED(k) && k != -ENODATA)
log_debug_errno(k,
"Failed to read 'user.extension-release.strict' extended attribute from extension-release file %s/%s: %m",
extension_release_dir_path,
de->d_name);
if (k < 0)
"%s/%s: Failed to read 'user.extension-release.strict' extended attribute from file: %m",
extension_release_dir_path, de->d_name);
if (k < 0) {
log_debug("%s/%s does not have user.extension-release.strict xattr, ignoring.", extension_release_dir_path, de->d_name);
continue;
}
/* Explicitly set to request strict matching? Skip it. */
k = parse_boolean(extension_release_xattr);
if (k < 0)
log_debug_errno(k,
"Failed to parse 'user.extension-release.strict' extended attribute value from extension-release file %s/%s: %m",
extension_release_dir_path,
de->d_name);
if (k < 0 || k > 0)
"%s/%s: Failed to parse 'user.extension-release.strict' extended attribute from file: %m",
extension_release_dir_path, de->d_name);
else if (k > 0)
log_debug("%s/%s: 'user.extension-release.strict' attribute is true, ignoring file.",
extension_release_dir_path, de->d_name);
if (k != 0)
continue;
log_debug("%s/%s: 'user.extension-release.strict' attribute is false…",
extension_release_dir_path, de->d_name);
/* We already found what we were looking for, but there's another candidate?
* We treat this as an error, as we want to enforce that there are no ambiguities
* in case we are in the fallback path.*/

View File

@ -1701,29 +1701,6 @@ static int apply_restrict_namespaces(const Unit *u, const ExecContext *c) {
return seccomp_restrict_namespaces(c->restrict_namespaces);
}
#if HAVE_LIBBPF
static bool skip_lsm_bpf_unsupported(const Unit* u, const char* msg) {
if (lsm_bpf_supported())
return false;
log_unit_debug(u, "LSM BPF not supported, skipping %s", msg);
return true;
}
static int apply_restrict_filesystems(Unit *u, const ExecContext *c) {
assert(u);
assert(c);
if (!exec_context_restrict_filesystems_set(c))
return 0;
if (skip_lsm_bpf_unsupported(u, "RestrictFileSystems="))
return 0;
return lsm_bpf_unit_restrict_filesystems(u, c->restrict_filesystems, c->restrict_filesystems_allow_list);
}
#endif
static int apply_lock_personality(const Unit* u, const ExecContext *c) {
unsigned long personality;
int r;
@ -1752,6 +1729,29 @@ static int apply_lock_personality(const Unit* u, const ExecContext *c) {
#endif
#if HAVE_LIBBPF
static bool skip_lsm_bpf_unsupported(const Unit* u, const char* msg) {
if (lsm_bpf_supported())
return false;
log_unit_debug(u, "LSM BPF not supported, skipping %s", msg);
return true;
}
static int apply_restrict_filesystems(Unit *u, const ExecContext *c) {
assert(u);
assert(c);
if (!exec_context_restrict_filesystems_set(c))
return 0;
if (skip_lsm_bpf_unsupported(u, "RestrictFileSystems="))
return 0;
return lsm_bpf_unit_restrict_filesystems(u, c->restrict_filesystems, c->restrict_filesystems_allow_list);
}
#endif
static int apply_protect_hostname(const Unit *u, const ExecContext *c, int *ret_exit_status) {
assert(u);
assert(c);

View File

@ -433,7 +433,7 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
if (arg_json_format_flags & JSON_FORMAT_OFF)
putc('\n', stdout);
r = dissected_image_acquire_metadata(m);
r = dissected_image_acquire_metadata(m, 0);
if (r == -ENXIO)
return log_error_errno(r, "No root partition discovered.");
if (r == -EUCLEAN)

View File

@ -1660,14 +1660,15 @@ static int journal_file_append_data(
const void *data, uint64_t size,
Object **ret, uint64_t *ret_offset) {
uint64_t hash, p;
uint64_t osize;
Object *o;
uint64_t hash, p, fp, osize;
Object *o, *fo;
int r, compression = 0;
const void *eq;
assert(f);
assert(data || size == 0);
if (!data || size == 0)
return -EINVAL;
hash = journal_file_hash_data(f, data, size);
@ -1685,6 +1686,10 @@ static int journal_file_append_data(
return 0;
}
eq = memchr(data, '=', size);
if (!eq)
return -EINVAL;
osize = offsetof(Object, data.payload) + size;
r = journal_file_append_object(f, OBJECT_DATA, osize, &o, &p);
if (r < 0)
@ -1729,23 +1734,14 @@ static int journal_file_append_data(
if (r < 0)
return r;
if (!data)
eq = NULL;
else
eq = memchr(data, '=', size);
if (eq && eq > data) {
Object *fo = NULL;
uint64_t fp;
/* Create field object ... */
r = journal_file_append_field(f, data, (uint8_t*) eq - (uint8_t*) data, &fo, &fp);
if (r < 0)
return r;
/* Create field object ... */
r = journal_file_append_field(f, data, (uint8_t*) eq - (uint8_t*) data, &fo, &fp);
if (r < 0)
return r;
/* ... and link it in. */
o->data.next_field_offset = fo->field.head_data_offset;
fo->field.head_data_offset = le64toh(p);
}
/* ... and link it in. */
o->data.next_field_offset = fo->field.head_data_offset;
fo->field.head_data_offset = le64toh(p);
if (ret)
*ret = o;
@ -2125,7 +2121,7 @@ int journal_file_append_entry(
assert(f);
assert(f->header);
assert(iovec || n_iovec == 0);
assert(iovec && n_iovec > 0);
if (ts) {
if (!VALID_REALTIME(ts->realtime))
@ -3917,6 +3913,9 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
} else
data = o->data.payload;
if (l == 0)
return -EBADMSG;
r = journal_file_append_data(to, data, l, &u, &h);
if (r < 0)
return r;
@ -3936,8 +3935,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
return r;
}
r = journal_file_append_entry_internal(to, &ts, boot_id, xor_hash, items, n,
NULL, NULL, NULL);
r = journal_file_append_entry_internal(to, &ts, boot_id, xor_hash, items, n, NULL, NULL, NULL);
if (mmap_cache_fd_got_sigbus(to->cache_fd))
return -EIO;

View File

@ -165,7 +165,7 @@ static bool check_compressed(uint64_t compress_threshold, uint64_t data_size) {
Object *o;
uint64_t p;
char t[] = "/var/tmp/journal-XXXXXX";
char data[2048] = {0};
char data[2048] = "FIELD=";
bool is_compressed;
int r;

View File

@ -1216,7 +1216,9 @@ int image_read_metadata(Image *i) {
if (r < 0)
return r;
r = dissected_image_acquire_metadata(m);
r = dissected_image_acquire_metadata(m,
DISSECT_IMAGE_VALIDATE_OS |
DISSECT_IMAGE_VALIDATE_OS_EXT);
if (r < 0)
return r;

View File

@ -3009,7 +3009,7 @@ int dissected_image_load_verity_sig_partition(
return 1;
}
int dissected_image_acquire_metadata(DissectedImage *m) {
int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_flags) {
enum {
META_HOSTNAME,
@ -3026,7 +3026,7 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
[META_MACHINE_ID] = "/etc/machine-id\0",
[META_MACHINE_INFO] = "/etc/machine-info\0",
[META_OS_RELEASE] = ("/etc/os-release\0"
"/usr/lib/os-release\0"),
"/usr/lib/os-release\0"),
[META_EXTENSION_RELEASE] = "extension-release\0", /* Used only for logging. */
[META_HAS_INIT_SYSTEM] = "has-init-system\0", /* ditto */
};
@ -3079,17 +3079,13 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
t,
UID_INVALID,
UID_INVALID,
DISSECT_IMAGE_READ_ONLY|
DISSECT_IMAGE_MOUNT_ROOT_ONLY|
DISSECT_IMAGE_VALIDATE_OS|
DISSECT_IMAGE_VALIDATE_OS_EXT|
extra_flags |
DISSECT_IMAGE_READ_ONLY |
DISSECT_IMAGE_MOUNT_ROOT_ONLY |
DISSECT_IMAGE_USR_NO_ROOT);
if (r < 0) {
/* Let parent know the error */
(void) write(error_pipe[1], &r, sizeof(r));
log_debug_errno(r, "Failed to mount dissected image: %m");
_exit(EXIT_FAILURE);
goto inner_fail;
}
for (unsigned k = 0; k < _META_MAX; k++) {
@ -3168,6 +3164,7 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
_exit(EXIT_SUCCESS);
inner_fail:
/* Let parent know the error */
(void) write(error_pipe[1], &r, sizeof(r));
_exit(EXIT_FAILURE);
}
@ -3193,7 +3190,7 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
case META_HOSTNAME:
r = read_etc_hostname_stream(f, &hostname);
if (r < 0)
log_debug_errno(r, "Failed to read /etc/hostname: %m");
log_debug_errno(r, "Failed to read /etc/hostname of image: %m");
break;
@ -3202,17 +3199,17 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
log_debug_errno(r, "Failed to read /etc/machine-id: %m");
log_debug_errno(r, "Failed to read /etc/machine-id of image: %m");
else if (r == 33) {
r = sd_id128_from_string(line, &machine_id);
if (r < 0)
log_debug_errno(r, "Image contains invalid /etc/machine-id: %s", line);
} else if (r == 0)
log_debug("/etc/machine-id file is empty.");
log_debug("/etc/machine-id file of image is empty.");
else if (streq(line, "uninitialized"))
log_debug("/etc/machine-id file is uninitialized (likely aborted first boot).");
log_debug("/etc/machine-id file of image is uninitialized (likely aborted first boot).");
else
log_debug("/etc/machine-id has unexpected length %i.", r);
log_debug("/etc/machine-id file of image has unexpected length %i.", r);
break;
}
@ -3220,21 +3217,21 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
case META_MACHINE_INFO:
r = load_env_file_pairs(f, "machine-info", &machine_info);
if (r < 0)
log_debug_errno(r, "Failed to read /etc/machine-info: %m");
log_debug_errno(r, "Failed to read /etc/machine-info of image: %m");
break;
case META_OS_RELEASE:
r = load_env_file_pairs(f, "os-release", &os_release);
if (r < 0)
log_debug_errno(r, "Failed to read OS release file: %m");
log_debug_errno(r, "Failed to read OS release file of image: %m");
break;
case META_EXTENSION_RELEASE:
r = load_env_file_pairs(f, "extension-release", &extension_release);
if (r < 0)
log_debug_errno(r, "Failed to read extension release file: %m");
log_debug_errno(r, "Failed to read extension release file of image: %m");
break;
@ -3312,29 +3309,32 @@ int dissect_image_and_warn(
return log_error_errno(r, "Dissecting images is not supported, compiled without blkid support.");
case -ENOPKG:
return log_error_errno(r, "Couldn't identify a suitable partition table or file system in '%s'.", name);
return log_error_errno(r, "%s: Couldn't identify a suitable partition table or file system.", name);
case -ENOMEDIUM:
return log_error_errno(r, "%s: The image does not pass validation.", name);
case -EADDRNOTAVAIL:
return log_error_errno(r, "No root partition for specified root hash found in '%s'.", name);
return log_error_errno(r, "%s: No root partition for specified root hash found.", name);
case -ENOTUNIQ:
return log_error_errno(r, "Multiple suitable root partitions found in image '%s'.", name);
return log_error_errno(r, "%s: Multiple suitable root partitions found in image.", name);
case -ENXIO:
return log_error_errno(r, "No suitable root partition found in image '%s'.", name);
return log_error_errno(r, "%s: No suitable root partition found in image.", name);
case -EPROTONOSUPPORT:
return log_error_errno(r, "Device '%s' is loopback block device with partition scanning turned off, please turn it on.", name);
case -ENOTBLK:
return log_error_errno(r, "%s: Image is not a block device.", name);
case -EBADR:
return log_error_errno(r,
"Combining partitioned images (such as '%s') with external Verity data (such as '%s') not supported. "
"(Consider setting $SYSTEMD_DISSECT_VERITY_SIDECAR=0 to disable automatic discovery of external Verity data.)",
name, strna(verity ? verity->data_path : NULL));
case -ENOTBLK:
return log_error_errno(r, "Specified image '%s' is not a block device.", name);
default:
if (r < 0)
return log_error_errno(r, "Failed to dissect image '%s': %m", name);

View File

@ -208,7 +208,7 @@ int dissected_image_decrypt_interactively(DissectedImage *m, const char *passphr
int dissected_image_mount(DissectedImage *m, const char *dest, uid_t uid_shift, uid_t uid_range, DissectImageFlags flags);
int dissected_image_mount_and_warn(DissectedImage *m, const char *where, uid_t uid_shift, uid_t uid_range, DissectImageFlags flags);
int dissected_image_acquire_metadata(DissectedImage *m);
int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_flags);
DecryptedImage* decrypted_image_unref(DecryptedImage *p);
DEFINE_TRIVIAL_CLEANUP_FUNC(DecryptedImage*, decrypted_image_unref);

View File

@ -1708,7 +1708,7 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
}
case TABLE_UID: {
_cleanup_free_ char *p = NULL;
char *p;
if (!uid_is_valid(d->uid))
return "n/a";
@ -1716,14 +1716,14 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
p = new(char, DECIMAL_STR_WIDTH(d->uid) + 1);
if (!p)
return NULL;
sprintf(p, UID_FMT, d->uid);
d->formatted = TAKE_PTR(p);
d->formatted = p;
break;
}
case TABLE_GID: {
_cleanup_free_ char *p = NULL;
char *p;
if (!gid_is_valid(d->gid))
return "n/a";
@ -1731,14 +1731,14 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
p = new(char, DECIMAL_STR_WIDTH(d->gid) + 1);
if (!p)
return NULL;
sprintf(p, GID_FMT, d->gid);
d->formatted = TAKE_PTR(p);
d->formatted = p;
break;
}
case TABLE_PID: {
_cleanup_free_ char *p = NULL;
char *p;
if (!pid_is_valid(d->pid))
return "n/a";
@ -1746,15 +1746,15 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
p = new(char, DECIMAL_STR_WIDTH(d->pid) + 1);
if (!p)
return NULL;
sprintf(p, PID_FMT, d->pid);
d->formatted = TAKE_PTR(p);
d->formatted = p;
break;
}
case TABLE_SIGNAL: {
_cleanup_free_ char *p = NULL;
const char *suffix;
char *p;
suffix = signal_to_string(d->int_val);
if (!suffix)
@ -1764,12 +1764,12 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
if (!p)
return NULL;
d->formatted = TAKE_PTR(p);
d->formatted = p;
break;
}
case TABLE_MODE: {
_cleanup_free_ char *p = NULL;
char *p;
if (d->mode == MODE_INVALID)
return "n/a";
@ -1779,7 +1779,7 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
return NULL;
sprintf(p, "%04o", d->mode & 07777);
d->formatted = TAKE_PTR(p);
d->formatted = p;
break;
}

View File

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#if HAVE_SECCOMP
#include <seccomp.h>
#include <stdbool.h>
#include <stdint.h>
@ -152,3 +154,11 @@ static inline const char *seccomp_errno_or_action_to_string(int num) {
int parse_syscall_and_errno(const char *in, char **name, int *error);
int seccomp_suppress_sync(void);
#else
static inline bool is_seccomp_available(void) {
return false;
}
#endif

View File

@ -292,7 +292,7 @@ static void test_close_all_fds_inner(void) {
}
static int seccomp_prohibit_close_range(void) {
#if defined(HAVE_SECCOMP) && defined(__SNR_close_range)
#if HAVE_SECCOMP && defined(__SNR_close_range)
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
int r;

View File

@ -34,7 +34,7 @@ static void test_cat_files(void) {
static void test_red_green_cross_check_mark(void) {
bool b = false;
printf("yeah: <%s>\n", GREEN_CHECK_MARK());
printf("yea: <%s>\n", GREEN_CHECK_MARK());
printf("nay: <%s>\n", RED_CROSS_MARK());
printf("%s → %s → %s → %s\n",