Compare commits

..

No commits in common. "cc479760b4736082d26ec332f2423a9ab23d59c5" and "2edc4942163fa12b5c5da5427cbe01ad87ff8dc4" have entirely different histories.

28 changed files with 355 additions and 473 deletions

View File

@ -1,7 +1,4 @@
--- sudo: required
# vi: ts=2 sw=2 et:
language: bash
dist: bionic dist: bionic
services: services:
- docker - docker
@ -12,40 +9,88 @@ env:
- CI_MANAGERS="$TRAVIS_BUILD_DIR/travis-ci/managers" - CI_MANAGERS="$TRAVIS_BUILD_DIR/travis-ci/managers"
- CI_TOOLS="$TRAVIS_BUILD_DIR/travis-ci/tools" - CI_TOOLS="$TRAVIS_BUILD_DIR/travis-ci/tools"
- REPO_ROOT="$TRAVIS_BUILD_DIR" - REPO_ROOT="$TRAVIS_BUILD_DIR"
jobs:
- DEBIAN_RELEASE=testing PHASE="RUN_GCC"
- DEBIAN_RELEASE=testing PHASE="RUN_GCC_ASAN_UBSAN"
- DEBIAN_RELEASE=testing PHASE="RUN_CLANG"
- DEBIAN_RELEASE=testing PHASE="RUN_CLANG_ASAN_UBSAN"
stages: stages:
# 'Test' is the default stage (for matrix jobs) - name: Build & test
- name: Test
if: type != cron if: type != cron
# Run Coverity periodically instead of for each commit/PR # Run Coverity periodically instead of for each commit/PR
- name: Coverity - name: Coverity
if: type = cron if: type = cron
# Matrix job definition - this is run for each combination of env variables
# from the env.jobs array above
before_install:
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- docker --version
install:
- $CI_MANAGERS/debian.sh SETUP
script:
- $CI_MANAGERS/debian.sh $PHASE || travis_terminate 1
after_script:
- $CI_MANAGERS/debian.sh CLEANUP
# Inject another (single) job into the matrix for Coverity
jobs: jobs:
include: include:
- stage: Build & test
name: Debian Testing
language: bash
env:
- DEBIAN_RELEASE="testing"
- CONT_NAME="systemd-debian-$DEBIAN_RELEASE"
- DOCKER_EXEC="docker exec -ti $CONT_NAME"
before_install:
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- docker --version
install:
- $CI_MANAGERS/debian.sh SETUP
script:
- $CI_MANAGERS/debian.sh RUN || travis_terminate 1
after_script:
- $CI_MANAGERS/debian.sh CLEANUP
- name: Debian Testing (ASan+UBSan)
language: bash
env:
- DEBIAN_RELEASE="testing"
- CONT_NAME="systemd-debian-$DEBIAN_RELEASE"
- DOCKER_EXEC="docker exec -ti $CONT_NAME"
before_install:
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- docker --version
install:
- $CI_MANAGERS/debian.sh SETUP
script:
- $CI_MANAGERS/debian.sh RUN_ASAN || travis_terminate 1
after_script:
- $CI_MANAGERS/debian.sh CLEANUP
- name: Debian Testing (clang)
language: bash
env:
- DEBIAN_RELEASE="testing"
- CONT_NAME="systemd-debian-$DEBIAN_RELEASE"
- DOCKER_EXEC="docker exec -ti $CONT_NAME"
before_install:
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- docker --version
install:
- $CI_MANAGERS/debian.sh SETUP
script:
- $CI_MANAGERS/debian.sh RUN_CLANG || travis-travis_terminate 1
after_script:
- $CI_MANAGERS/debian.sh CLEANUP
- name: Debian Testing (clang ASan+UBSan)
language: bash
env:
- DEBIAN_RELEASE="testing"
- CONT_NAME="systemd-debian-$DEBIAN_RELEASE"
- DOCKER_EXEC="docker exec -ti $CONT_NAME"
before_install:
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- docker --version
install:
- $CI_MANAGERS/debian.sh SETUP
script:
- $CI_MANAGERS/debian.sh RUN_CLANG_ASAN || travis_terminate 1
after_script:
- $CI_MANAGERS/debian.sh CLEANUP
- stage: Coverity - stage: Coverity
language: bash language: bash
env: env:
- FEDORA_RELEASE="latest" - FEDORA_RELEASE="latest"
- CONT_NAME="coverity-fedora-$FEDORA_RELEASE"
- DOCKER_EXEC="docker exec -ti $CONT_NAME"
- TOOL_BASE="/var/tmp/coverity-scan-analysis" - TOOL_BASE="/var/tmp/coverity-scan-analysis"
- DOCKER_RUN="docker run -v $TOOL_BASE:$TOOL_BASE:rw --env-file .cov-env" - DOCKER_RUN="docker run -v $TOOL_BASE:$TOOL_BASE:rw --env-file .cov-env"
# Coverity env variables # Coverity env variables

View File

@ -19,8 +19,7 @@
<xsl:template match="citerefentry[not(@project)]"> <xsl:template match="citerefentry[not(@project)]">
<a> <a>
<xsl:attribute name="href"> <xsl:attribute name="href">
<xsl:value-of select="refentrytitle"/> <xsl:value-of select="refentrytitle"/><xsl:text>.html#</xsl:text>
<xsl:text>.html#</xsl:text>
<xsl:value-of select="refentrytitle/@target"/> <xsl:value-of select="refentrytitle/@target"/>
</xsl:attribute> </xsl:attribute>
<xsl:call-template name="inline.charseq"/> <xsl:call-template name="inline.charseq"/>
@ -134,15 +133,6 @@
</a> </a>
</xsl:template> </xsl:template>
<xsl:template match="citerefentry[@project='url']">
<a>
<xsl:attribute name="href">
<xsl:value-of select="refentrytitle/@url"/>
</xsl:attribute>
<xsl:call-template name="inline.charseq"/>
</a>
</xsl:template>
<!-- <!--
- helper template to do conflict resolution between various headings with the same inferred ID attribute/tag from the headerlink template - helper template to do conflict resolution between various headings with the same inferred ID attribute/tag from the headerlink template
- this conflict resolution is necessary to prevent malformed HTML output (multiple ID attributes with the same value) - this conflict resolution is necessary to prevent malformed HTML output (multiple ID attributes with the same value)

View File

