Compare commits
No commits in common. "cc479760b4736082d26ec332f2423a9ab23d59c5" and "2edc4942163fa12b5c5da5427cbe01ad87ff8dc4" have entirely different histories.
cc479760b4
...
2edc494216
187
.travis.yml
187
.travis.yml
|
@ -1,82 +1,127 @@
|
|||
---
|
||||
# vi: ts=2 sw=2 et:
|
||||
|
||||
language: bash
|
||||
sudo: required
|
||||
dist: bionic
|
||||
services:
|
||||
- docker
|
||||
- docker
|
||||
|
||||
env:
|
||||
global:
|
||||
- AUTHOR_EMAIL="$(git log -1 $TRAVIS_COMMIT --pretty=\"%aE\")"
|
||||
- CI_MANAGERS="$TRAVIS_BUILD_DIR/travis-ci/managers"
|
||||
- CI_TOOLS="$TRAVIS_BUILD_DIR/travis-ci/tools"
|
||||
- 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"
|
||||
global:
|
||||
- AUTHOR_EMAIL="$(git log -1 $TRAVIS_COMMIT --pretty=\"%aE\")"
|
||||
- CI_MANAGERS="$TRAVIS_BUILD_DIR/travis-ci/managers"
|
||||
- CI_TOOLS="$TRAVIS_BUILD_DIR/travis-ci/tools"
|
||||
- REPO_ROOT="$TRAVIS_BUILD_DIR"
|
||||
|
||||
stages:
|
||||
# 'Test' is the default stage (for matrix jobs)
|
||||
- name: Test
|
||||
if: type != cron
|
||||
- name: Build & test
|
||||
if: type != cron
|
||||
|
||||
# Run Coverity periodically instead of for each commit/PR
|
||||
- name: Coverity
|
||||
if: type = cron
|
||||
- name: Coverity
|
||||
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:
|
||||
include:
|
||||
- stage: Coverity
|
||||
language: bash
|
||||
env:
|
||||
- FEDORA_RELEASE="latest"
|
||||
- TOOL_BASE="/var/tmp/coverity-scan-analysis"
|
||||
- DOCKER_RUN="docker run -v $TOOL_BASE:$TOOL_BASE:rw --env-file .cov-env"
|
||||
# Coverity env variables
|
||||
- PLATFORM="$(uname)"
|
||||
- TOOL_ARCHIVE="/var/tmp/cov-analysis-$PLATFORM.tgz"
|
||||
- SCAN_URL="https://scan.coverity.com"
|
||||
- UPLOAD_URL="https://scan.coverity.com/builds"
|
||||
- COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG"
|
||||
- COVERITY_SCAN_NOTIFICATION_EMAIL="${AUTHOR_EMAIL}"
|
||||
- COVERITY_SCAN_BRANCH_PATTERN="$TRAVIS_BRANCH"
|
||||
# Encrypted COVERITY_SCAN_TOKEN env variable
|
||||
# Generated using `travis encrypt -r systemd/systemd COVERITY_SCAN_TOKEN=xxxx`
|
||||
- secure: "jKSz+Y1Mv8xMpQHh7g5lzW7E6HQGndFz/vKDJQ1CVShwFoyjV3Zu+MFS3UYKlh1236zL0Z4dvsYFx/b3Hq8nxZWCrWeZs2NdXgy/wh8LZhxwzcGYigp3sIA/cYdP5rDjFJO0MasNkl25/rml8+eZWz+8/xQic98UQHjSco/EOWtssoRcg0J0c4eDM7bGLfIQWE73NNY1Q1UtWjKmx1kekVrM8dPmHXJ9aERka7bmcbJAcKd6vabs6DQ5AfWccUPIn/EsRYqIJTRxJrFYU6XizANZ1a7Vwk/DWHZUEn2msxcZw5BbAMDTMx0TbfrNkKSHMHuvQUCu6KCBAq414i+LgkMfmQ2SWwKiIUsud1kxXX3ZPl9bxDv1HkvVdcniC/EM7lNEEVwm4meOnjuhI2lhOyOjmP3FTSlMHGP7xlK8DS2k9fqL58vn0BaSjwWgd+2+HuL2+nJmxcK1eLGzKqaostFxrk2Xs2vPZkUdV2nWY/asUrcWHml6YlWDn2eP83pfwxHYsMiEHY/rTKvxeVY+iirO/AphoO+eaYu7LvjKZU1Yx5Z4u/SnGWAiCH0yhMis0bWmgi7SCbw+sDd2uya+aoiLIGiB2ChW7hXHXCue/dif6/gLU7b+L8R00pQwnWdvKUPoIJCmZJYCluTeib4jpW+EmARB2+nR8wms2K9FGKM="
|
||||
before_install:
|
||||
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
||||
- docker --version
|
||||
install:
|
||||
# Install Coverity on the host
|
||||
- $CI_TOOLS/get-coverity.sh
|
||||
# Export necessary env variables for Coverity
|
||||
- env | grep -E "TRAVIS|COV|TOOL|URL" > .cov-env
|
||||
# Pull a Docker image and start a new container
|
||||
- $CI_MANAGERS/fedora.sh SETUP
|
||||
script:
|
||||
- set -e
|
||||
# Preconfigure with meson to prevent Coverity from capturing meson metadata
|
||||
- $DOCKER_EXEC meson cov-build -Dman=false
|
||||
# Run Coverity
|
||||
- $DOCKER_EXEC tools/coverity.sh build
|
||||
- $DOCKER_EXEC tools/coverity.sh upload
|
||||
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
|
||||
|
||||
- set +e
|
||||
after_script:
|
||||
- $CI_MANAGERS/fedora.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
|
||||
language: bash
|
||||
env:
|
||||
- FEDORA_RELEASE="latest"
|
||||
- CONT_NAME="coverity-fedora-$FEDORA_RELEASE"
|
||||
- DOCKER_EXEC="docker exec -ti $CONT_NAME"
|
||||
- TOOL_BASE="/var/tmp/coverity-scan-analysis"
|
||||
- DOCKER_RUN="docker run -v $TOOL_BASE:$TOOL_BASE:rw --env-file .cov-env"
|
||||
# Coverity env variables
|
||||
- PLATFORM="$(uname)"
|
||||
- TOOL_ARCHIVE="/var/tmp/cov-analysis-$PLATFORM.tgz"
|
||||
- SCAN_URL="https://scan.coverity.com"
|
||||
- UPLOAD_URL="https://scan.coverity.com/builds"
|
||||
- COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG"
|
||||
- COVERITY_SCAN_NOTIFICATION_EMAIL="${AUTHOR_EMAIL}"
|
||||
- COVERITY_SCAN_BRANCH_PATTERN="$TRAVIS_BRANCH"
|
||||
# Encrypted COVERITY_SCAN_TOKEN env variable
|
||||
# Generated using `travis encrypt -r systemd/systemd COVERITY_SCAN_TOKEN=xxxx`
|
||||
- secure: "jKSz+Y1Mv8xMpQHh7g5lzW7E6HQGndFz/vKDJQ1CVShwFoyjV3Zu+MFS3UYKlh1236zL0Z4dvsYFx/b3Hq8nxZWCrWeZs2NdXgy/wh8LZhxwzcGYigp3sIA/cYdP5rDjFJO0MasNkl25/rml8+eZWz+8/xQic98UQHjSco/EOWtssoRcg0J0c4eDM7bGLfIQWE73NNY1Q1UtWjKmx1kekVrM8dPmHXJ9aERka7bmcbJAcKd6vabs6DQ5AfWccUPIn/EsRYqIJTRxJrFYU6XizANZ1a7Vwk/DWHZUEn2msxcZw5BbAMDTMx0TbfrNkKSHMHuvQUCu6KCBAq414i+LgkMfmQ2SWwKiIUsud1kxXX3ZPl9bxDv1HkvVdcniC/EM7lNEEVwm4meOnjuhI2lhOyOjmP3FTSlMHGP7xlK8DS2k9fqL58vn0BaSjwWgd+2+HuL2+nJmxcK1eLGzKqaostFxrk2Xs2vPZkUdV2nWY/asUrcWHml6YlWDn2eP83pfwxHYsMiEHY/rTKvxeVY+iirO/AphoO+eaYu7LvjKZU1Yx5Z4u/SnGWAiCH0yhMis0bWmgi7SCbw+sDd2uya+aoiLIGiB2ChW7hXHXCue/dif6/gLU7b+L8R00pQwnWdvKUPoIJCmZJYCluTeib4jpW+EmARB2+nR8wms2K9FGKM="
|
||||
before_install:
|
||||
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
||||
- docker --version
|
||||
install:
|
||||
# Install Coverity on the host
|
||||
- $CI_TOOLS/get-coverity.sh
|
||||
# Export necessary env variables for Coverity
|
||||
- env | grep -E "TRAVIS|COV|TOOL|URL" > .cov-env
|
||||
# Pull a Docker image and start a new container
|
||||
- $CI_MANAGERS/fedora.sh SETUP
|
||||
script:
|
||||
- set -e
|
||||
# Preconfigure with meson to prevent Coverity from capturing meson metadata
|
||||
- $DOCKER_EXEC meson cov-build -Dman=false
|
||||
# Run Coverity
|
||||
- $DOCKER_EXEC tools/coverity.sh build
|
||||
- $DOCKER_EXEC tools/coverity.sh upload
|
||||
|
||||
- set +e
|
||||
after_script:
|
||||
- $CI_MANAGERS/fedora.sh CLEANUP
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
<xsl:template match="citerefentry[not(@project)]">
|
||||
<a>
|
||||
<xsl:attribute name="href">
|
||||
<xsl:value-of select="refentrytitle"/>
|
||||
<xsl:text>.html#</xsl:text>
|
||||
<xsl:value-of select="refentrytitle"/><xsl:text>.html#</xsl:text>
|
||||
<xsl:value-of select="refentrytitle/@target"/>
|
||||
</xsl:attribute>
|
||||
<xsl:call-template name="inline.charseq"/>
|
||||
|
@ -134,15 +133,6 @@
|
|||
</a>
|
||||
</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
|
||||
- this conflict resolution is necessary to prevent malformed HTML output (multiple ID attributes with the same value)
|
||||
|
|
|
@ -51,8 +51,7 @@
|
|||
<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
|
||||
contain a file system or other content, it will execute binaries specific to
|
||||
each filesystem type (<filename>/sbin/mkfs.<replaceable>type</replaceable></filename>
|
||||
or <filename>/sbin/mkswap</filename>).</para>
|
||||
each filesystem type (<filename>/sbin/mkfs.<replaceable>type</replaceable></filename>).</para>
|
||||
|
||||
<para><filename>systemd-growfs</filename> knows very little about specific file
|
||||
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.
|
||||
Currently:
|
||||
<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>,
|
||||
<!-- yes, that's what the man page is called. -->
|
||||
and dm-crypt partitions (see
|
||||
|
|
|
@ -145,43 +145,6 @@
|
|||
<xi:include href="system-only.xml" xpointer="singular"/></listitem>
|
||||
</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>
|
||||
<term><varname>MountAPIVFS=</varname></term>
|
||||
|
||||
|
|
|
@ -39,18 +39,7 @@ static int cached_enforcing = -1;
|
|||
static struct selabel_handle *label_hnd = NULL;
|
||||
|
||||
#define log_enforcing(...) log_full(mac_selinux_enforcing() ? LOG_ERR : LOG_WARNING, __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; \
|
||||
})
|
||||
#define log_enforcing_errno(r, ...) log_full_errno(mac_selinux_enforcing() ? LOG_ERR : LOG_WARNING, r, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
bool mac_selinux_use(void) {
|
||||
|
@ -70,15 +59,14 @@ bool mac_selinux_enforcing(void) {
|
|||
#if HAVE_SELINUX
|
||||
if (_unlikely_(cached_enforcing < 0)) {
|
||||
cached_enforcing = security_getenforce();
|
||||
if (cached_enforcing < 0) {
|
||||
log_debug_errno(errno, "Failed to get SELinux enforced status, continuing in enforcing mode: %m");
|
||||
return true; /* treat failure as enforcing mode */
|
||||
}
|
||||
|
||||
log_debug("SELinux enforcing state cached to: %s", cached_enforcing ? "enforcing" : "permissive");
|
||||
if (cached_enforcing == -1)
|
||||
log_error_errno(errno, "Failed to get SELinux enforced status, continue in enforcing mode: %m");
|
||||
else
|
||||
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
|
||||
return false;
|
||||
#endif
|
||||
|
@ -102,11 +90,11 @@ static int setenforce_callback(int enforcing) {
|
|||
#endif
|
||||
|
||||
int mac_selinux_init(void) {
|
||||
int r = 0;
|
||||
|
||||
#if HAVE_SELINUX
|
||||
usec_t before_timestamp, after_timestamp;
|
||||
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_SETENFORCE, (union selinux_callback) setenforce_callback);
|
||||
|
@ -121,20 +109,25 @@ int mac_selinux_init(void) {
|
|||
before_timestamp = now(CLOCK_MONOTONIC);
|
||||
|
||||
label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
|
||||
if (!label_hnd)
|
||||
return log_enforcing_errno(errno, "Failed to initialize SELinux context: %m");
|
||||
if (!label_hnd) {
|
||||
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_mallinfo = mallinfo();
|
||||
after_timestamp = now(CLOCK_MONOTONIC);
|
||||
after_mallinfo = mallinfo();
|
||||
|
||||
l = after_mallinfo.uordblks > before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0;
|
||||
|
||||
log_debug("Successfully loaded SELinux database in %s, size on heap is %iK.",
|
||||
format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0),
|
||||
(l+1023)/1024);
|
||||
l = after_mallinfo.uordblks > before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0;
|
||||
|
||||
log_debug("Successfully loaded SELinux database in %s, size on heap is %iK.",
|
||||
format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0),
|
||||
(l+1023)/1024);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void mac_selinux_finish(void) {
|
||||
|
@ -233,7 +226,9 @@ int mac_selinux_fix_container(const char *path, const char *inside_path, LabelFi
|
|||
return 0;
|
||||
|
||||
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
|
||||
|
||||
return 0;
|
||||
|
@ -248,17 +243,21 @@ int mac_selinux_apply(const char *path, const char *label) {
|
|||
assert(path);
|
||||
assert(label);
|
||||
|
||||
if (setfilecon(path, label) < 0)
|
||||
return log_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, path);
|
||||
if (setfilecon(path, label) < 0) {
|
||||
log_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, path);
|
||||
if (mac_selinux_enforcing())
|
||||
return -errno;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mac_selinux_get_create_label_from_exe(const char *exe, char **label) {
|
||||
int r = -EOPNOTSUPP;
|
||||
|
||||
#if HAVE_SELINUX
|
||||
_cleanup_freecon_ char *mycon = NULL, *fcon = NULL;
|
||||
security_class_t sclass;
|
||||
int r;
|
||||
|
||||
assert(exe);
|
||||
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);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int mac_selinux_get_our_label(char **label) {
|
||||
#if HAVE_SELINUX
|
||||
int r;
|
||||
int r = -EOPNOTSUPP;
|
||||
|
||||
assert(label);
|
||||
|
||||
#if HAVE_SELINUX
|
||||
if (!mac_selinux_use())
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
r = getcon_raw(label);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
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
|
||||
_cleanup_freecon_ char *mycon = NULL, *peercon = NULL, *fcon = NULL;
|
||||
_cleanup_context_free_ context_t pcon = NULL, bcon = NULL;
|
||||
security_class_t sclass;
|
||||
const char *range = NULL;
|
||||
int r;
|
||||
|
||||
assert(socket_fd >= 0);
|
||||
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);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
#endif
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
return log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", filecon, abspath);
|
||||
if (mac_selinux_enforcing())
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int mac_selinux_create_file_prepare_at(int dirfd, const char *path, mode_t mode) {
|
||||
int r = 0;
|
||||
|
||||
#if HAVE_SELINUX
|
||||
_cleanup_free_ char *abspath = NULL;
|
||||
int r;
|
||||
|
||||
|
||||
assert(path);
|
||||
|
||||
|
@ -441,16 +440,15 @@ int mac_selinux_create_file_prepare_at(int dirfd, const char *path, mode_t mode)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return selinux_create_file_prepare_abspath(path, mode);
|
||||
#else
|
||||
return 0;
|
||||
r = selinux_create_file_prepare_abspath(path, mode);
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
int mac_selinux_create_file_prepare(const char *path, mode_t mode) {
|
||||
#if HAVE_SELINUX
|
||||
int r;
|
||||
int r = 0;
|
||||
|
||||
#if HAVE_SELINUX
|
||||
_cleanup_free_ char *abspath = NULL;
|
||||
|
||||
assert(path);
|
||||
|
@ -462,10 +460,9 @@ int mac_selinux_create_file_prepare(const char *path, mode_t mode) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return selinux_create_file_prepare_abspath(abspath, mode);
|
||||
#else
|
||||
return 0;
|
||||
r = selinux_create_file_prepare_abspath(abspath, mode);
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
#if HAVE_SELINUX
|
||||
assert(label);
|
||||
|
||||
if (!mac_selinux_use())
|
||||
return 0;
|
||||
|
||||
if (setsockcreatecon(label) < 0)
|
||||
return log_enforcing_errno(errno, "Failed to set SELinux security context %s for sockets: %m", label);
|
||||
assert(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
|
||||
|
||||
return 0;
|
||||
|
@ -560,14 +561,15 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
|||
if (errno == ENOENT)
|
||||
goto skipped;
|
||||
|
||||
r = log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
log_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", path);
|
||||
if (mac_selinux_enforcing())
|
||||
return -errno;
|
||||
|
||||
} else {
|
||||
if (setfscreatecon_raw(fcon) < 0) {
|
||||
r = log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", fcon, path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
log_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", fcon, path);
|
||||
if (mac_selinux_enforcing())
|
||||
return -errno;
|
||||
} else
|
||||
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;
|
||||
|
||||
if (context_changed)
|
||||
(void) setfscreatecon_raw(NULL);
|
||||
setfscreatecon_raw(NULL);
|
||||
|
||||
return r;
|
||||
|
||||
|
|
|
@ -746,25 +746,6 @@ static int property_get_log_extra_fields(
|
|||
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[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
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("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("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("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),
|
||||
|
@ -1280,55 +1258,6 @@ int bus_exec_context_set_transient_property(
|
|||
if (streq(name, "RootImage"))
|
||||
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"))
|
||||
return bus_set_transient_path(u, name, &c->root_directory, message, flags, error);
|
||||
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
#include "format-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "glob-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "io-util.h"
|
||||
#include "ioprio.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_system : PROTECT_SYSTEM_NO,
|
||||
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,
|
||||
error_path);
|
||||
|
||||
|
@ -4197,10 +4195,6 @@ void exec_context_done(ExecContext *c) {
|
|||
c->working_directory = mfree(c->working_directory);
|
||||
c->root_directory = mfree(c->root_directory);
|
||||
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->syslog_identifier = mfree(c->syslog_identifier);
|
||||
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)
|
||||
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)
|
||||
fprintf(f, "%sEnvironment: %s\n", prefix, *e);
|
||||
|
||||
|
|
|
@ -155,9 +155,7 @@ struct ExecContext {
|
|||
char **unset_environment;
|
||||
|
||||
struct rlimit *rlimit[_RLIMIT_MAX];
|
||||
char *working_directory, *root_directory, *root_image, *root_verity, *root_hash_path;
|
||||
void *root_hash;
|
||||
size_t root_hash_size;
|
||||
char *working_directory, *root_directory, *root_image;
|
||||
bool working_directory_missing_ok:1;
|
||||
bool working_directory_home:1;
|
||||
|
||||
|
|
|
@ -387,25 +387,62 @@ JobType job_type_lookup_merge(JobType a, JobType b) {
|
|||
return job_merging_table[(a - 1) * a / 2 + b];
|
||||
}
|
||||
|
||||
bool job_type_is_redundant(JobType a, UnitActiveState b) {
|
||||
switch (a) {
|
||||
bool job_later_link_matters(Job *j, JobType type, unsigned generation) {
|
||||
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:
|
||||
return IN_SET(state, UNIT_INACTIVE, UNIT_FAILED) ||
|
||||
job_later_link_matters(l->object, type, generation);
|
||||
|
||||
case JOB_STOP:
|
||||
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(b, UNIT_ACTIVE, UNIT_RELOADING);
|
||||
return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING) && !job_later_link_matters(j, JOB_START, generation);
|
||||
|
||||
case JOB_STOP:
|
||||
return IN_SET(b, UNIT_INACTIVE, UNIT_FAILED);
|
||||
return IN_SET(state, UNIT_INACTIVE, UNIT_FAILED) && !job_later_link_matters(j, JOB_STOP, generation);
|
||||
|
||||
case JOB_VERIFY_ACTIVE:
|
||||
return IN_SET(b, UNIT_ACTIVE, UNIT_RELOADING);
|
||||
return IN_SET(state, UNIT_ACTIVE, UNIT_RELOADING);
|
||||
|
||||
case JOB_RELOAD:
|
||||
return
|
||||
b == UNIT_RELOADING;
|
||||
state == UNIT_RELOADING;
|
||||
|
||||
case JOB_RESTART:
|
||||
return
|
||||
b == UNIT_ACTIVATING;
|
||||
state == UNIT_ACTIVATING;
|
||||
|
||||
case JOB_NOP:
|
||||
return true;
|
||||
|
|
|
@ -196,7 +196,8 @@ _pure_ static inline bool job_type_is_superset(JobType a, JobType 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
|
||||
* the state of the unit which it is going to be applied to. */
|
||||
|
|
|
@ -23,8 +23,6 @@ m4_define(`EXEC_CONTEXT_CONFIG_ITEMS',
|
|||
`$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.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.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)
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "errno-list.h"
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "io-util.h"
|
||||
|
@ -1414,64 +1413,6 @@ int config_parse_exec_cpu_sched_prio(const char *unit,
|
|||
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,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
|
|
|
@ -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_affinity);
|
||||
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_exec_mount_flags);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_timer);
|
||||
|
|
|
@ -1257,20 +1257,16 @@ int setup_namespace(
|
|||
ProtectHome protect_home,
|
||||
ProtectSystem protect_system,
|
||||
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,
|
||||
char **error_path) {
|
||||
|
||||
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
|
||||
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_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;
|
||||
MountEntry *m = NULL, *mounts = NULL;
|
||||
size_t n_mounts;
|
||||
size_t n_mounts, root_hash_size = 0;
|
||||
bool require_prefix = false;
|
||||
const char *root;
|
||||
int r = 0;
|
||||
|
@ -1299,16 +1295,16 @@ int setup_namespace(
|
|||
if (r < 0)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
return log_debug_errno(r, "Failed to decrypt dissected image: %m");
|
||||
}
|
||||
|
|
|
@ -88,10 +88,6 @@ int setup_namespace(
|
|||
ProtectHome protect_home,
|
||||
ProtectSystem protect_system,
|
||||
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,
|
||||
char **error_path);
|
||||
|
||||
|
|
|
@ -279,7 +279,7 @@ static int transaction_merge_jobs(Transaction *tr, sd_bus_error *e) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void transaction_drop_redundant(Transaction *tr) {
|
||||
static void transaction_drop_redundant(Transaction *tr, unsigned generation) {
|
||||
bool again;
|
||||
|
||||
/* 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)
|
||||
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))) {
|
||||
keep = true;
|
||||
break;
|
||||
|
@ -735,7 +735,7 @@ int transaction_activate(
|
|||
transaction_minimize_impact(tr);
|
||||
|
||||
/* Third step: Drop redundant jobs */
|
||||
transaction_drop_redundant(tr);
|
||||
transaction_drop_redundant(tr, generation++);
|
||||
|
||||
for (;;) {
|
||||
/* 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. */
|
||||
transaction_drop_redundant(tr);
|
||||
transaction_drop_redundant(tr, generation++);
|
||||
|
||||
/* Ninth step: check whether we can actually apply this */
|
||||
r = transaction_is_destructive(tr, mode, e);
|
||||
|
|
|
@ -201,7 +201,7 @@ static int run(int argc, char *argv[]) {
|
|||
if (r < 0)
|
||||
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);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read verity artefacts for %s: %m", arg_image);
|
||||
|
|
|
@ -619,9 +619,9 @@ int mount_all(const char *dest,
|
|||
|
||||
#if HAVE_SELINUX
|
||||
{ "/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,
|
||||
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
|
||||
};
|
||||
|
||||
|
|
|
@ -5141,7 +5141,7 @@ static int run(int argc, char *argv[]) {
|
|||
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);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to read verity artefacts for %s: %m", arg_image);
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "escape.h"
|
||||
#include "exec-util.h"
|
||||
#include "exit-status.h"
|
||||
#include "fileio.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "hostname-util.h"
|
||||
#include "in-addr-util.h"
|
||||
|
@ -25,7 +24,6 @@
|
|||
#include "nsflags.h"
|
||||
#include "numa-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "rlimit-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",
|
||||
"SELinuxContext",
|
||||
"RootImage",
|
||||
"RootVerity",
|
||||
"RuntimeDirectoryPreserve",
|
||||
"Personality",
|
||||
"KeyringMode",
|
||||
|
@ -1418,24 +1415,6 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1421,7 +1421,7 @@ int decrypted_image_relinquish(DecryptedImage *d) {
|
|||
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_ void *roothash_decoded = NULL;
|
||||
size_t roothash_decoded_size = 0;
|
||||
|
@ -1465,31 +1465,24 @@ int verity_metadata_load(const char *image, const char *root_hash_path, void **r
|
|||
_cleanup_free_ char *text = NULL;
|
||||
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)
|
||||
r = getxattr_malloc(image, "user.verity.roothash", &text, true);
|
||||
if (r < 0) {
|
||||
char *fn, *e, *n;
|
||||
|
||||
if (!IN_SET(r, -ENODATA, -EOPNOTSUPP, -ENOENT))
|
||||
return r;
|
||||
} else {
|
||||
r = getxattr_malloc(image, "user.verity.roothash", &text, true);
|
||||
if (r < 0) {
|
||||
char *fn, *e, *n;
|
||||
|
||||
if (!IN_SET(r, -ENODATA, -EOPNOTSUPP, -ENOENT))
|
||||
return r;
|
||||
fn = newa(char, strlen(image) + STRLEN(".roothash") + 1);
|
||||
n = stpcpy(fn, image);
|
||||
e = endswith(fn, ".raw");
|
||||
if (e)
|
||||
n = e;
|
||||
|
||||
fn = newa(char, strlen(image) + STRLEN(".roothash") + 1);
|
||||
n = stpcpy(fn, image);
|
||||
e = endswith(fn, ".raw");
|
||||
if (e)
|
||||
n = e;
|
||||
strcpy(n, ".roothash");
|
||||
|
||||
strcpy(n, ".roothash");
|
||||
|
||||
r = read_one_line_file(fn, &text);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
return r;
|
||||
}
|
||||
r = read_one_line_file(fn, &text);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (text) {
|
||||
|
|
|
@ -100,6 +100,6 @@ int decrypted_image_relinquish(DecryptedImage *d);
|
|||
const char* partition_designator_to_string(int i) _const_;
|
||||
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_has_verity(const DissectedImage *image, unsigned partition_designator);
|
||||
|
|
|
@ -152,10 +152,6 @@ static void test_protect_kernel_logs(void) {
|
|||
PROTECT_HOME_NO,
|
||||
PROTECT_SYSTEM_NO,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
assert_se(r == 0);
|
||||
|
|
|
@ -76,10 +76,6 @@ int main(int argc, char *argv[]) {
|
|||
PROTECT_HOME_NO,
|
||||
PROTECT_SYSTEM_NO,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
NULL);
|
||||
if (r < 0) {
|
||||
|
|
|
@ -196,8 +196,6 @@ ReusePort=
|
|||
RootDirectory=
|
||||
RootDirectoryStartOnly=
|
||||
RootImage=
|
||||
RootHash=
|
||||
RootVerity=
|
||||
RuntimeMaxSec=
|
||||
SELinuxContextFromNet=
|
||||
SecureBits=
|
||||
|
|
|
@ -935,7 +935,7 @@ install_config_files() {
|
|||
inst /etc/login.defs
|
||||
inst /etc/group
|
||||
inst /etc/shells
|
||||
inst_any /etc/nsswitch.conf /usr/etc/nsswitch.conf
|
||||
inst /etc/nsswitch.conf
|
||||
inst /etc/pam.conf || :
|
||||
inst /etc/os-release
|
||||
inst /etc/localtime
|
||||
|
|
|
@ -9,25 +9,23 @@
|
|||
# export CONT_NAME="my-fancy-container"
|
||||
# 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}"
|
||||
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_RUN="${DOCKER_RUN:-docker run}"
|
||||
REPO_ROOT="${REPO_ROOT:-$PWD}"
|
||||
ADDITIONAL_DEPS=(
|
||||
clang
|
||||
fdisk
|
||||
libfdisk-dev
|
||||
libp11-kit-dev
|
||||
libpwquality-dev
|
||||
libssl-dev
|
||||
libzstd-dev
|
||||
perl
|
||||
python3-libevdev
|
||||
python3-pyparsing
|
||||
zstd
|
||||
)
|
||||
ADDITIONAL_DEPS=(python3-libevdev
|
||||
python3-pyparsing
|
||||
clang
|
||||
perl
|
||||
libpwquality-dev
|
||||
fdisk
|
||||
libfdisk-dev
|
||||
libp11-kit-dev
|
||||
libssl-dev
|
||||
libzstd-dev
|
||||
zstd)
|
||||
|
||||
function info() {
|
||||
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 install "${ADDITIONAL_DEPS[@]}"
|
||||
;;
|
||||
RUN|RUN_GCC|RUN_CLANG)
|
||||
RUN|RUN_CLANG)
|
||||
if [[ "$phase" = "RUN_CLANG" ]]; then
|
||||
ENV_VARS="-e CC=clang -e CXX=clang++"
|
||||
fi
|
||||
|
@ -64,8 +62,8 @@ for phase in "${PHASES[@]}"; do
|
|||
$DOCKER_EXEC ninja -v -C build
|
||||
docker exec -e "TRAVIS=$TRAVIS" -it $CONT_NAME ninja -C build test
|
||||
;;
|
||||
RUN_ASAN_UBSAN|RUN_GCC_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN)
|
||||
if [[ "$phase" = "RUN_CLANG_ASAN_UBSAN" ]]; then
|
||||
RUN_ASAN|RUN_CLANG_ASAN)
|
||||
if [[ "$phase" = "RUN_CLANG_ASAN" ]]; then
|
||||
ENV_VARS="-e CC=clang -e CXX=clang++"
|
||||
# Build fuzzer regression tests only with clang (for now),
|
||||
# see: https://github.com/systemd/systemd/pull/15886#issuecomment-632689604
|
||||
|
|
|
@ -9,32 +9,38 @@
|
|||
# export CONT_NAME="my-fancy-container"
|
||||
# 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}"
|
||||
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_RUN="${DOCKER_RUN:-docker run}"
|
||||
REPO_ROOT="${REPO_ROOT:-$PWD}"
|
||||
ADDITIONAL_DEPS=(
|
||||
clang
|
||||
dnf-plugins-core
|
||||
hostname libasan
|
||||
jq iputils
|
||||
libfdisk-devel
|
||||
libpwquality-devel
|
||||
libubsan
|
||||
llvm
|
||||
openssl-devel
|
||||
p11-kit-devel
|
||||
perl
|
||||
python3-evdev
|
||||
python3-pyparsing
|
||||
)
|
||||
ADDITIONAL_DEPS=(dnf-plugins-core
|
||||
jq iputils
|
||||
hostname libasan
|
||||
python3-pyparsing
|
||||
python3-evdev
|
||||
libubsan
|
||||
clang
|
||||
llvm
|
||||
perl
|
||||
libfdisk-devel
|
||||
libpwquality-devel
|
||||
openssl-devel
|
||||
p11-kit-devel)
|
||||
|
||||
info() {
|
||||
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
|
||||
_retry() {
|
||||
local EC=1
|
||||
|
@ -88,8 +94,8 @@ for phase in "${PHASES[@]}"; do
|
|||
$DOCKER_EXEC ninja -v -C build
|
||||
$DOCKER_EXEC ninja -C build test
|
||||
;;
|
||||
RUN_ASAN|RUN_GCC_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN)
|
||||
if [[ "$phase" = "RUN_CLANG_ASAN_UBSAN" ]]; then
|
||||
RUN_ASAN|RUN_CLANG_ASAN)
|
||||
if [[ "$phase" = "RUN_CLANG_ASAN" ]]; then
|
||||
ENV_VARS="-e CC=clang -e CXX=clang++"
|
||||
MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764
|
||||
fi
|
||||
|
@ -104,6 +110,46 @@ for phase in "${PHASES[@]}"; do
|
|||
-t $CONT_NAME \
|
||||
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)
|
||||
info "Cleanup phase"
|
||||
docker stop $CONT_NAME
|
||||
|
|
Loading…
Reference in New Issue