@ -51,8 +51,7 @@
<para><filename>systemd-makefs</filename> knows very little about specific file <para><filename>systemd-makefs</filename> knows very little about specific file
systems and swap devices, and after checking that the block device does not already systems and swap devices, and after checking that the block device does not already
contain a file system or other content, it will execute binaries specific to contain a file system or other content, it will execute binaries specific to
each filesystem type (<filename>/sbin/mkfs.<replaceable>type</replaceable></filename> each filesystem type (<filename>/sbin/mkfs.<replaceable>type</replaceable></filename>).</para>
or <filename>/sbin/mkswap</filename>).</para>
<para><filename>systemd-growfs</filename> knows very little about specific file <para><filename>systemd-growfs</filename> knows very little about specific file
systems and swap devices, and will instruct the kernel to grow the mounted systems and swap devices, and will instruct the kernel to grow the mounted
@ -62,7 +61,8 @@
number specific to each file system, so only certain types are supported. number specific to each file system, so only certain types are supported.
Currently: Currently:
<citerefentry project='man-pages'><refentrytitle>ext4</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>ext4</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry project='url'><refentrytitle url='https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs(5)'>btrfs</refentrytitle><manvolnum>5</manvolnum></citerefentry>, btrfs (see
<citerefentry project='man-pages'><refentrytitle>btrfs-man5</refentrytitle><manvolnum>5</manvolnum></citerefentry>),
<citerefentry project='man-pages'><refentrytitle>xfs</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>xfs</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<!-- yes, that's what the man page is called. --> <!-- yes, that's what the man page is called. -->
and dm-crypt partitions (see and dm-crypt partitions (see

View File

@ -145,43 +145,6 @@
<xi:include href="system-only.xml" xpointer="singular"/></listitem> <xi:include href="system-only.xml" xpointer="singular"/></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>RootHash=</varname></term>
<listitem><para>Takes a data integrity (dm-verity) root hash specified in hexadecimal, or the path to a file
containing a root hash in ASCII hexadecimal format. This option enables data integrity checks using dm-verity,
if the used image contains the appropriate integrity data (see above) or if <varname>RootVerity=</varname> is used.
The specified hash must match the root hash of integrity data, and is usually at least 256 bits (and hence 64
formatted hexadecimal characters) long (in case of SHA256 for example). If this option is not specified, but
the image file carries the <literal>user.verity.roothash</literal> extended file attribute (see <citerefentry
project='man-pages'><refentrytitle>xattr</refentrytitle><manvolnum>7</manvolnum></citerefentry>), then the root
hash is read from it, also as formatted hexadecimal characters. If the extended file attribute is not found (or
is not supported by the underlying file system), but a file with the <filename>.roothash</filename> suffix is
found next to the image file, bearing otherwise the same name (except if the image has the
<filename>.raw</filename> suffix, in which case the root hash file must not have it in its name), the root hash
is read from it and automatically used, also as formatted hexadecimal characters.</para>
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>RootVerity=</varname></term>
<listitem><para>Takes the path to a data integrity (dm-verity) file. This option enables data integrity checks
using dm-verity, if <varname>RootImage=</varname> is used and a root-hash is passed and if the used image itself
does not contains the integrity data. The integrity data must be matched by the root hash. If this option is not
specified, but a file with the <filename>.verity</filename> suffix is found next to the image file, bearing otherwise
the same name (except if the image has the <filename>.raw</filename> suffix, in which case the verity data file must
not have it in its name), the verity data is read from it and automatically used.</para>
<para>This option is supported only for disk images that contain a single file system, without an enveloping partition
table. Images that contain a GPT partition table should instead include both root file system and matching Verity
data in the same image, implementing the
[Discoverable Partition Specification](https://systemd.io/DISCOVERABLE_PARTITIONS)</para>
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>MountAPIVFS=</varname></term> <term><varname>MountAPIVFS=</varname></term>

View File

@ -39,18 +39,7 @@ static int cached_enforcing = -1;
static struct selabel_handle *label_hnd = NULL; static struct selabel_handle *label_hnd = NULL;
#define log_enforcing(...) log_full(mac_selinux_enforcing() ? LOG_ERR : LOG_WARNING, __VA_ARGS__) #define log_enforcing(...) log_full(mac_selinux_enforcing() ? LOG_ERR : LOG_WARNING, __VA_ARGS__)
#define log_enforcing_errno(r, ...) log_full_errno(mac_selinux_enforcing() ? LOG_ERR : LOG_WARNING, r, __VA_ARGS__)
#define log_enforcing_errno(error, ...) \
({ \
bool _enforcing = mac_selinux_enforcing(); \
int _level = _enforcing ? LOG_ERR : LOG_WARNING; \
int _e = (error); \
\
int _r = (log_get_max_level() >= LOG_PRI(_level)) \
? log_internal_realm(_level, _e, PROJECT_FILE, __LINE__, __func__, __VA_ARGS__) \
: -ERRNO_VALUE(_e); \
_enforcing ? _r : 0; \
})
#endif #endif
bool mac_selinux_use(void) { bool mac_selinux_use(void) {
@ -70,15 +59,14 @@ bool mac_selinux_enforcing(void) {
#if HAVE_SELINUX #if HAVE_SELINUX
if (_unlikely_(cached_enforcing < 0)) { if (_unlikely_(cached_enforcing < 0)) {
cached_enforcing = security_getenforce(); cached_enforcing = security_getenforce();
if (cached_enforcing < 0) { if (cached_enforcing == -1)
log_debug_errno(errno, "Failed to get SELinux enforced status, continuing in enforcing mode: %m"); log_error_errno(errno, "Failed to get SELinux enforced status, continue in enforcing mode: %m");
return true; /* treat failure as enforcing mode */ else
}
log_debug("SELinux enforcing state cached to: %s", cached_enforcing ? "enforcing" : "permissive"); log_debug("SELinux enforcing state cached to: %s", cached_enforcing ? "enforcing" : "permissive");
} }
return cached_enforcing > 0; /* treat failure as enforcing mode */
return (cached_enforcing != 0);
#else #else
return false; return false;
#endif #endif
@ -102,11 +90,11 @@ static int setenforce_callback(int enforcing) {
#endif #endif
int mac_selinux_init(void) { int mac_selinux_init(void) {
int r = 0;
#if HAVE_SELINUX #if HAVE_SELINUX
usec_t before_timestamp, after_timestamp; usec_t before_timestamp, after_timestamp;
struct mallinfo before_mallinfo, after_mallinfo; struct mallinfo before_mallinfo, after_mallinfo;
char timespan[FORMAT_TIMESPAN_MAX];
int l;
selinux_set_callback(SELINUX_CB_POLICYLOAD, (union selinux_callback) mac_selinux_reload); selinux_set_callback(SELINUX_CB_POLICYLOAD, (union selinux_callback) mac_selinux_reload);
selinux_set_callback(SELINUX_CB_SETENFORCE, (union selinux_callback) setenforce_callback); selinux_set_callback(SELINUX_CB_SETENFORCE, (union selinux_callback) setenforce_callback);
@ -121,8 +109,12 @@ int mac_selinux_init(void) {
before_timestamp = now(CLOCK_MONOTONIC); before_timestamp = now(CLOCK_MONOTONIC);
label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
if (!label_hnd) if (!label_hnd) {
return log_enforcing_errno(errno, "Failed to initialize SELinux context: %m"); log_enforcing_errno(errno, "Failed to initialize SELinux context: %m");
r = mac_selinux_enforcing() ? -errno : 0;
} else {
char timespan[FORMAT_TIMESPAN_MAX];
int l;
after_timestamp = now(CLOCK_MONOTONIC); after_timestamp = now(CLOCK_MONOTONIC);
after_mallinfo = mallinfo(); after_mallinfo = mallinfo();
@ -132,9 +124,10 @@ int mac_selinux_init(void) {
log_debug("Successfully loaded SELinux database in %s, size on heap is %iK.", log_debug("Successfully loaded SELinux database in %s, size on heap is %iK.",
format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0), format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0),
(l+1023)/1024); (l+1023)/1024);
}
#endif #endif
return 0;
return r;
} }
void mac_selinux_finish(void) { void mac_selinux_finish(void) {
@ -233,7 +226,9 @@ int mac_selinux_fix_container(const char *path, const char *inside_path, LabelFi
return 0; return 0;
fail: fail:
return log_enforcing_errno(r, "Unable to fix SELinux security context of %s (%s): %m", path, inside_path); log_enforcing_errno(r, "Unable to fix SELinux security context of %s (%s): %m", path, inside_path);
if (mac_selinux_enforcing())
return r;
#endif #endif
return 0; return 0;
@ -248,17 +243,21 @@ int mac_selinux_apply(const char *path, const char *label) {
assert(path); assert(path);
assert(label); assert(label);
if (setfilecon(path, label) < 0) if (setfilecon(path, label) < 0) {
return log_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, path); log_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, path);
if (mac_selinux_enforcing())
return -errno;
}
#endif #endif
return 0; return 0;
} }
int mac_selinux_get_create_label_from_exe(const char *exe, char **label) { int mac_selinux_get_create_label_from_exe(const char *exe, char **label) {
int r = -EOPNOTSUPP;
#if HAVE_SELINUX #if HAVE_SELINUX
_cleanup_freecon_ char *mycon = NULL, *fcon = NULL; _cleanup_freecon_ char *mycon = NULL, *fcon = NULL;
security_class_t sclass; security_class_t sclass;
int r;
assert(exe); assert(exe);
assert(label); assert(label);
@ -281,39 +280,36 @@ int mac_selinux_get_create_label_from_exe(const char *exe, char **label) {
r = security_compute_create_raw(mycon, fcon, sclass, label); r = security_compute_create_raw(mycon, fcon, sclass, label);
if (r < 0) if (r < 0)
return -errno; return -errno;
return 0;
#else
return -EOPNOTSUPP;
#endif #endif
return r;
} }
int mac_selinux_get_our_label(char **label) { int mac_selinux_get_our_label(char **label) {
#if HAVE_SELINUX int r = -EOPNOTSUPP;
int r;
assert(label); assert(label);
#if HAVE_SELINUX
if (!mac_selinux_use()) if (!mac_selinux_use())
return -EOPNOTSUPP; return -EOPNOTSUPP;
r = getcon_raw(label); r = getcon_raw(label);
if (r < 0) if (r < 0)
return -errno; return -errno;
return 0;
#else
return -EOPNOTSUPP;
#endif #endif
return r;
} }
int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *exec_label, char **label) { int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *exec_label, char **label) {
int r = -EOPNOTSUPP;
#if HAVE_SELINUX #if HAVE_SELINUX
_cleanup_freecon_ char *mycon = NULL, *peercon = NULL, *fcon = NULL; _cleanup_freecon_ char *mycon = NULL, *peercon = NULL, *fcon = NULL;
_cleanup_context_free_ context_t pcon = NULL, bcon = NULL; _cleanup_context_free_ context_t pcon = NULL, bcon = NULL;
security_class_t sclass; security_class_t sclass;
const char *range = NULL; const char *range = NULL;
int r;
assert(socket_fd >= 0); assert(socket_fd >= 0);
assert(exe); assert(exe);
@ -366,11 +362,9 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *
r = security_compute_create_raw(mycon, fcon, sclass, label); r = security_compute_create_raw(mycon, fcon, sclass, label);
if (r < 0) if (r < 0)
return -errno; return -errno;
return 0;
#else
return -EOPNOTSUPP;
#endif #endif
return r;
} }
char* mac_selinux_free(char *label) { char* mac_selinux_free(char *label) {
@ -405,21 +399,26 @@ static int selinux_create_file_prepare_abspath(const char *abspath, mode_t mode)
if (errno == ENOENT) if (errno == ENOENT)
return 0; return 0;
return log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", abspath); log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", abspath);
} else {
if (setfscreatecon_raw(filecon) >= 0)
return 0; /* Success! */
log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", filecon, abspath);
} }
if (setfscreatecon_raw(filecon) < 0) if (mac_selinux_enforcing())
return log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", filecon, abspath); return -errno;
return 0; return 0;
} }
#endif #endif
int mac_selinux_create_file_prepare_at(int dirfd, const char *path, mode_t mode) { int mac_selinux_create_file_prepare_at(int dirfd, const char *path, mode_t mode) {
int r = 0;
#if HAVE_SELINUX #if HAVE_SELINUX
_cleanup_free_ char *abspath = NULL; _cleanup_free_ char *abspath = NULL;
int r;
assert(path); assert(path);
@ -441,16 +440,15 @@ int mac_selinux_create_file_prepare_at(int dirfd, const char *path, mode_t mode)
return -ENOMEM; return -ENOMEM;
} }
return selinux_create_file_prepare_abspath(path, mode); r = selinux_create_file_prepare_abspath(path, mode);
#else
return 0;
#endif #endif
return r;
} }
int mac_selinux_create_file_prepare(const char *path, mode_t mode) { int mac_selinux_create_file_prepare(const char *path, mode_t mode) {
#if HAVE_SELINUX int r = 0;
int r;
#if HAVE_SELINUX
_cleanup_free_ char *abspath = NULL; _cleanup_free_ char *abspath = NULL;
assert(path); assert(path);
@ -462,10 +460,9 @@ int mac_selinux_create_file_prepare(const char *path, mode_t mode) {
if (r < 0) if (r < 0)
return r; return r;
return selinux_create_file_prepare_abspath(abspath, mode); r = selinux_create_file_prepare_abspath(abspath, mode);
#else
return 0;
#endif #endif
return r;
} }
void mac_selinux_create_file_clear(void) { void mac_selinux_create_file_clear(void) {
@ -483,13 +480,17 @@ void mac_selinux_create_file_clear(void) {
int mac_selinux_create_socket_prepare(const char *label) { int mac_selinux_create_socket_prepare(const char *label) {
#if HAVE_SELINUX #if HAVE_SELINUX
assert(label);
if (!mac_selinux_use()) if (!mac_selinux_use())
return 0; return 0;
if (setsockcreatecon(label) < 0) assert(label);
return log_enforcing_errno(errno, "Failed to set SELinux security context %s for sockets: %m", label);
if (setsockcreatecon(label) < 0) {
log_enforcing_errno(errno, "Failed to set SELinux security context %s for sockets: %m", label);
if (mac_selinux_enforcing())
return -errno;
}
#endif #endif
return 0; return 0;
@ -560,14 +561,15 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
if (errno == ENOENT) if (errno == ENOENT)
goto skipped; goto skipped;
r = log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", path); log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", path);
if (r < 0) if (mac_selinux_enforcing())
return r; return -errno;
} else { } else {
if (setfscreatecon_raw(fcon) < 0) { if (setfscreatecon_raw(fcon) < 0) {
r = log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", fcon, path); log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", fcon, path);
if (r < 0) if (mac_selinux_enforcing())
return r; return -errno;
} else } else
context_changed = true; context_changed = true;
} }
@ -575,7 +577,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
r = bind(fd, addr, addrlen) < 0 ? -errno : 0; r = bind(fd, addr, addrlen) < 0 ? -errno : 0;
if (context_changed) if (context_changed)
(void) setfscreatecon_raw(NULL); setfscreatecon_raw(NULL);
return r; return r;

View File

@ -746,25 +746,6 @@ static int property_get_log_extra_fields(
return sd_bus_message_close_container(reply); return sd_bus_message_close_container(reply);
} }
static int property_get_root_hash(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
ExecContext *c = userdata;
assert(bus);
assert(c);
assert(property);
assert(reply);
return sd_bus_message_append_array(reply, 'y', c->root_hash, c->root_hash_size);
}
const sd_bus_vtable bus_exec_vtable[] = { const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_VTABLE_START(0), SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
@ -807,9 +788,6 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootHash", "ay", property_get_root_hash, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootHashPath", "s", NULL, offsetof(ExecContext, root_hash_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootVerity", "s", NULL, offsetof(ExecContext, root_verity), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CoredumpFilter", "t", property_get_coredump_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("CoredumpFilter", "t", property_get_coredump_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
@ -1280,55 +1258,6 @@ int bus_exec_context_set_transient_property(
if (streq(name, "RootImage")) if (streq(name, "RootImage"))
return bus_set_transient_path(u, name, &c->root_image, message, flags, error); return bus_set_transient_path(u, name, &c->root_image, message, flags, error);
if (streq(name, "RootHash")) {
const void *roothash_decoded;
size_t roothash_decoded_size;
r = sd_bus_message_read_array(message, 'y', &roothash_decoded, &roothash_decoded_size);
if (r < 0)
return r;
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
_cleanup_free_ char *encoded = NULL;
if (roothash_decoded_size == 0) {
c->root_hash_path = mfree(c->root_hash_path);
c->root_hash = mfree(c->root_hash);
c->root_hash_size = 0;
unit_write_settingf(u, flags, name, "RootHash=");
} else {
_cleanup_free_ void *p;
encoded = hexmem(roothash_decoded, roothash_decoded_size);
if (!encoded)
return -ENOMEM;
p = memdup(roothash_decoded, roothash_decoded_size);
if (!p)
return -ENOMEM;
free_and_replace(c->root_hash, p);
c->root_hash_size = roothash_decoded_size;
c->root_hash_path = mfree(c->root_hash_path);
unit_write_settingf(u, flags, name, "RootHash=%s", encoded);
}
}
return 1;
}
if (streq(name, "RootHashPath")) {
c->root_hash_size = 0;
c->root_hash = mfree(c->root_hash);
return bus_set_transient_path(u, "RootHash", &c->root_hash_path, message, flags, error);
}
if (streq(name, "RootVerity"))
return bus_set_transient_path(u, name, &c->root_verity, message, flags, error);
if (streq(name, "RootDirectory")) if (streq(name, "RootDirectory"))
return bus_set_transient_path(u, name, &c->root_directory, message, flags, error); return bus_set_transient_path(u, name, &c->root_directory, message, flags, error);

View File

@ -54,7 +54,6 @@
#include "format-util.h" #include "format-util.h"
#include "fs-util.h" #include "fs-util.h"
#include "glob-util.h" #include "glob-util.h"
#include "hexdecoct.h"
#include "io-util.h" #include "io-util.h"
#include "ioprio.h" #include "ioprio.h"
#include "label.h" #include "label.h"
@ -2667,7 +2666,6 @@ static int apply_mount_namespace(
needs_sandboxing ? context->protect_home : PROTECT_HOME_NO, needs_sandboxing ? context->protect_home : PROTECT_HOME_NO,
needs_sandboxing ? context->protect_system : PROTECT_SYSTEM_NO, needs_sandboxing ? context->protect_system : PROTECT_SYSTEM_NO,
context->mount_flags, context->mount_flags,
context->root_hash, context->root_hash_size, context->root_hash_path, context->root_verity,
DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK, DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK,
error_path); error_path);
@ -4197,10 +4195,6 @@ void exec_context_done(ExecContext *c) {
c->working_directory = mfree(c->working_directory); c->working_directory = mfree(c->working_directory);
c->root_directory = mfree(c->root_directory); c->root_directory = mfree(c->root_directory);
c->root_image = mfree(c->root_image); c->root_image = mfree(c->root_image);
c->root_hash = mfree(c->root_hash);
c->root_hash_size = 0;
c->root_hash_path = mfree(c->root_hash_path);
c->root_verity = mfree(c->root_verity);
c->tty_path = mfree(c->tty_path); c->tty_path = mfree(c->tty_path);
c->syslog_identifier = mfree(c->syslog_identifier); c->syslog_identifier = mfree(c->syslog_identifier);
c->user = mfree(c->user); c->user = mfree(c->user);
@ -4605,19 +4599,6 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
if (c->root_image) if (c->root_image)
fprintf(f, "%sRootImage: %s\n", prefix, c->root_image); fprintf(f, "%sRootImage: %s\n", prefix, c->root_image);
if (c->root_hash) {
_cleanup_free_ char *encoded = NULL;
encoded = hexmem(c->root_hash, c->root_hash_size);
if (encoded)
fprintf(f, "%sRootHash: %s\n", prefix, encoded);
}
if (c->root_hash_path)
fprintf(f, "%sRootHash: %s\n", prefix, c->root_hash_path);
if (c->root_verity)
fprintf(f, "%sRootVerity: %s\n", prefix, c->root_verity);
STRV_FOREACH(e, c->environment) STRV_FOREACH(e, c->environment)
fprintf(f, "%sEnvironment: %s\n", prefix, *e); fprintf(f, "%sEnvironment: %s\n", prefix, *e);

View File

@ -155,9 +155,7 @@ struct ExecContext {
char **unset_environment; char **unset_environment;
struct rlimit *rlimit[_RLIMIT_MAX]; struct rlimit *rlimit[_RLIMIT_MAX];
char *working_directory, *root_directory, *root_image, *root_verity, *root_hash_path; char *working_directory, *root_directory, *root_image;
void *root_hash;
size_t root_hash_size;
bool working_directory_missing_ok:1; bool working_directory_missing_ok:1;
bool working_directory_home:1; bool working_directory_home:1;

View File

@ -387,25 +387,62 @@ JobType job_type_lookup_merge(JobType a, JobType b) {
return job_merging_table[(a - 1) * a / 2 + b]; return job_merging_table[(a - 1) * a / 2 + b];
} }
bool job_type_is_redundant(JobType a, UnitActiveState b) { bool job_later_link_matters(Job *j, JobType type, unsigned generation) {
switch (a) { JobDependency *l;
assert(j);
j->generation = generation;
LIST_FOREACH(subject, l, j->subject_list) {
UnitActiveState state = _UNIT_ACTIVE_STATE_INVALID;
/* Have we seen this before? */
if (l->object->generation == generation)
continue;
state = unit_active_state(l->object->unit);
switch (type) {
case JOB_START: case JOB_START:
return IN_SET(b, UNIT_ACTIVE, UNIT_RELOADING); return IN_SET(state, UNIT_INACTIVE, UNIT_FAILED) ||
job_later_link_matters(l->object, type, generation);
case JOB_STOP: case JOB_STOP:
return IN_SET(b, UNIT_INACTIVE, UNIT_FAILED); return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING) ||
job_later_link_matters(l->object, type, generation);
default:
assert_not_reached("Invalid job type");
}
}
return false;
}
bool job_is_redundant(Job *j, unsigned generation) {
assert(j);
UnitActiveState state = unit_active_state(j->unit);
switch (j->type) {
case JOB_START:
return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING) && !job_later_link_matters(j, JOB_START, generation);
case JOB_STOP:
return IN_SET(state, UNIT_INACTIVE, UNIT_FAILED) && !job_later_link_matters(j, JOB_STOP, generation);
case JOB_VERIFY_ACTIVE: case JOB_VERIFY_ACTIVE:
return IN_SET(b, UNIT_ACTIVE, UNIT_RELOADING); return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING);
case JOB_RELOAD: case JOB_RELOAD:
return return
b == UNIT_RELOADING; state == UNIT_RELOADING;
case JOB_RESTART: case JOB_RESTART:
return return
b == UNIT_ACTIVATING; state == UNIT_ACTIVATING;
case JOB_NOP: case JOB_NOP:
return true; return true;

View File

@ -196,7 +196,8 @@ _pure_ static inline bool job_type_is_superset(JobType a, JobType b) {
return a == job_type_lookup_merge(a, b); return a == job_type_lookup_merge(a, b);
} }
bool job_type_is_redundant(JobType a, UnitActiveState b) _pure_; bool job_later_link_matters(Job *j, JobType type, unsigned generation);
bool job_is_redundant(Job *j, unsigned generation);
/* Collapses a state-dependent job type into a simpler type by observing /* Collapses a state-dependent job type into a simpler type by observing
* the state of the unit which it is going to be applied to. */ * the state of the unit which it is going to be applied to. */

View File

@ -23,8 +23,6 @@ m4_define(`EXEC_CONTEXT_CONFIG_ITEMS',
`$1.WorkingDirectory, config_parse_working_directory, 0, offsetof($1, exec_context) `$1.WorkingDirectory, config_parse_working_directory, 0, offsetof($1, exec_context)
$1.RootDirectory, config_parse_unit_path_printf, true, offsetof($1, exec_context.root_directory) $1.RootDirectory, config_parse_unit_path_printf, true, offsetof($1, exec_context.root_directory)
$1.RootImage, config_parse_unit_path_printf, true, offsetof($1, exec_context.root_image) $1.RootImage, config_parse_unit_path_printf, true, offsetof($1, exec_context.root_image)
$1.RootHash, config_parse_exec_root_hash, 0, offsetof($1, exec_context)
$1.RootVerity, config_parse_unit_path_printf, true, offsetof($1, exec_context.root_verity)
$1.User, config_parse_user_group_compat, 0, offsetof($1, exec_context.user) $1.User, config_parse_user_group_compat, 0, offsetof($1, exec_context.user)
$1.Group, config_parse_user_group_compat, 0, offsetof($1, exec_context.group) $1.Group, config_parse_user_group_compat, 0, offsetof($1, exec_context.group)
$1.SupplementaryGroups, config_parse_user_group_strv_compat, 0, offsetof($1, exec_context.supplementary_groups) $1.SupplementaryGroups, config_parse_user_group_strv_compat, 0, offsetof($1, exec_context.supplementary_groups)

View File

@ -29,7 +29,6 @@
#include "errno-list.h" #include "errno-list.h"
#include "escape.h" #include "escape.h"
#include "fd-util.h" #include "fd-util.h"
#include "fileio.h"
#include "fs-util.h" #include "fs-util.h"
#include "hexdecoct.h" #include "hexdecoct.h"
#include "io-util.h" #include "io-util.h"
@ -1414,64 +1413,6 @@ int config_parse_exec_cpu_sched_prio(const char *unit,
return 0; return 0;
} }
int config_parse_exec_root_hash(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_free_ void *roothash_decoded = NULL;
ExecContext *c = data;
size_t roothash_decoded_size = 0;
int r;
assert(data);
assert(filename);
assert(line);
assert(rvalue);
if (isempty(rvalue)) {
/* Reset if the empty string is assigned */
c->root_hash_path = mfree(c->root_hash_path);
c->root_hash = mfree(c->root_hash);
c->root_hash_size = 0;
return 0;
}
if (path_is_absolute(rvalue)) {
/* We have the path to a roothash to load and decode, eg: RootHash=/foo/bar.roothash */
_cleanup_free_ char *p = NULL;
p = strdup(rvalue);
if (!p)
return -ENOMEM;
free_and_replace(c->root_hash_path, p);
c->root_hash = mfree(c->root_hash);
c->root_hash_size = 0;
return 0;
}
/* We have a roothash to decode, eg: RootHash=012345789abcdef */
r = unhexmem(rvalue, strlen(rvalue), &roothash_decoded, &roothash_decoded_size);
if (r < 0)
return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to decode RootHash=, ignoring: %s", rvalue);
if (roothash_decoded_size < sizeof(sd_id128_t))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "RootHash= is too short, ignoring: %s", rvalue);
free_and_replace(c->root_hash, roothash_decoded);
c->root_hash_size = roothash_decoded_size;
c->root_hash_path = mfree(c->root_hash_path);
return 0;
}
int config_parse_exec_cpu_affinity(const char *unit, int config_parse_exec_cpu_affinity(const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,

View File

@ -44,7 +44,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_sched_policy);
CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_sched_prio); CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_sched_prio);
CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_affinity); CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_affinity);
CONFIG_PARSER_PROTOTYPE(config_parse_exec_secure_bits); CONFIG_PARSER_PROTOTYPE(config_parse_exec_secure_bits);
CONFIG_PARSER_PROTOTYPE(config_parse_exec_root_hash);
CONFIG_PARSER_PROTOTYPE(config_parse_capability_set); CONFIG_PARSER_PROTOTYPE(config_parse_capability_set);
CONFIG_PARSER_PROTOTYPE(config_parse_exec_mount_flags); CONFIG_PARSER_PROTOTYPE(config_parse_exec_mount_flags);
CONFIG_PARSER_PROTOTYPE(config_parse_timer); CONFIG_PARSER_PROTOTYPE(config_parse_timer);

View File

@ -1257,20 +1257,16 @@ int setup_namespace(
ProtectHome protect_home, ProtectHome protect_home,
ProtectSystem protect_system, ProtectSystem protect_system,
unsigned long mount_flags, unsigned long mount_flags,
const void *root_hash,
size_t root_hash_size,
const char *root_hash_path,
const char *root_verity,
DissectImageFlags dissect_image_flags, DissectImageFlags dissect_image_flags,
char **error_path) { char **error_path) {
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL; _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL; _cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
_cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL; _cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
_cleanup_free_ void *root_hash_decoded = NULL; _cleanup_free_ void *root_hash = NULL;
_cleanup_free_ char *verity_data = NULL; _cleanup_free_ char *verity_data = NULL;
MountEntry *m = NULL, *mounts = NULL; MountEntry *m = NULL, *mounts = NULL;
size_t n_mounts; size_t n_mounts, root_hash_size = 0;
bool require_prefix = false; bool require_prefix = false;
const char *root; const char *root;
int r = 0; int r = 0;
@ -1299,16 +1295,16 @@ int setup_namespace(
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to create loop device for root image: %m"); return log_debug_errno(r, "Failed to create loop device for root image: %m");
r = verity_metadata_load(root_image, root_hash_path, root_hash ? NULL : &root_hash_decoded, root_hash ? NULL : &root_hash_size, root_verity ? NULL : &verity_data); r = verity_metadata_load(root_image, &root_hash, &root_hash_size, &verity_data);
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to load root hash: %m"); return log_debug_errno(r, "Failed to load root hash: %m");
dissect_image_flags |= root_verity || verity_data ? DISSECT_IMAGE_NO_PARTITION_TABLE : 0; dissect_image_flags |= verity_data ? DISSECT_IMAGE_NO_PARTITION_TABLE : 0;
r = dissect_image(loop_device->fd, root_hash ?: root_hash_decoded, root_hash_size, root_verity ?: verity_data, dissect_image_flags, &dissected_image); r = dissect_image(loop_device->fd, root_hash, root_hash_size, verity_data, dissect_image_flags, &dissected_image);
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to dissect image: %m"); return log_debug_errno(r, "Failed to dissect image: %m");
r = dissected_image_decrypt(dissected_image, NULL, root_hash ?: root_hash_decoded, root_hash_size, root_verity ?: verity_data, dissect_image_flags, &decrypted_image); r = dissected_image_decrypt(dissected_image, NULL, root_hash, root_hash_size, verity_data, dissect_image_flags, &decrypted_image);
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to decrypt dissected image: %m"); return log_debug_errno(r, "Failed to decrypt dissected image: %m");
} }

View File

@ -88,10 +88,6 @@ int setup_namespace(
ProtectHome protect_home, ProtectHome protect_home,
ProtectSystem protect_system, ProtectSystem protect_system,
unsigned long mount_flags, unsigned long mount_flags,
const void *root_hash,
size_t root_hash_size,
const char *root_hash_path,
const char *root_verity,
DissectImageFlags dissected_image_flags, DissectImageFlags dissected_image_flags,
char **error_path); char **error_path);

View File

@ -279,7 +279,7 @@ static int transaction_merge_jobs(Transaction *tr, sd_bus_error *e) {
return 0; return 0;
} }
static void transaction_drop_redundant(Transaction *tr) { static void transaction_drop_redundant(Transaction *tr, unsigned generation) {
bool again; bool again;
/* Goes through the transaction and removes all jobs of the units whose jobs are all noops. If not /* Goes through the transaction and removes all jobs of the units whose jobs are all noops. If not
@ -299,7 +299,7 @@ static void transaction_drop_redundant(Transaction *tr) {
LIST_FOREACH(transaction, k, j) LIST_FOREACH(transaction, k, j)
if (tr->anchor_job == k || if (tr->anchor_job == k ||
!job_type_is_redundant(k->type, unit_active_state(k->unit)) || !job_is_redundant(k, generation) ||
(k->unit->job && job_type_is_conflicting(k->type, k->unit->job->type))) { (k->unit->job && job_type_is_conflicting(k->type, k->unit->job->type))) {
keep = true; keep = true;
break; break;
@ -735,7 +735,7 @@ int transaction_activate(
transaction_minimize_impact(tr); transaction_minimize_impact(tr);
/* Third step: Drop redundant jobs */ /* Third step: Drop redundant jobs */
transaction_drop_redundant(tr); transaction_drop_redundant(tr, generation++);
for (;;) { for (;;) {
/* Fourth step: Let's remove unneeded jobs that might /* Fourth step: Let's remove unneeded jobs that might
@ -777,7 +777,7 @@ int transaction_activate(
} }
/* Eights step: Drop redundant jobs again, if the merging now allows us to drop more. */ /* Eights step: Drop redundant jobs again, if the merging now allows us to drop more. */
transaction_drop_redundant(tr); transaction_drop_redundant(tr, generation++);
/* Ninth step: check whether we can actually apply this */ /* Ninth step: check whether we can actually apply this */
r = transaction_is_destructive(tr, mode, e); r = transaction_is_destructive(tr, mode, e);

View File

@ -201,7 +201,7 @@ static int run(int argc, char *argv[]) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to set up loopback device: %m"); return log_error_errno(r, "Failed to set up loopback device: %m");
r = verity_metadata_load(arg_image, NULL, arg_root_hash ? NULL : &arg_root_hash, &arg_root_hash_size, r = verity_metadata_load(arg_image, arg_root_hash ? NULL : &arg_root_hash, &arg_root_hash_size,
arg_verity_data ? NULL : &arg_verity_data); arg_verity_data ? NULL : &arg_verity_data);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to read verity artefacts for %s: %m", arg_image); return log_error_errno(r, "Failed to read verity artefacts for %s: %m", arg_image);

View File

@ -619,9 +619,9 @@ int mount_all(const char *dest,
#if HAVE_SELINUX #if HAVE_SELINUX
{ "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND, { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND,
MOUNT_MKDIR }, /* Bind mount first (mkdir/chown the mount point in case /sys/ is mounted as minimal skeleton tmpfs) */ 0 }, /* Bind mount first */
{ NULL, "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, { NULL, "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT,
0 }, /* Then, make it r/o (don't mkdir/chown the mount point here, the previous entry already did that) */ 0 }, /* Then, make it r/o */
#endif #endif
}; };

View File

@ -5141,7 +5141,7 @@ static int run(int argc, char *argv[]) {
goto finish; goto finish;
} }
r = verity_metadata_load(arg_image, NULL, arg_root_hash ? NULL : &arg_root_hash, &arg_root_hash_size, r = verity_metadata_load(arg_image, arg_root_hash ? NULL : &arg_root_hash, &arg_root_hash_size,
arg_verity_data ? NULL : &arg_verity_data); arg_verity_data ? NULL : &arg_verity_data);
if (r < 0) { if (r < 0) {
log_error_errno(r, "Failed to read verity artefacts for %s: %m", arg_image); log_error_errno(r, "Failed to read verity artefacts for %s: %m", arg_image);

View File

@ -13,7 +13,6 @@
#include "escape.h" #include "escape.h"
#include "exec-util.h" #include "exec-util.h"
#include "exit-status.h" #include "exit-status.h"
#include "fileio.h"
#include "hexdecoct.h" #include "hexdecoct.h"
#include "hostname-util.h" #include "hostname-util.h"
#include "in-addr-util.h" #include "in-addr-util.h"
@ -25,7 +24,6 @@
#include "nsflags.h" #include "nsflags.h"
#include "numa-util.h" #include "numa-util.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h"
#include "process-util.h" #include "process-util.h"
#include "rlimit-util.h" #include "rlimit-util.h"
#include "securebits-util.h" #include "securebits-util.h"
@ -851,7 +849,6 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
"ProtectHome", "ProtectHome",
"SELinuxContext", "SELinuxContext",
"RootImage", "RootImage",
"RootVerity",
"RuntimeDirectoryPreserve", "RuntimeDirectoryPreserve",
"Personality", "Personality",
"KeyringMode", "KeyringMode",
@ -1418,24 +1415,6 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
return 1; return 1;
} }
if (streq(field, "RootHash")) {
_cleanup_free_ void *roothash_decoded = NULL;
size_t roothash_decoded_size = 0;
/* We have the path to a roothash to load and decode, eg: RootHash=/foo/bar.roothash */
if (path_is_absolute(eq))
return bus_append_string(m, "RootHashPath", eq);
/* We have a roothash to decode, eg: RootHash=012345789abcdef */
r = unhexmem(eq, strlen(eq), &roothash_decoded, &roothash_decoded_size);
if (r < 0)
return log_error_errno(r, "Failed to decode RootHash= '%s': %m", eq);
if (roothash_decoded_size < sizeof(sd_id128_t))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "RootHash= '%s' is too short: %m", eq);
return bus_append_byte_array(m, field, roothash_decoded, roothash_decoded_size);
}
return 0; return 0;
} }

View File

@ -1421,7 +1421,7 @@ int decrypted_image_relinquish(DecryptedImage *d) {
return 0; return 0;
} }
int verity_metadata_load(const char *image, const char *root_hash_path, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data) { int verity_metadata_load(const char *image, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data) {
_cleanup_free_ char *verity_filename = NULL; _cleanup_free_ char *verity_filename = NULL;
_cleanup_free_ void *roothash_decoded = NULL; _cleanup_free_ void *roothash_decoded = NULL;
size_t roothash_decoded_size = 0; size_t roothash_decoded_size = 0;
@ -1465,12 +1465,6 @@ int verity_metadata_load(const char *image, const char *root_hash_path, void **r
_cleanup_free_ char *text = NULL; _cleanup_free_ char *text = NULL;
assert(ret_roothash_size); assert(ret_roothash_size);
if (root_hash_path) {
/* We have the path to a roothash to load and decode, eg: RootHash=/foo/bar.roothash */
r = read_one_line_file(root_hash_path, &text);
if (r < 0)
return r;
} else {
r = getxattr_malloc(image, "user.verity.roothash", &text, true); r = getxattr_malloc(image, "user.verity.roothash", &text, true);
if (r < 0) { if (r < 0) {
char *fn, *e, *n; char *fn, *e, *n;
@ -1490,7 +1484,6 @@ int verity_metadata_load(const char *image, const char *root_hash_path, void **r
if (r < 0 && r != -ENOENT) if (r < 0 && r != -ENOENT)
return r; return r;
} }
}
if (text) { if (text) {
r = unhexmem(text, strlen(text), &roothash_decoded, &roothash_decoded_size); r = unhexmem(text, strlen(text), &roothash_decoded, &roothash_decoded_size);

View File

@ -100,6 +100,6 @@ int decrypted_image_relinquish(DecryptedImage *d);
const char* partition_designator_to_string(int i) _const_; const char* partition_designator_to_string(int i) _const_;
int partition_designator_from_string(const char *name) _pure_; int partition_designator_from_string(const char *name) _pure_;
int verity_metadata_load(const char *image, const char *root_hash_path, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data); int verity_metadata_load(const char *image, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data);
bool dissected_image_can_do_verity(const DissectedImage *image, unsigned partition_designator); bool dissected_image_can_do_verity(const DissectedImage *image, unsigned partition_designator);
bool dissected_image_has_verity(const DissectedImage *image, unsigned partition_designator); bool dissected_image_has_verity(const DissectedImage *image, unsigned partition_designator);

View File

@ -152,10 +152,6 @@ static void test_protect_kernel_logs(void) {
PROTECT_HOME_NO, PROTECT_HOME_NO,
PROTECT_SYSTEM_NO, PROTECT_SYSTEM_NO,
0, 0,
NULL,
0,
NULL,
NULL,
0, 0,
NULL); NULL);
assert_se(r == 0); assert_se(r == 0);

View File

@ -76,10 +76,6 @@ int main(int argc, char *argv[]) {
PROTECT_HOME_NO, PROTECT_HOME_NO,
PROTECT_SYSTEM_NO, PROTECT_SYSTEM_NO,
0, 0,
NULL,
0,
NULL,
NULL,
0, 0,
NULL); NULL);
if (r < 0) { if (r < 0) {

View File

@ -196,8 +196,6 @@ ReusePort=
RootDirectory= RootDirectory=
RootDirectoryStartOnly= RootDirectoryStartOnly=
RootImage= RootImage=
RootHash=
RootVerity=
RuntimeMaxSec= RuntimeMaxSec=
SELinuxContextFromNet= SELinuxContextFromNet=
SecureBits= SecureBits=

View File

@ -935,7 +935,7 @@ install_config_files() {
inst /etc/login.defs inst /etc/login.defs
inst /etc/group inst /etc/group
inst /etc/shells inst /etc/shells
inst_any /etc/nsswitch.conf /usr/etc/nsswitch.conf inst /etc/nsswitch.conf
inst /etc/pam.conf || : inst /etc/pam.conf || :
inst /etc/os-release inst /etc/os-release
inst /etc/localtime inst /etc/localtime

View File

@ -9,25 +9,23 @@
# export CONT_NAME="my-fancy-container" # export CONT_NAME="my-fancy-container"
# travis-ci/managers/debian.sh SETUP RUN CLEANUP # travis-ci/managers/debian.sh SETUP RUN CLEANUP
PHASES=(${@:-SETUP RUN RUN_ASAN_UBSAN CLEANUP}) PHASES=(${@:-SETUP RUN RUN_ASAN CLEANUP})
DEBIAN_RELEASE="${DEBIAN_RELEASE:-testing}" DEBIAN_RELEASE="${DEBIAN_RELEASE:-testing}"
CONT_NAME="${CONT_NAME:-systemd-debian-$DEBIAN_RELEASE}" CONT_NAME="${CONT_NAME:-debian-$DEBIAN_RELEASE-$RANDOM}"
DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}" DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}"
DOCKER_RUN="${DOCKER_RUN:-docker run}" DOCKER_RUN="${DOCKER_RUN:-docker run}"
REPO_ROOT="${REPO_ROOT:-$PWD}" REPO_ROOT="${REPO_ROOT:-$PWD}"
ADDITIONAL_DEPS=( ADDITIONAL_DEPS=(python3-libevdev
python3-pyparsing
clang clang
perl
libpwquality-dev
fdisk fdisk
libfdisk-dev libfdisk-dev
libp11-kit-dev libp11-kit-dev
libpwquality-dev
libssl-dev libssl-dev
libzstd-dev libzstd-dev
perl zstd)
python3-libevdev
python3-pyparsing
zstd
)
function info() { function info() {
echo -e "\033[33;1m$1\033[0m" echo -e "\033[33;1m$1\033[0m"
@ -56,7 +54,7 @@ for phase in "${PHASES[@]}"; do
$DOCKER_EXEC apt-get -y build-dep systemd $DOCKER_EXEC apt-get -y build-dep systemd
$DOCKER_EXEC apt-get -y install "${ADDITIONAL_DEPS[@]}" $DOCKER_EXEC apt-get -y install "${ADDITIONAL_DEPS[@]}"
;; ;;
RUN|RUN_GCC|RUN_CLANG) RUN|RUN_CLANG)
if [[ "$phase" = "RUN_CLANG" ]]; then if [[ "$phase" = "RUN_CLANG" ]]; then
ENV_VARS="-e CC=clang -e CXX=clang++" ENV_VARS="-e CC=clang -e CXX=clang++"
fi fi
@ -64,8 +62,8 @@ for phase in "${PHASES[@]}"; do
$DOCKER_EXEC ninja -v -C build $DOCKER_EXEC ninja -v -C build
docker exec -e "TRAVIS=$TRAVIS" -it $CONT_NAME ninja -C build test docker exec -e "TRAVIS=$TRAVIS" -it $CONT_NAME ninja -C build test
;; ;;
RUN_ASAN_UBSAN|RUN_GCC_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN) RUN_ASAN|RUN_CLANG_ASAN)
if [[ "$phase" = "RUN_CLANG_ASAN_UBSAN" ]]; then if [[ "$phase" = "RUN_CLANG_ASAN" ]]; then
ENV_VARS="-e CC=clang -e CXX=clang++" ENV_VARS="-e CC=clang -e CXX=clang++"
# Build fuzzer regression tests only with clang (for now), # Build fuzzer regression tests only with clang (for now),
# see: https://github.com/systemd/systemd/pull/15886#issuecomment-632689604 # see: https://github.com/systemd/systemd/pull/15886#issuecomment-632689604

View File

@ -9,32 +9,38 @@
# export CONT_NAME="my-fancy-container" # export CONT_NAME="my-fancy-container"
# travis-ci/managers/fedora.sh SETUP RUN CLEANUP # travis-ci/managers/fedora.sh SETUP RUN CLEANUP
PHASES=(${@:-SETUP RUN RUN_ASAN_UBSAN CLEANUP}) PHASES=(${@:-SETUP RUN RUN_ASAN CLEANUP})
FEDORA_RELEASE="${FEDORA_RELEASE:-rawhide}" FEDORA_RELEASE="${FEDORA_RELEASE:-rawhide}"
CONT_NAME="${CONT_NAME:-systemd-fedora-$FEDORA_RELEASE}" CONT_NAME="${CONT_NAME:-fedora-$FEDORA_RELEASE-$RANDOM}"
DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}" DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}"
DOCKER_RUN="${DOCKER_RUN:-docker run}" DOCKER_RUN="${DOCKER_RUN:-docker run}"
REPO_ROOT="${REPO_ROOT:-$PWD}" REPO_ROOT="${REPO_ROOT:-$PWD}"
ADDITIONAL_DEPS=( ADDITIONAL_DEPS=(dnf-plugins-core
clang
dnf-plugins-core
hostname libasan
jq iputils jq iputils
hostname libasan
python3-pyparsing
python3-evdev
libubsan
clang
llvm
perl
libfdisk-devel libfdisk-devel
libpwquality-devel libpwquality-devel
libubsan
llvm
openssl-devel openssl-devel
p11-kit-devel p11-kit-devel)
perl
python3-evdev
python3-pyparsing
)
info() { info() {
echo -e "\033[33;1m$1\033[0m" echo -e "\033[33;1m$1\033[0m"
} }
error() {
echo >&2 -e "\033[31;1m$1\033[0m"
}
success() {
echo >&2 -e "\033[32;1m$1\033[0m"
}
# Simple wrapper which retries given command up to five times # Simple wrapper which retries given command up to five times
_retry() { _retry() {
local EC=1 local EC=1
@ -88,8 +94,8 @@ for phase in "${PHASES[@]}"; do
$DOCKER_EXEC ninja -v -C build $DOCKER_EXEC ninja -v -C build
$DOCKER_EXEC ninja -C build test $DOCKER_EXEC ninja -C build test
;; ;;
RUN_ASAN|RUN_GCC_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN) RUN_ASAN|RUN_CLANG_ASAN)
if [[ "$phase" = "RUN_CLANG_ASAN_UBSAN" ]]; then if [[ "$phase" = "RUN_CLANG_ASAN" ]]; then
ENV_VARS="-e CC=clang -e CXX=clang++" ENV_VARS="-e CC=clang -e CXX=clang++"
MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764 MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764
fi fi
@ -104,6 +110,46 @@ for phase in "${PHASES[@]}"; do
-t $CONT_NAME \ -t $CONT_NAME \
meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs
;; ;;
RUN_BUILD_CHECK_GCC|RUN_BUILD_CHECK_CLANG)
ARGS=(
"--optimization=0"
"--optimization=2"
"--optimization=3"
"--optimization=s"
"-Db_lto=true"
"-Db_ndebug=true"
)
if [[ "$phase" = "RUN_BUILD_CHECK_CLANG" ]]; then
ENV_VARS="-e CC=clang -e CXX=clang++"
$DOCKER_EXEC clang --version
else
$DOCKER_EXEC gcc --version
fi
for args in "${ARGS[@]}"; do
SECONDS=0
info "Checking build with $args"
# Redirect meson/ninja logs into separate files, otherwise we
# would trip over Travis' log size limit
if ! docker exec $ENV_VARS -it $CONT_NAME meson --werror $args build &> meson.log; then
cat meson.log
error "meson failed with $args"
exit 1
fi
if ! $DOCKER_EXEC ninja -v -C build &> ninja.log; then
cat ninja.log
error "ninja failed with $args"
exit 1
fi
$DOCKER_EXEC rm -fr build
rm -f meson.log ninja.log
success "Build with $args passed in $SECONDS seconds"
done
;;
CLEANUP) CLEANUP)
info "Cleanup phase" info "Cleanup phase"
docker stop $CONT_NAME docker stop $CONT_NAME