mirror of
https://github.com/systemd/systemd
synced 2025-11-22 02:04:45 +01:00
Compare commits
No commits in common. "582a1e187701b02ab3ed948dc452f1387848c788" and "996e6d0d8957653ff84387367e81ba5f9cbfbbf2" have entirely different histories.
582a1e1877
...
996e6d0d89
2
.github/workflows/mkosi.yml
vendored
2
.github/workflows/mkosi.yml
vendored
@ -110,7 +110,7 @@ jobs:
|
|||||||
no_kvm: 0
|
no_kvm: 0
|
||||||
shim: 0
|
shim: 0
|
||||||
- distro: fedora
|
- distro: fedora
|
||||||
release: "43"
|
release: "42"
|
||||||
runner: ubuntu-24.04
|
runner: ubuntu-24.04
|
||||||
sanitizers: address,undefined
|
sanitizers: address,undefined
|
||||||
llvm: 1
|
llvm: 1
|
||||||
|
|||||||
7
TODO
7
TODO
@ -1772,6 +1772,11 @@ Features:
|
|||||||
* pid1: also remove PID files of a service when the service starts, not just
|
* pid1: also remove PID files of a service when the service starts, not just
|
||||||
when it exits
|
when it exits
|
||||||
|
|
||||||
|
* make us use dynamically fewer deps for containers in general purpose distros:
|
||||||
|
o turn into dlopen() deps:
|
||||||
|
- libblkid (only in RootImage= handling in PID 1, but not elsewhere)
|
||||||
|
- libpam (only when called from PID 1)
|
||||||
|
|
||||||
* seccomp: maybe use seccomp_merge() to merge our filters per-arch if we can.
|
* seccomp: maybe use seccomp_merge() to merge our filters per-arch if we can.
|
||||||
Apparently kernel performance is much better with fewer larger seccomp
|
Apparently kernel performance is much better with fewer larger seccomp
|
||||||
filters than with more smaller seccomp filters.
|
filters than with more smaller seccomp filters.
|
||||||
@ -1793,7 +1798,7 @@ Features:
|
|||||||
* unify on openssl:
|
* unify on openssl:
|
||||||
- figure out what to do about libmicrohttpd, which has a hard dependency on
|
- figure out what to do about libmicrohttpd, which has a hard dependency on
|
||||||
gnutls
|
gnutls
|
||||||
- port fsprg over to openssl
|
- port fsprg over to a dlopen lib, then switch it to openssl
|
||||||
|
|
||||||
* add growvol and makevol options for /etc/crypttab, similar to
|
* add growvol and makevol options for /etc/crypttab, similar to
|
||||||
x-systemd.growfs and x-systemd-makefs.
|
x-systemd.growfs and x-systemd-makefs.
|
||||||
|
|||||||
@ -1050,10 +1050,6 @@ manpages = [
|
|||||||
['systemd-modules-load.service', '8', ['systemd-modules-load'], 'HAVE_KMOD'],
|
['systemd-modules-load.service', '8', ['systemd-modules-load'], 'HAVE_KMOD'],
|
||||||
['systemd-mount', '1', ['systemd-umount'], ''],
|
['systemd-mount', '1', ['systemd-umount'], ''],
|
||||||
['systemd-mountfsd.service', '8', ['systemd-mountfsd'], 'ENABLE_MOUNTFSD'],
|
['systemd-mountfsd.service', '8', ['systemd-mountfsd'], 'ENABLE_MOUNTFSD'],
|
||||||
['systemd-mute-console',
|
|
||||||
'1',
|
|
||||||
['systemd-mute-console.socket', 'systemd-mute-console@.service'],
|
|
||||||
''],
|
|
||||||
['systemd-network-generator.service', '8', ['systemd-network-generator'], ''],
|
['systemd-network-generator.service', '8', ['systemd-network-generator'], ''],
|
||||||
['systemd-networkd-wait-online.service',
|
['systemd-networkd-wait-online.service',
|
||||||
'8',
|
'8',
|
||||||
|
|||||||
@ -354,16 +354,6 @@
|
|||||||
<xi:include href="version-info.xml" xpointer="v259"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v259"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><option>--mute-console=</option></term>
|
|
||||||
|
|
||||||
<listitem><para>Takes a boolean argument. If true kernel log output and service manager status output
|
|
||||||
to the system console is temporarily disabled while <command>systemd-firstboot</command> is running,
|
|
||||||
so that its own output is not interrupted. Defaults to false.</para>
|
|
||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v259"/></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<xi:include href="standard-options.xml" xpointer="help" />
|
<xi:include href="standard-options.xml" xpointer="help" />
|
||||||
<xi:include href="standard-options.xml" xpointer="version" />
|
<xi:include href="standard-options.xml" xpointer="version" />
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|||||||
@ -1,79 +0,0 @@
|
|||||||
<?xml version='1.0'?> <!--*-nxml-*-->
|
|
||||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
|
||||||
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
|
|
||||||
|
|
||||||
<refentry id="systemd-mute-console"
|
|
||||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
|
||||||
|
|
||||||
<refentryinfo>
|
|
||||||
<title>systemd-mute-console</title>
|
|
||||||
<productname>systemd</productname>
|
|
||||||
</refentryinfo>
|
|
||||||
|
|
||||||
<refmeta>
|
|
||||||
<refentrytitle>systemd-mute-console</refentrytitle>
|
|
||||||
<manvolnum>1</manvolnum>
|
|
||||||
</refmeta>
|
|
||||||
|
|
||||||
<refnamediv>
|
|
||||||
<refname>systemd-mute-console</refname>
|
|
||||||
<refname>systemd-mute-console@.service</refname>
|
|
||||||
<refname>systemd-mute-console.socket</refname>
|
|
||||||
<refpurpose>Temporarily mute kernel log output and service manager status output to the system console</refpurpose>
|
|
||||||
</refnamediv>
|
|
||||||
|
|
||||||
<refsynopsisdiv>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>systemd-mute-console</command>
|
|
||||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
|
||||||
</cmdsynopsis>
|
|
||||||
|
|
||||||
<para><filename>systemd-mute-console@.service</filename></para>
|
|
||||||
<para><filename>systemd-mute-console.socket</filename></para>
|
|
||||||
</refsynopsisdiv>
|
|
||||||
|
|
||||||
<refsect1>
|
|
||||||
<title>Description</title>
|
|
||||||
|
|
||||||
<para>The <command>systemd-mute-console</command> tool and service may be used to
|
|
||||||
temporarily mute the log output of the kernel as well as the status output of the service manager to
|
|
||||||
the system console. It may be used by tools running on the console to ensure their terminal output is not
|
|
||||||
interrupted by unrelated messages.</para>
|
|
||||||
|
|
||||||
<para>The tool can be invoked directly in which case it will mute the two outputs and then issue an
|
|
||||||
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
|
||||||
<literal>READY=1</literal> notification once that is completed. On <constant>SIGINT</constant> or
|
|
||||||
<constant>SIGTERM</constant> output is unmuted again. Alternatively it can be invoked via Varlink
|
|
||||||
IPC.</para>
|
|
||||||
</refsect1>
|
|
||||||
|
|
||||||
<refsect1>
|
|
||||||
<title>Options</title>
|
|
||||||
|
|
||||||
<para>The following options are understood:</para>
|
|
||||||
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term><option>--kernel=<replaceable>bool</replaceable></option></term>
|
|
||||||
<term><option>--pid1=<replaceable>bool</replaceable></option></term>
|
|
||||||
<listitem><para>Individually controls which output to mute. If true is specified the respective
|
|
||||||
output is muted, if false the output is left as is. Defaults to true.</para>
|
|
||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v259"/></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<xi:include href="standard-options.xml" xpointer="help" />
|
|
||||||
<xi:include href="standard-options.xml" xpointer="version" />
|
|
||||||
</variablelist>
|
|
||||||
</refsect1>
|
|
||||||
|
|
||||||
<refsect1>
|
|
||||||
<title>See Also</title>
|
|
||||||
<para><simplelist type="inline">
|
|
||||||
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
|
|
||||||
<member><citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
|
|
||||||
</simplelist></para>
|
|
||||||
</refsect1>
|
|
||||||
|
|
||||||
</refentry>
|
|
||||||
@ -1154,7 +1154,6 @@ libselinux = dependency('libselinux',
|
|||||||
version : '>= 2.1.9',
|
version : '>= 2.1.9',
|
||||||
required : get_option('selinux'))
|
required : get_option('selinux'))
|
||||||
conf.set10('HAVE_SELINUX', libselinux.found())
|
conf.set10('HAVE_SELINUX', libselinux.found())
|
||||||
libselinux_cflags = libselinux.partial_dependency(includes: true, compile_args: true)
|
|
||||||
|
|
||||||
libapparmor = dependency('libapparmor',
|
libapparmor = dependency('libapparmor',
|
||||||
version : '>= 2.13',
|
version : '>= 2.13',
|
||||||
@ -2384,7 +2383,6 @@ subdir('src/measure')
|
|||||||
subdir('src/modules-load')
|
subdir('src/modules-load')
|
||||||
subdir('src/mount')
|
subdir('src/mount')
|
||||||
subdir('src/mountfsd')
|
subdir('src/mountfsd')
|
||||||
subdir('src/mute-console')
|
|
||||||
subdir('src/network')
|
subdir('src/network')
|
||||||
subdir('src/notify')
|
subdir('src/notify')
|
||||||
subdir('src/nspawn')
|
subdir('src/nspawn')
|
||||||
|
|||||||
@ -1299,12 +1299,6 @@ static void boot_entry_add_type1(
|
|||||||
} else if (streq8(key, "sort-key")) {
|
} else if (streq8(key, "sort-key")) {
|
||||||
free(entry->sort_key);
|
free(entry->sort_key);
|
||||||
entry->sort_key = xstr8_to_16(value);
|
entry->sort_key = xstr8_to_16(value);
|
||||||
} else if (streq8(key, "profile")) {
|
|
||||||
uint64_t u;
|
|
||||||
if (parse_number8(value, &u, NULL) && u <= UINT_MAX)
|
|
||||||
entry->profile = (unsigned)u;
|
|
||||||
else
|
|
||||||
log_warning("Error parsing 'profile' entry option, ignoring: %s", value);
|
|
||||||
|
|
||||||
} else if (streq8(key, "version")) {
|
} else if (streq8(key, "version")) {
|
||||||
free(entry->version);
|
free(entry->version);
|
||||||
|
|||||||
@ -6111,7 +6111,7 @@ int exec_invoke(
|
|||||||
char *exec_context = mac_selinux_context_net ?: context->selinux_context;
|
char *exec_context = mac_selinux_context_net ?: context->selinux_context;
|
||||||
|
|
||||||
if (exec_context) {
|
if (exec_context) {
|
||||||
r = sym_setexeccon_raw(exec_context);
|
r = setexeccon(exec_context);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (!context->selinux_context_ignore) {
|
if (!context->selinux_context_ignore) {
|
||||||
*exit_status = EXIT_SELINUX_CONTEXT;
|
*exit_status = EXIT_SELINUX_CONTEXT;
|
||||||
|
|||||||
@ -6124,7 +6124,7 @@ int unit_load_fragment(Unit *u) {
|
|||||||
_cleanup_freecon_ char *selcon = NULL;
|
_cleanup_freecon_ char *selcon = NULL;
|
||||||
|
|
||||||
/* Cache the SELinux context of the unit file here. We'll make use of when checking access permissions to loaded units */
|
/* Cache the SELinux context of the unit file here. We'll make use of when checking access permissions to loaded units */
|
||||||
r = sym_fgetfilecon_raw(fileno(f), &selcon);
|
r = fgetfilecon_raw(fileno(f), &selcon);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_unit_warning_errno(u, r, "Failed to read SELinux context of '%s', ignoring: %m", fragment);
|
log_unit_warning_errno(u, r, "Failed to read SELinux context of '%s', ignoring: %m", fragment);
|
||||||
|
|
||||||
|
|||||||
@ -137,7 +137,7 @@ libcore_static = static_library(
|
|||||||
libmount_cflags,
|
libmount_cflags,
|
||||||
librt,
|
librt,
|
||||||
libseccomp_cflags,
|
libseccomp_cflags,
|
||||||
libselinux_cflags,
|
libselinux,
|
||||||
threads,
|
threads,
|
||||||
userspace],
|
userspace],
|
||||||
build_by_default : false)
|
build_by_default : false)
|
||||||
@ -200,7 +200,7 @@ executables += [
|
|||||||
libapparmor_cflags,
|
libapparmor_cflags,
|
||||||
libkmod_cflags,
|
libkmod_cflags,
|
||||||
libseccomp_cflags,
|
libseccomp_cflags,
|
||||||
libselinux_cflags,
|
libselinux,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
libexec_template + {
|
libexec_template + {
|
||||||
@ -213,7 +213,7 @@ executables += [
|
|||||||
libapparmor_cflags,
|
libapparmor_cflags,
|
||||||
libpam_cflags,
|
libpam_cflags,
|
||||||
libseccomp_cflags,
|
libseccomp_cflags,
|
||||||
libselinux_cflags,
|
libselinux,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
fuzz_template + {
|
fuzz_template + {
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#if HAVE_SELINUX
|
#if HAVE_SELINUX
|
||||||
|
|
||||||
|
#include <selinux/avc.h>
|
||||||
|
#include <selinux/selinux.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "sd-bus.h"
|
#include "sd-bus.h"
|
||||||
@ -151,7 +153,7 @@ static int access_init(sd_bus_error *error) {
|
|||||||
if (initialized)
|
if (initialized)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (sym_avc_open(NULL, 0) != 0) {
|
if (avc_open(NULL, 0) != 0) {
|
||||||
/* Passing errno to save original value for later */
|
/* Passing errno to save original value for later */
|
||||||
r = log_selinux_enforcing_errno(errno, "Failed to open the SELinux AVC: %m");
|
r = log_selinux_enforcing_errno(errno, "Failed to open the SELinux AVC: %m");
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
@ -166,8 +168,8 @@ static int access_init(sd_bus_error *error) {
|
|||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to open the SELinux AVC: %m");
|
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to open the SELinux AVC: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
sym_selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback) { .func_audit = audit_callback });
|
selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback) { .func_audit = audit_callback });
|
||||||
sym_selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) { .func_log = log_callback });
|
selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) { .func_log = log_callback });
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
return 1;
|
return 1;
|
||||||
@ -194,7 +196,7 @@ static int get_our_contexts(const Unit *unit, const char **ret_acon, const char
|
|||||||
* does exactly the same - call getcon_raw(). However, it involves
|
* does exactly the same - call getcon_raw(). However, it involves
|
||||||
* selinux_init() which opens label DB. It was not part of the
|
* selinux_init() which opens label DB. It was not part of the
|
||||||
* original code. I don't want to change it for now. */
|
* original code. I don't want to change it for now. */
|
||||||
if (sym_getcon_raw(&fcon) < 0)
|
if (getcon_raw(&fcon) < 0)
|
||||||
return log_debug_errno(errno, "SELinux getcon_raw() failed: %m");
|
return log_debug_errno(errno, "SELinux getcon_raw() failed: %m");
|
||||||
|
|
||||||
if (!fcon)
|
if (!fcon)
|
||||||
@ -224,7 +226,7 @@ static int check_access(
|
|||||||
assert(audit_info);
|
assert(audit_info);
|
||||||
assert(audit_info->function);
|
assert(audit_info->function);
|
||||||
|
|
||||||
r = sym_selinux_check_access(scon, tcon, tclass, permission, audit_info);
|
r = selinux_check_access(scon, tcon, tclass, permission, audit_info);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
errno = -(r = errno_or_else(EPERM));
|
errno = -(r = errno_or_else(EPERM));
|
||||||
|
|
||||||
@ -355,7 +357,7 @@ int mac_selinux_access_check_varlink_internal(
|
|||||||
|
|
||||||
/* We should call mac_selinux_get_peer_label() here similarly to get_our_contexts().
|
/* We should call mac_selinux_get_peer_label() here similarly to get_our_contexts().
|
||||||
* See the explanation there why not. */
|
* See the explanation there why not. */
|
||||||
if (sym_getpeercon_raw(fd, &scon) < 0)
|
if (getpeercon_raw(fd, &scon) < 0)
|
||||||
return log_selinux_enforcing_errno(
|
return log_selinux_enforcing_errno(
|
||||||
errno,
|
errno,
|
||||||
"Failed to get peer SELinux context%s: %m",
|
"Failed to get peer SELinux context%s: %m",
|
||||||
|
|||||||
@ -18,17 +18,13 @@ int mac_selinux_setup(bool *loaded_policy) {
|
|||||||
#if HAVE_SELINUX
|
#if HAVE_SELINUX
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = dlopen_libselinux();
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "No SELinux library available, skipping setup: %m");
|
|
||||||
|
|
||||||
mac_selinux_disable_logging();
|
mac_selinux_disable_logging();
|
||||||
|
|
||||||
/* Don't load policy in the initrd if we don't appear to have it. For the real root, we check below
|
/* Don't load policy in the initrd if we don't appear to have it. For the real root, we check below
|
||||||
* if we've already loaded policy, and return gracefully. */
|
* if we've already loaded policy, and return gracefully. */
|
||||||
if (in_initrd() && access(sym_selinux_path(), F_OK) < 0) {
|
if (in_initrd() && access(selinux_path(), F_OK) < 0) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
log_warning_errno(errno, "Unable to check if %s exists, assuming it does not: %m", sym_selinux_path());
|
log_warning_errno(errno, "Unable to check if %s exists, assuming it does not: %m", selinux_path());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -41,7 +37,7 @@ int mac_selinux_setup(bool *loaded_policy) {
|
|||||||
* empty. SELinux guarantees this won't happen, but that file isn't specific to SELinux, and may be
|
* empty. SELinux guarantees this won't happen, but that file isn't specific to SELinux, and may be
|
||||||
* provided by some other arbitrary LSM with different semantics. */
|
* provided by some other arbitrary LSM with different semantics. */
|
||||||
_cleanup_freecon_ char *con = NULL;
|
_cleanup_freecon_ char *con = NULL;
|
||||||
if (sym_getcon_raw(&con) < 0)
|
if (getcon_raw(&con) < 0)
|
||||||
log_debug_errno(errno, "getcon_raw() failed, assuming SELinux is not initialized: %m");
|
log_debug_errno(errno, "getcon_raw() failed, assuming SELinux is not initialized: %m");
|
||||||
else if (con) {
|
else if (con) {
|
||||||
initialized = !streq(con, "kernel");
|
initialized = !streq(con, "kernel");
|
||||||
@ -54,7 +50,7 @@ int mac_selinux_setup(bool *loaded_policy) {
|
|||||||
/* Now load the policy */
|
/* Now load the policy */
|
||||||
usec_t before_load = now(CLOCK_MONOTONIC);
|
usec_t before_load = now(CLOCK_MONOTONIC);
|
||||||
int enforce = 0;
|
int enforce = 0;
|
||||||
if (sym_selinux_init_load_policy(&enforce) == 0) { /* NB: Apparently doesn't set useful errno! */
|
if (selinux_init_load_policy(&enforce) == 0) { /* NB: Apparently doesn't set useful errno! */
|
||||||
mac_selinux_retest();
|
mac_selinux_retest();
|
||||||
|
|
||||||
/* Transition to the new context */
|
/* Transition to the new context */
|
||||||
@ -64,7 +60,7 @@ int mac_selinux_setup(bool *loaded_policy) {
|
|||||||
log_open();
|
log_open();
|
||||||
log_warning_errno(r, "Failed to compute init label, ignoring: %m");
|
log_warning_errno(r, "Failed to compute init label, ignoring: %m");
|
||||||
} else {
|
} else {
|
||||||
r = RET_NERRNO(sym_setcon_raw(label));
|
r = RET_NERRNO(setcon_raw(label));
|
||||||
log_open();
|
log_open();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to transition into init label '%s', ignoring: %m", label);
|
log_warning_errno(r, "Failed to transition into init label '%s', ignoring: %m", label);
|
||||||
|
|||||||
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include "sd-bus.h"
|
#include "sd-bus.h"
|
||||||
#include "sd-id128.h"
|
#include "sd-id128.h"
|
||||||
#include "sd-varlink.h"
|
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "ask-password-api.h"
|
#include "ask-password-api.h"
|
||||||
@ -87,7 +86,6 @@ static bool arg_welcome = true;
|
|||||||
static bool arg_reset = false;
|
static bool arg_reset = false;
|
||||||
static ImagePolicy *arg_image_policy = NULL;
|
static ImagePolicy *arg_image_policy = NULL;
|
||||||
static bool arg_chrome = true;
|
static bool arg_chrome = true;
|
||||||
static bool arg_mute_console = false;
|
|
||||||
|
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
||||||
@ -101,17 +99,13 @@ STATIC_DESTRUCTOR_REGISTER(arg_root_shell, freep);
|
|||||||
STATIC_DESTRUCTOR_REGISTER(arg_kernel_cmdline, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_kernel_cmdline, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
|
||||||
|
|
||||||
static void print_welcome(int rfd, sd_varlink **mute_console_link) {
|
static void print_welcome(int rfd) {
|
||||||
_cleanup_free_ char *pretty_name = NULL, *os_name = NULL, *ansi_color = NULL;
|
_cleanup_free_ char *pretty_name = NULL, *os_name = NULL, *ansi_color = NULL;
|
||||||
static bool done = false;
|
static bool done = false;
|
||||||
const char *pn, *ac;
|
const char *pn, *ac;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0);
|
assert(rfd >= 0);
|
||||||
assert(mute_console_link);
|
|
||||||
|
|
||||||
if (!*mute_console_link && arg_mute_console)
|
|
||||||
(void) mute_console(mute_console_link);
|
|
||||||
|
|
||||||
if (!arg_welcome)
|
if (!arg_welcome)
|
||||||
return;
|
return;
|
||||||
@ -233,7 +227,7 @@ static int locale_is_ok(const char *name, void *userdata) {
|
|||||||
return r != 0 ? locale_is_installed(name) > 0 : locale_is_valid(name);
|
return r != 0 ? locale_is_installed(name) > 0 : locale_is_valid(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prompt_locale(int rfd, sd_varlink **mute_console_link) {
|
static int prompt_locale(int rfd) {
|
||||||
_cleanup_strv_free_ char **locales = NULL;
|
_cleanup_strv_free_ char **locales = NULL;
|
||||||
bool acquired_from_creds = false;
|
bool acquired_from_creds = false;
|
||||||
int r;
|
int r;
|
||||||
@ -285,7 +279,7 @@ static int prompt_locale(int rfd, sd_varlink **mute_console_link) {
|
|||||||
/* Not setting arg_locale_message here, since it defaults to LANG anyway */
|
/* Not setting arg_locale_message here, since it defaults to LANG anyway */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print_welcome(rfd, mute_console_link);
|
print_welcome(rfd);
|
||||||
|
|
||||||
r = prompt_loop("Please enter the new system locale name or number",
|
r = prompt_loop("Please enter the new system locale name or number",
|
||||||
GLYPH_WORLD,
|
GLYPH_WORLD,
|
||||||
@ -327,7 +321,7 @@ static int prompt_locale(int rfd, sd_varlink **mute_console_link) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_locale(int rfd, sd_varlink **mute_console_link) {
|
static int process_locale(int rfd) {
|
||||||
_cleanup_close_ int pfd = -EBADF;
|
_cleanup_close_ int pfd = -EBADF;
|
||||||
_cleanup_free_ char *f = NULL;
|
_cleanup_free_ char *f = NULL;
|
||||||
char* locales[3];
|
char* locales[3];
|
||||||
@ -363,7 +357,7 @@ static int process_locale(int rfd, sd_varlink **mute_console_link) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = prompt_locale(rfd, mute_console_link);
|
r = prompt_locale(rfd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -400,7 +394,7 @@ static int keymap_is_ok(const char* name, void *userdata) {
|
|||||||
return r != 0 ? keymap_exists(name) > 0 : keymap_is_valid(name);
|
return r != 0 ? keymap_exists(name) > 0 : keymap_is_valid(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prompt_keymap(int rfd, sd_varlink **mute_console_link) {
|
static int prompt_keymap(int rfd) {
|
||||||
_cleanup_strv_free_ char **kmaps = NULL;
|
_cleanup_strv_free_ char **kmaps = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -428,7 +422,7 @@ static int prompt_keymap(int rfd, sd_varlink **mute_console_link) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to read keymaps: %m");
|
return log_error_errno(r, "Failed to read keymaps: %m");
|
||||||
|
|
||||||
print_welcome(rfd, mute_console_link);
|
print_welcome(rfd);
|
||||||
|
|
||||||
return prompt_loop(
|
return prompt_loop(
|
||||||
"Please enter the new keymap name or number",
|
"Please enter the new keymap name or number",
|
||||||
@ -445,7 +439,7 @@ static int prompt_keymap(int rfd, sd_varlink **mute_console_link) {
|
|||||||
&arg_keymap);
|
&arg_keymap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_keymap(int rfd, sd_varlink **mute_console_link) {
|
static int process_keymap(int rfd) {
|
||||||
_cleanup_close_ int pfd = -EBADF;
|
_cleanup_close_ int pfd = -EBADF;
|
||||||
_cleanup_free_ char *f = NULL;
|
_cleanup_free_ char *f = NULL;
|
||||||
_cleanup_strv_free_ char **keymap = NULL;
|
_cleanup_strv_free_ char **keymap = NULL;
|
||||||
@ -480,7 +474,7 @@ static int process_keymap(int rfd, sd_varlink **mute_console_link) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = prompt_keymap(rfd, mute_console_link);
|
r = prompt_keymap(rfd);
|
||||||
if (r == -ENOENT)
|
if (r == -ENOENT)
|
||||||
return 0; /* don't fail if no keymaps are installed */
|
return 0; /* don't fail if no keymaps are installed */
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -514,7 +508,7 @@ static int timezone_is_ok(const char *name, void *userdata) {
|
|||||||
return timezone_is_valid(name, LOG_DEBUG);
|
return timezone_is_valid(name, LOG_DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prompt_timezone(int rfd, sd_varlink **mute_console_link) {
|
static int prompt_timezone(int rfd) {
|
||||||
_cleanup_strv_free_ char **zones = NULL;
|
_cleanup_strv_free_ char **zones = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -540,7 +534,7 @@ static int prompt_timezone(int rfd, sd_varlink **mute_console_link) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Cannot query timezone list: %m");
|
return log_error_errno(r, "Cannot query timezone list: %m");
|
||||||
|
|
||||||
print_welcome(rfd, mute_console_link);
|
print_welcome(rfd);
|
||||||
|
|
||||||
return prompt_loop(
|
return prompt_loop(
|
||||||
"Please enter the new timezone name or number",
|
"Please enter the new timezone name or number",
|
||||||
@ -557,7 +551,7 @@ static int prompt_timezone(int rfd, sd_varlink **mute_console_link) {
|
|||||||
&arg_timezone);
|
&arg_timezone);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_timezone(int rfd, sd_varlink **mute_console_link) {
|
static int process_timezone(int rfd) {
|
||||||
_cleanup_close_ int pfd = -EBADF;
|
_cleanup_close_ int pfd = -EBADF;
|
||||||
_cleanup_free_ char *f = NULL, *relpath = NULL;
|
_cleanup_free_ char *f = NULL, *relpath = NULL;
|
||||||
const char *e;
|
const char *e;
|
||||||
@ -598,7 +592,7 @@ static int process_timezone(int rfd, sd_varlink **mute_console_link) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = prompt_timezone(rfd, mute_console_link);
|
r = prompt_timezone(rfd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -622,7 +616,7 @@ static int hostname_is_ok(const char *name, void *userdata) {
|
|||||||
return hostname_is_valid(name, VALID_HOSTNAME_TRAILING_DOT);
|
return hostname_is_valid(name, VALID_HOSTNAME_TRAILING_DOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prompt_hostname(int rfd, sd_varlink **mute_console_link) {
|
static int prompt_hostname(int rfd) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0);
|
assert(rfd >= 0);
|
||||||
@ -635,7 +629,7 @@ static int prompt_hostname(int rfd, sd_varlink **mute_console_link) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_welcome(rfd, mute_console_link);
|
print_welcome(rfd);
|
||||||
|
|
||||||
r = prompt_loop("Please enter the new hostname",
|
r = prompt_loop("Please enter the new hostname",
|
||||||
GLYPH_LABEL,
|
GLYPH_LABEL,
|
||||||
@ -658,7 +652,7 @@ static int prompt_hostname(int rfd, sd_varlink **mute_console_link) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_hostname(int rfd, sd_varlink **mute_console_link) {
|
static int process_hostname(int rfd) {
|
||||||
_cleanup_close_ int pfd = -EBADF;
|
_cleanup_close_ int pfd = -EBADF;
|
||||||
_cleanup_free_ char *f = NULL;
|
_cleanup_free_ char *f = NULL;
|
||||||
int r;
|
int r;
|
||||||
@ -677,7 +671,7 @@ static int process_hostname(int rfd, sd_varlink **mute_console_link) {
|
|||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = prompt_hostname(rfd, mute_console_link);
|
r = prompt_hostname(rfd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -726,7 +720,7 @@ static int process_machine_id(int rfd) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prompt_root_password(int rfd, sd_varlink **mute_console_link) {
|
static int prompt_root_password(int rfd) {
|
||||||
const char *msg1, *msg2;
|
const char *msg1, *msg2;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -743,10 +737,10 @@ static int prompt_root_password(int rfd, sd_varlink **mute_console_link) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_welcome(rfd, mute_console_link);
|
print_welcome(rfd);
|
||||||
|
|
||||||
msg1 = "Please enter the new root password (empty to skip):";
|
msg1 = strjoina("Please enter the new root password (empty to skip):");
|
||||||
msg2 = "Please enter the new root password again:";
|
msg2 = strjoina("Please enter the new root password again:");
|
||||||
|
|
||||||
suggest_passwords();
|
suggest_passwords();
|
||||||
|
|
||||||
@ -823,7 +817,7 @@ static int shell_is_ok(const char *path, void *userdata) {
|
|||||||
return find_shell(rfd, path) >= 0;
|
return find_shell(rfd, path) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prompt_root_shell(int rfd, sd_varlink **mute_console_link) {
|
static int prompt_root_shell(int rfd) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0);
|
assert(rfd >= 0);
|
||||||
@ -844,7 +838,7 @@ static int prompt_root_shell(int rfd, sd_varlink **mute_console_link) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_welcome(rfd, mute_console_link);
|
print_welcome(rfd);
|
||||||
|
|
||||||
return prompt_loop(
|
return prompt_loop(
|
||||||
"Please enter the new root shell",
|
"Please enter the new root shell",
|
||||||
@ -1011,7 +1005,7 @@ static int write_root_shadow(int etc_fd, const char *hashed_password) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_root_account(int rfd, sd_varlink **mute_console_link) {
|
static int process_root_account(int rfd) {
|
||||||
_cleanup_close_ int pfd = -EBADF;
|
_cleanup_close_ int pfd = -EBADF;
|
||||||
_cleanup_(release_lock_file) LockFile lock = LOCK_FILE_INIT;
|
_cleanup_(release_lock_file) LockFile lock = LOCK_FILE_INIT;
|
||||||
_cleanup_(erase_and_freep) char *_hashed_password = NULL;
|
_cleanup_(erase_and_freep) char *_hashed_password = NULL;
|
||||||
@ -1065,7 +1059,7 @@ static int process_root_account(int rfd, sd_varlink **mute_console_link) {
|
|||||||
return log_oom();
|
return log_oom();
|
||||||
}
|
}
|
||||||
|
|
||||||
r = prompt_root_shell(rfd, mute_console_link);
|
r = prompt_root_shell(rfd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -1084,7 +1078,7 @@ static int process_root_account(int rfd, sd_varlink **mute_console_link) {
|
|||||||
arg_root_password_is_hashed = true;
|
arg_root_password_is_hashed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = prompt_root_password(rfd, mute_console_link);
|
r = prompt_root_password(rfd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -1252,8 +1246,6 @@ static int help(void) {
|
|||||||
" --welcome=no Disable the welcome text\n"
|
" --welcome=no Disable the welcome text\n"
|
||||||
" --chrome=no Don't show color bar at top and bottom of\n"
|
" --chrome=no Don't show color bar at top and bottom of\n"
|
||||||
" terminal\n"
|
" terminal\n"
|
||||||
" --mute-console=yes Tell kernel/PID 1 to not write to the console\n"
|
|
||||||
" while running\n"
|
|
||||||
" --reset Remove existing files\n"
|
" --reset Remove existing files\n"
|
||||||
"\nSee the %2$s for details.\n",
|
"\nSee the %2$s for details.\n",
|
||||||
program_invocation_short_name,
|
program_invocation_short_name,
|
||||||
@ -1301,7 +1293,6 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
ARG_WELCOME,
|
ARG_WELCOME,
|
||||||
ARG_CHROME,
|
ARG_CHROME,
|
||||||
ARG_RESET,
|
ARG_RESET,
|
||||||
ARG_MUTE_CONSOLE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
@ -1340,7 +1331,6 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
{ "welcome", required_argument, NULL, ARG_WELCOME },
|
{ "welcome", required_argument, NULL, ARG_WELCOME },
|
||||||
{ "chrome", required_argument, NULL, ARG_CHROME },
|
{ "chrome", required_argument, NULL, ARG_CHROME },
|
||||||
{ "reset", no_argument, NULL, ARG_RESET },
|
{ "reset", no_argument, NULL, ARG_RESET },
|
||||||
{ "mute-console", required_argument, NULL, ARG_MUTE_CONSOLE },
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1560,13 +1550,6 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
arg_reset = true;
|
arg_reset = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARG_MUTE_CONSOLE:
|
|
||||||
r = parse_boolean_argument("--mute-console=", optarg, &arg_mute_console);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@ -1729,28 +1712,27 @@ static int run(int argc, char *argv[]) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
_cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *mute_console_link = NULL;
|
r = process_locale(rfd);
|
||||||
r = process_locale(rfd, &mute_console_link);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (r > 0 && !offline)
|
if (r > 0 && !offline)
|
||||||
(void) reload_system_manager(&bus);
|
(void) reload_system_manager(&bus);
|
||||||
|
|
||||||
r = process_keymap(rfd, &mute_console_link);
|
r = process_keymap(rfd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (r > 0 && !offline)
|
if (r > 0 && !offline)
|
||||||
(void) reload_vconsole(&bus);
|
(void) reload_vconsole(&bus);
|
||||||
|
|
||||||
r = process_timezone(rfd, &mute_console_link);
|
r = process_timezone(rfd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = process_hostname(rfd, &mute_console_link);
|
r = process_hostname(rfd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = process_root_account(rfd, &mute_console_link);
|
r = process_root_account(rfd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#if HAVE_SELINUX
|
||||||
|
#include <selinux/selinux.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -23,7 +27,6 @@
|
|||||||
#include "prioq.h"
|
#include "prioq.h"
|
||||||
#include "process-util.h"
|
#include "process-util.h"
|
||||||
#include "procfs-util.h"
|
#include "procfs-util.h"
|
||||||
#include "selinux-util.h"
|
|
||||||
#include "set.h"
|
#include "set.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "syslog-util.h"
|
#include "syslog-util.h"
|
||||||
@ -254,9 +257,6 @@ static int client_context_read_label(
|
|||||||
assert(pid_is_valid(c->pid));
|
assert(pid_is_valid(c->pid));
|
||||||
assert(label_size == 0 || label);
|
assert(label_size == 0 || label);
|
||||||
|
|
||||||
if (!mac_selinux_use())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (label_size > 0) {
|
if (label_size > 0) {
|
||||||
char *l;
|
char *l;
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ static int client_context_read_label(
|
|||||||
|
|
||||||
/* If we got no SELinux label passed in, let's try to acquire one */
|
/* If we got no SELinux label passed in, let's try to acquire one */
|
||||||
|
|
||||||
if (sym_getpidcon_raw(c->pid, &con) >= 0 && con) {
|
if (getpidcon(c->pid, &con) >= 0 && con) {
|
||||||
free_and_replace(c->label, con);
|
free_and_replace(c->label, con);
|
||||||
c->label_size = strlen(c->label);
|
c->label_size = strlen(c->label);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,7 +58,7 @@ journal_test_template = test_template + {
|
|||||||
|
|
||||||
journal_fuzz_template = fuzz_template + {
|
journal_fuzz_template = fuzz_template + {
|
||||||
'objects' : ['systemd-journald'],
|
'objects' : ['systemd-journald'],
|
||||||
'dependencies' : libselinux_cflags,
|
'dependencies' : libselinux,
|
||||||
}
|
}
|
||||||
|
|
||||||
executables += [
|
executables += [
|
||||||
@ -69,7 +69,7 @@ executables += [
|
|||||||
'extract' : systemd_journald_extract_sources,
|
'extract' : systemd_journald_extract_sources,
|
||||||
'dependencies' : [
|
'dependencies' : [
|
||||||
liblz4_cflags,
|
liblz4_cflags,
|
||||||
libselinux_cflags,
|
libselinux,
|
||||||
libxz_cflags,
|
libxz_cflags,
|
||||||
libzstd_cflags,
|
libzstd_cflags,
|
||||||
threads,
|
threads,
|
||||||
@ -87,7 +87,7 @@ executables += [
|
|||||||
'public' : true,
|
'public' : true,
|
||||||
'sources' : files('cat.c'),
|
'sources' : files('cat.c'),
|
||||||
'objects' : ['systemd-journald'],
|
'objects' : ['systemd-journald'],
|
||||||
'dependencies' : [threads],
|
'dependencies' : [libselinux, threads],
|
||||||
},
|
},
|
||||||
executable_template + {
|
executable_template + {
|
||||||
'name' : 'journalctl',
|
'name' : 'journalctl',
|
||||||
@ -106,7 +106,7 @@ executables += [
|
|||||||
'sources' : files('test-journald-config.c'),
|
'sources' : files('test-journald-config.c'),
|
||||||
'dependencies' : [
|
'dependencies' : [
|
||||||
liblz4_cflags,
|
liblz4_cflags,
|
||||||
libselinux_cflags,
|
libselinux,
|
||||||
libxz_cflags,
|
libxz_cflags,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -114,7 +114,7 @@ executables += [
|
|||||||
'sources' : files('test-journald-rate-limit.c'),
|
'sources' : files('test-journald-rate-limit.c'),
|
||||||
'dependencies' : [
|
'dependencies' : [
|
||||||
liblz4_cflags,
|
liblz4_cflags,
|
||||||
libselinux_cflags,
|
libselinux,
|
||||||
libxz_cflags,
|
libxz_cflags,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -122,7 +122,7 @@ executables += [
|
|||||||
'sources' : files('test-journald-syslog.c'),
|
'sources' : files('test-journald-syslog.c'),
|
||||||
'dependencies' : [
|
'dependencies' : [
|
||||||
liblz4_cflags,
|
liblz4_cflags,
|
||||||
libselinux_cflags,
|
libselinux,
|
||||||
libxz_cflags,
|
libxz_cflags,
|
||||||
threads,
|
threads,
|
||||||
],
|
],
|
||||||
@ -130,7 +130,7 @@ executables += [
|
|||||||
journal_test_template + {
|
journal_test_template + {
|
||||||
'sources' : files('test-journald-tables.c'),
|
'sources' : files('test-journald-tables.c'),
|
||||||
'dependencies' : [
|
'dependencies' : [
|
||||||
libselinux_cflags,
|
libselinux,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
journal_fuzz_template + {
|
journal_fuzz_template + {
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
|
|
||||||
executables += [
|
|
||||||
executable_template + {
|
|
||||||
'name' : 'systemd-mute-console',
|
|
||||||
'public' : true,
|
|
||||||
'sources' : files('mute-console.c'),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
@ -1,419 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
||||||
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "sd-bus.h"
|
|
||||||
#include "sd-event.h"
|
|
||||||
#include "sd-varlink.h"
|
|
||||||
|
|
||||||
#include "alloc-util.h"
|
|
||||||
#include "ansi-color.h"
|
|
||||||
#include "build.h"
|
|
||||||
#include "bus-error.h"
|
|
||||||
#include "bus-locator.h"
|
|
||||||
#include "bus-util.h"
|
|
||||||
#include "daemon-util.h"
|
|
||||||
#include "errno-util.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "main-func.h"
|
|
||||||
#include "parse-argument.h"
|
|
||||||
#include "pretty-print.h"
|
|
||||||
#include "printk-util.h"
|
|
||||||
#include "varlink-io.systemd.MuteConsole.h"
|
|
||||||
#include "varlink-util.h"
|
|
||||||
#include "virt.h"
|
|
||||||
|
|
||||||
static bool arg_mute_pid1 = true;
|
|
||||||
static bool arg_mute_kernel = true;
|
|
||||||
static bool arg_varlink = false;
|
|
||||||
|
|
||||||
static int help(void) {
|
|
||||||
_cleanup_free_ char *link = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = terminal_urlify_man("systemd-mute-console", "1", &link);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
printf("%s [OPTIONS...]\n"
|
|
||||||
"\n%sMute status output to the console.%s\n\n"
|
|
||||||
" -h --help Show this help\n"
|
|
||||||
" --version Show package version\n"
|
|
||||||
" --kernel=BOOL Mute kernel log output\n"
|
|
||||||
" --pid1=BOOL Mute PID 1 status output\n"
|
|
||||||
"\nSee the %s for details.\n",
|
|
||||||
program_invocation_short_name,
|
|
||||||
ansi_highlight(),
|
|
||||||
ansi_normal(),
|
|
||||||
link);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_argv(int argc, char *argv[]) {
|
|
||||||
|
|
||||||
enum {
|
|
||||||
ARG_VERSION = 0x100,
|
|
||||||
ARG_KERNEL,
|
|
||||||
ARG_PID1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct option options[] = {
|
|
||||||
{ "help", no_argument, NULL, 'h' },
|
|
||||||
{ "version", no_argument, NULL, ARG_VERSION },
|
|
||||||
{ "kernel", required_argument, NULL, ARG_KERNEL },
|
|
||||||
{ "pid1", required_argument, NULL, ARG_PID1 },
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
int c, r;
|
|
||||||
|
|
||||||
assert(argc >= 0);
|
|
||||||
assert(argv);
|
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "hq", options, NULL)) >= 0) {
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
|
|
||||||
case 'h':
|
|
||||||
return help();
|
|
||||||
|
|
||||||
case ARG_VERSION:
|
|
||||||
return version();
|
|
||||||
|
|
||||||
case ARG_PID1:
|
|
||||||
r = parse_boolean_argument("--pid1=", optarg, &arg_mute_pid1);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARG_KERNEL:
|
|
||||||
r = parse_boolean_argument("--kernel=", optarg, &arg_mute_kernel);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '?':
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert_not_reached();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sd_varlink_invocation(SD_VARLINK_ALLOW_ACCEPT);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to check if invoked in Varlink mode: %m");
|
|
||||||
if (r > 0)
|
|
||||||
arg_varlink = true;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_show_status(const char *value) {
|
|
||||||
int r;
|
|
||||||
assert(value);
|
|
||||||
|
|
||||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
|
||||||
r = bus_connect_system_systemd(&bus);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to connect to systemd: %m");
|
|
||||||
|
|
||||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
|
||||||
r = bus_call_method(bus, bus_systemd_mgr, "SetShowStatus", &error, /* ret_reply= */ NULL, "s", value);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to issue SetShowStatus() method call: %s", bus_error_message(&error, r));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct Context {
|
|
||||||
bool mute_pid1;
|
|
||||||
bool mute_kernel;
|
|
||||||
|
|
||||||
bool muted_pid1;
|
|
||||||
int saved_kernel;
|
|
||||||
|
|
||||||
sd_varlink *link;
|
|
||||||
} Context;
|
|
||||||
|
|
||||||
static int mute_pid1(Context *c) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(c);
|
|
||||||
|
|
||||||
if (!c->mute_pid1) {
|
|
||||||
log_debug("Muting of PID 1 status console output disabled.");
|
|
||||||
c->muted_pid1 = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = set_show_status("no");
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
log_debug("Successfully muted PID 1 status console output.");
|
|
||||||
|
|
||||||
c->muted_pid1 = true;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int unmute_pid1(Context *c) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(c);
|
|
||||||
|
|
||||||
if (!c->muted_pid1) {
|
|
||||||
log_debug("Not restoring PID 1 status console output level.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = set_show_status("");
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
log_debug("Successfully unmuted PID 1 status console output.");
|
|
||||||
c->muted_pid1 = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mute_kernel(Context *c) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(c);
|
|
||||||
|
|
||||||
if (!arg_mute_kernel) {
|
|
||||||
log_debug("Muting of kernel printk() console output disabled.");
|
|
||||||
c->saved_kernel = -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (detect_container() > 0) {
|
|
||||||
log_debug("Skipping muting of print() console output, because running in a container.");
|
|
||||||
c->saved_kernel = -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int level = sysctl_printk_read();
|
|
||||||
if (level < 0)
|
|
||||||
return log_error_errno(level, "Failed to read kernel printk() console output level: %m");
|
|
||||||
|
|
||||||
if (level == 0) {
|
|
||||||
log_info("Not muting kernel printk() console output, since it is already disabled.");
|
|
||||||
c->saved_kernel = -1; /* don't bother with restoring */
|
|
||||||
} else {
|
|
||||||
r = sysctl_printk_write(0);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to change kernel printk() console output level: %m");
|
|
||||||
|
|
||||||
log_debug("Successfully muted kernel printk() console output.");
|
|
||||||
c->saved_kernel = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int unmute_kernel(Context *c) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(c);
|
|
||||||
|
|
||||||
if (c->saved_kernel < 0) {
|
|
||||||
log_debug("Not restoring kernel printk() console output level.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int level = sysctl_printk_read();
|
|
||||||
if (level < 0)
|
|
||||||
return log_error_errno(level, "Failed to read kernel printk() console output level: %m");
|
|
||||||
|
|
||||||
if (level != 0) {
|
|
||||||
log_info("Not unmuting kernel printk() console output, since it has been changed externally in the meantime.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sysctl_printk_write(c->saved_kernel);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to unmute kernel printk() console output level: %m");
|
|
||||||
|
|
||||||
log_debug("Successfully unmuted kernel printk() console output.");
|
|
||||||
c->saved_kernel = -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void context_done(Context *c) {
|
|
||||||
assert(c);
|
|
||||||
|
|
||||||
(void) unmute_pid1(c);
|
|
||||||
(void) unmute_kernel(c);
|
|
||||||
|
|
||||||
if (c->link) {
|
|
||||||
(void) sd_varlink_set_userdata(c->link, NULL);
|
|
||||||
c->link = sd_varlink_flush_close_unref(c->link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Context* context_free(Context *c) {
|
|
||||||
if (!c)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
context_done(c);
|
|
||||||
return mfree(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Context*, context_free);
|
|
||||||
|
|
||||||
static void vl_on_disconnect(sd_varlink_server *server, sd_varlink *link, void *userdata) {
|
|
||||||
assert(link);
|
|
||||||
|
|
||||||
Context *c = sd_varlink_get_userdata(link);
|
|
||||||
if (!c)
|
|
||||||
return;
|
|
||||||
|
|
||||||
context_free(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int vl_method_mute(
|
|
||||||
sd_varlink *link,
|
|
||||||
sd_json_variant *parameters,
|
|
||||||
sd_varlink_method_flags_t flags,
|
|
||||||
void *userdata) {
|
|
||||||
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(link);
|
|
||||||
|
|
||||||
_cleanup_(context_freep) Context *nc = new(Context, 1);
|
|
||||||
if (!nc)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
*nc = (Context) {
|
|
||||||
.mute_pid1 = true,
|
|
||||||
.mute_kernel = true,
|
|
||||||
.saved_kernel = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const sd_json_dispatch_field dispatch_table[] = {
|
|
||||||
{ "kernel", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(Context, mute_kernel), 0 },
|
|
||||||
{ "pid1", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(Context, mute_pid1), 0 },
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
r = sd_varlink_dispatch(link, parameters, dispatch_table, nc);
|
|
||||||
if (r != 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
|
|
||||||
return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL);
|
|
||||||
|
|
||||||
r = sd_varlink_server_bind_disconnect(sd_varlink_get_server(link), vl_on_disconnect);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
(void) sd_varlink_set_userdata(link, nc);
|
|
||||||
nc->link = sd_varlink_ref(link);
|
|
||||||
Context *c = TAKE_PTR(nc); /* the Context object is now managed by the disconnect handler, not us anymore */
|
|
||||||
|
|
||||||
r = 0;
|
|
||||||
RET_GATHER(r, mute_pid1(c));
|
|
||||||
RET_GATHER(r, mute_kernel(c));
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
/* Let client know we are muted now. We use sd_varlink_notify() here (rather than sd_varlink_reply())
|
|
||||||
* because we want to keep the method call open, as we want that the lifetime of the
|
|
||||||
* connection/method call to determine how long we keep the console muted. */
|
|
||||||
r = sd_varlink_notify(link, /* parameters= */ NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int vl_server(void) {
|
|
||||||
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *varlink_server = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
/* Invocation as Varlink service */
|
|
||||||
|
|
||||||
r = varlink_server_new(
|
|
||||||
&varlink_server,
|
|
||||||
SD_VARLINK_SERVER_ROOT_ONLY|
|
|
||||||
SD_VARLINK_SERVER_HANDLE_SIGINT|
|
|
||||||
SD_VARLINK_SERVER_HANDLE_SIGTERM,
|
|
||||||
/* userdata= */ NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to allocate Varlink server: %m");
|
|
||||||
|
|
||||||
r = sd_varlink_server_add_interface(varlink_server, &vl_interface_io_systemd_MuteConsole);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to add Varlink interface: %m");
|
|
||||||
|
|
||||||
r = sd_varlink_server_bind_method_many(
|
|
||||||
varlink_server,
|
|
||||||
"io.systemd.MuteConsole.Mute", vl_method_mute);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to bind Varlink methods: %m");
|
|
||||||
|
|
||||||
r = sd_varlink_server_loop_auto(varlink_server);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to run Varlink event loop: %m");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int run(int argc, char* argv[]) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
log_setup();
|
|
||||||
|
|
||||||
r = parse_argv(argc, argv);
|
|
||||||
if (r <= 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (arg_varlink)
|
|
||||||
return vl_server();
|
|
||||||
|
|
||||||
if (!arg_mute_pid1 && !arg_mute_kernel)
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Not asked to mute anything, refusing.");
|
|
||||||
|
|
||||||
_cleanup_(context_done) Context c = {
|
|
||||||
.mute_pid1 = arg_mute_pid1,
|
|
||||||
.mute_kernel = arg_mute_kernel,
|
|
||||||
.saved_kernel = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
|
|
||||||
r = sd_event_new(&event);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to get default event source: %m");
|
|
||||||
|
|
||||||
(void) sd_event_set_watchdog(event, true);
|
|
||||||
(void) sd_event_set_signal_exit(event, true);
|
|
||||||
|
|
||||||
int ret = 0;
|
|
||||||
RET_GATHER(ret, mute_pid1(&c));
|
|
||||||
RET_GATHER(ret, mute_kernel(&c));
|
|
||||||
|
|
||||||
/* Now tell service manager we area ready to go */
|
|
||||||
_unused_ _cleanup_(notify_on_cleanup) const char *notify_message =
|
|
||||||
notify_start("READY=1\n"
|
|
||||||
"STATUS=Console status output muted temporarily.",
|
|
||||||
"STOPPING=1\n"
|
|
||||||
"STATUS=Console status output unmuted.");
|
|
||||||
|
|
||||||
/* Now wait for SIGINT/SIGTERM */
|
|
||||||
r = sd_event_loop(event);
|
|
||||||
if (r < 0)
|
|
||||||
RET_GATHER(ret, log_error_errno(r, "Failed to run event loop: %m"));
|
|
||||||
|
|
||||||
RET_GATHER(ret, unmute_pid1(&c));
|
|
||||||
RET_GATHER(ret, unmute_kernel(&c));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_MAIN_FUNCTION(run);
|
|
||||||
@ -21,7 +21,7 @@
|
|||||||
ip={dhcp|on|any|dhcp6|auto6|either6|link6|link-local}
|
ip={dhcp|on|any|dhcp6|auto6|either6|link6|link-local}
|
||||||
ip=<interface>:{dhcp|on|any|dhcp6|auto6|link6|link-local}[:[<mtu>][:<macaddr>]]
|
ip=<interface>:{dhcp|on|any|dhcp6|auto6|link6|link-local}[:[<mtu>][:<macaddr>]]
|
||||||
ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|link6|ibft|link-local}[:[<mtu>][:<macaddr>]]
|
ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|link6|ibft|link-local}[:[<mtu>][:<macaddr>]]
|
||||||
ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|link6|ibft|link-local}[:[<dns1>][:[<dns2>][:[<ntp>]]]]
|
ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|link6|ibft|link-local}[:[<dns1>][:<dns2>]]
|
||||||
rd.route=<net>/<netmask>:<gateway>[:<interface>]
|
rd.route=<net>/<netmask>:<gateway>[:<interface>]
|
||||||
nameserver=<IP> [nameserver=<IP> ...]
|
nameserver=<IP> [nameserver=<IP> ...]
|
||||||
rd.peerdns=0
|
rd.peerdns=0
|
||||||
@ -197,7 +197,6 @@ static Network* network_free(Network *network) {
|
|||||||
strv_free(network->vlan);
|
strv_free(network->vlan);
|
||||||
free(network->bridge);
|
free(network->bridge);
|
||||||
free(network->bond);
|
free(network->bond);
|
||||||
free(network->ntp);
|
|
||||||
|
|
||||||
while ((address = network->addresses))
|
while ((address = network->addresses))
|
||||||
address_free(address);
|
address_free(address);
|
||||||
@ -651,27 +650,6 @@ static int network_set_bond(Context *context, const char *ifname, const char *va
|
|||||||
return free_and_strdup(&network->bond, value);
|
return free_and_strdup(&network->bond, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int network_set_ntp(Context *context, const char *ifname, const char *value) {
|
|
||||||
Network *network;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(context);
|
|
||||||
assert(ifname);
|
|
||||||
|
|
||||||
if (isempty(value))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
r = in_addr_from_string_auto(value, NULL, NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Invalid NTP address '%s' for '%s'", value, ifname);
|
|
||||||
|
|
||||||
r = network_acquire(context, ifname, &network);
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Failed to acquire network for '%s': %m", ifname);
|
|
||||||
|
|
||||||
return free_and_strdup(&network->ntp, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, const char *value) {
|
static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, const char *value) {
|
||||||
_cleanup_free_ char *mtu = NULL;
|
_cleanup_free_ char *mtu = NULL;
|
||||||
int r;
|
int r;
|
||||||
@ -887,18 +865,6 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* Next, try [:<ntp>] */
|
|
||||||
_cleanup_free_ char *ntp = NULL;
|
|
||||||
r = extract_ip_address_str(AF_UNSPEC, &p, &ntp);
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Failed to parse NTP address in ip=%s: %m", value);
|
|
||||||
if (r == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
r = network_set_ntp(context, ifname, ntp);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
/* refuse unexpected trailing strings */
|
/* refuse unexpected trailing strings */
|
||||||
if (!isempty(p))
|
if (!isempty(p))
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unexpected trailing string in 'ip=%s'.", value);
|
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unexpected trailing string in 'ip=%s'.", value);
|
||||||
@ -1407,9 +1373,6 @@ void network_dump(Network *network, FILE *f) {
|
|||||||
if (network->bond)
|
if (network->bond)
|
||||||
fprintf(f, "Bond=%s\n", network->bond);
|
fprintf(f, "Bond=%s\n", network->bond);
|
||||||
|
|
||||||
if (network->ntp)
|
|
||||||
fprintf(f, "NTP=%s\n", network->ntp);
|
|
||||||
|
|
||||||
fputs("\n[DHCP]\n", f);
|
fputs("\n[DHCP]\n", f);
|
||||||
|
|
||||||
if (!isempty(network->hostname))
|
if (!isempty(network->hostname))
|
||||||
|
|||||||
@ -65,7 +65,6 @@ struct Network {
|
|||||||
char **vlan;
|
char **vlan;
|
||||||
char *bridge;
|
char *bridge;
|
||||||
char *bond;
|
char *bond;
|
||||||
char *ntp;
|
|
||||||
|
|
||||||
/* [DHCP] */
|
/* [DHCP] */
|
||||||
char *hostname;
|
char *hostname;
|
||||||
|
|||||||
@ -213,51 +213,6 @@ int main(int argc, char *argv[]) {
|
|||||||
"Gateway=192.168.0.1\n"
|
"Gateway=192.168.0.1\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
test_network_one("eth0", "ip", "192.168.0.10::192.168.0.1:255.255.255.0::eth0:on:10.10.10.10:10.10.10.11:10.10.10.161",
|
|
||||||
"[Match]\n"
|
|
||||||
"Name=eth0\n"
|
|
||||||
"\n[Link]\n"
|
|
||||||
"\n[Network]\n"
|
|
||||||
"DHCP=yes\n"
|
|
||||||
"DNS=10.10.10.10\n"
|
|
||||||
"DNS=10.10.10.11\n"
|
|
||||||
"NTP=10.10.10.161\n"
|
|
||||||
"\n[DHCP]\n"
|
|
||||||
"\n[Address]\n"
|
|
||||||
"Address=192.168.0.10/24\n"
|
|
||||||
"\n[Route]\n"
|
|
||||||
"Gateway=192.168.0.1\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
test_network_one("eth0", "ip", "192.168.0.10::192.168.0.1:255.255.255.0::eth0:on:10.10.10.10::10.10.10.161",
|
|
||||||
"[Match]\n"
|
|
||||||
"Name=eth0\n"
|
|
||||||
"\n[Link]\n"
|
|
||||||
"\n[Network]\n"
|
|
||||||
"DHCP=yes\n"
|
|
||||||
"DNS=10.10.10.10\n"
|
|
||||||
"NTP=10.10.10.161\n"
|
|
||||||
"\n[DHCP]\n"
|
|
||||||
"\n[Address]\n"
|
|
||||||
"Address=192.168.0.10/24\n"
|
|
||||||
"\n[Route]\n"
|
|
||||||
"Gateway=192.168.0.1\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
test_network_one("eth0", "ip", "192.168.0.10::192.168.0.1:255.255.255.0::eth0:on:::10.10.10.161",
|
|
||||||
"[Match]\n"
|
|
||||||
"Name=eth0\n"
|
|
||||||
"\n[Link]\n"
|
|
||||||
"\n[Network]\n"
|
|
||||||
"DHCP=yes\n"
|
|
||||||
"NTP=10.10.10.161\n"
|
|
||||||
"\n[DHCP]\n"
|
|
||||||
"\n[Address]\n"
|
|
||||||
"Address=192.168.0.10/24\n"
|
|
||||||
"\n[Route]\n"
|
|
||||||
"Gateway=192.168.0.1\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
test_network_one("eth0", "ip", "[2001:1234:56:8f63::10]::[2001:1234:56:8f63::1]:64:hogehoge:eth0:on",
|
test_network_one("eth0", "ip", "[2001:1234:56:8f63::10]::[2001:1234:56:8f63::1]:64:hogehoge:eth0:on",
|
||||||
"[Match]\n"
|
"[Match]\n"
|
||||||
"Name=eth0\n"
|
"Name=eth0\n"
|
||||||
|
|||||||
@ -768,7 +768,7 @@ static int link_status_one(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return table_log_add_error(r);
|
return table_log_add_error(r);
|
||||||
|
|
||||||
r = table_add_cell_stringf(table, NULL, "%sBps/%sBps",
|
r = table_add_cell_stringf(table, NULL, "%sbps/%sbps",
|
||||||
FORMAT_BYTES_FULL(info->tx_bitrate, 0),
|
FORMAT_BYTES_FULL(info->tx_bitrate, 0),
|
||||||
FORMAT_BYTES_FULL(info->rx_bitrate, 0));
|
FORMAT_BYTES_FULL(info->rx_bitrate, 0));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|||||||
@ -444,15 +444,14 @@ static int network_append_json(Network *network, sd_json_variant **v) {
|
|||||||
v,
|
v,
|
||||||
SD_JSON_BUILD_PAIR_STRING("NetworkFile", network->filename),
|
SD_JSON_BUILD_PAIR_STRING("NetworkFile", network->filename),
|
||||||
SD_JSON_BUILD_PAIR_STRV("NetworkFileDropins", network->dropins),
|
SD_JSON_BUILD_PAIR_STRV("NetworkFileDropins", network->dropins),
|
||||||
SD_JSON_BUILD_PAIR_BOOLEAN("RequiredForOnline", network->required_for_online > 0),
|
SD_JSON_BUILD_PAIR_BOOLEAN("RequiredForOnline", network->required_for_online),
|
||||||
SD_JSON_BUILD_PAIR_CONDITION(
|
SD_JSON_BUILD_PAIR("RequiredOperationalStateForOnline",
|
||||||
operational_state_range_is_valid(&network->required_operstate_for_online),
|
SD_JSON_BUILD_ARRAY(SD_JSON_BUILD_STRING(link_operstate_to_string(network->required_operstate_for_online.min)),
|
||||||
"RequiredOperationalStateForOnline",
|
SD_JSON_BUILD_STRING(link_operstate_to_string(network->required_operstate_for_online.max)))),
|
||||||
SD_JSON_BUILD_ARRAY(
|
SD_JSON_BUILD_PAIR_STRING("RequiredFamilyForOnline",
|
||||||
SD_JSON_BUILD_STRING(link_operstate_to_string(network->required_operstate_for_online.min)),
|
link_required_address_family_to_string(network->required_family_for_online)),
|
||||||
SD_JSON_BUILD_STRING(link_operstate_to_string(network->required_operstate_for_online.max)))),
|
SD_JSON_BUILD_PAIR_STRING("ActivationPolicy",
|
||||||
SD_JSON_BUILD_PAIR_STRING("RequiredFamilyForOnline", link_required_address_family_to_string(network->required_family_for_online)),
|
activation_policy_to_string(network->activation_policy)));
|
||||||
SD_JSON_BUILD_PAIR_STRING("ActivationPolicy", activation_policy_to_string(network->activation_policy)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int netdev_append_json(NetDev *netdev, sd_json_variant **v) {
|
static int netdev_append_json(NetDev *netdev, sd_json_variant **v) {
|
||||||
|
|||||||
@ -48,7 +48,7 @@ executables += [
|
|||||||
'extract' : nspawn_extract_sources,
|
'extract' : nspawn_extract_sources,
|
||||||
'dependencies' : [
|
'dependencies' : [
|
||||||
libseccomp_cflags,
|
libseccomp_cflags,
|
||||||
libselinux_cflags,
|
libselinux,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
nspawn_test_template + {
|
nspawn_test_template + {
|
||||||
|
|||||||
@ -13,6 +13,10 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#if HAVE_SELINUX
|
||||||
|
#include <selinux/selinux.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "sd-bus.h"
|
#include "sd-bus.h"
|
||||||
#include "sd-daemon.h"
|
#include "sd-daemon.h"
|
||||||
#include "sd-event.h"
|
#include "sd-event.h"
|
||||||
@ -100,7 +104,6 @@
|
|||||||
#include "rm-rf.h"
|
#include "rm-rf.h"
|
||||||
#include "runtime-scope.h"
|
#include "runtime-scope.h"
|
||||||
#include "seccomp-util.h"
|
#include "seccomp-util.h"
|
||||||
#include "selinux-util.h"
|
|
||||||
#include "shift-uid.h"
|
#include "shift-uid.h"
|
||||||
#include "signal-util.h"
|
#include "signal-util.h"
|
||||||
#include "siphash24.h"
|
#include "siphash24.h"
|
||||||
@ -3529,8 +3532,8 @@ static int inner_child(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_SELINUX
|
#if HAVE_SELINUX
|
||||||
if (arg_selinux_context && mac_selinux_use())
|
if (arg_selinux_context)
|
||||||
if (sym_setexeccon_raw(arg_selinux_context) < 0)
|
if (setexeccon(arg_selinux_context) < 0)
|
||||||
return log_error_errno(errno, "setexeccon(\"%s\") failed: %m", arg_selinux_context);
|
return log_error_errno(errno, "setexeccon(\"%s\") failed: %m", arg_selinux_context);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@ executables += [
|
|||||||
'sources' : systemd_portabled_sources,
|
'sources' : systemd_portabled_sources,
|
||||||
'link_with' : portabled_link_with,
|
'link_with' : portabled_link_with,
|
||||||
'dependencies' : [
|
'dependencies' : [
|
||||||
libselinux_cflags,
|
libselinux,
|
||||||
threads,
|
threads,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@ -310,11 +310,10 @@ static int extract_now(
|
|||||||
#if HAVE_SELINUX
|
#if HAVE_SELINUX
|
||||||
/* The units will be copied on the host's filesystem, so if they had a SELinux label
|
/* The units will be copied on the host's filesystem, so if they had a SELinux label
|
||||||
* we have to preserve it. Copy it out so that it can be applied later. */
|
* we have to preserve it. Copy it out so that it can be applied later. */
|
||||||
if (mac_selinux_use()) {
|
|
||||||
r = sym_fgetfilecon_raw(fd, &con);
|
r = fgetfilecon_raw(fd, &con);
|
||||||
if (r < 0 && !ERRNO_IS_XATTR_ABSENT(errno))
|
if (r < 0 && !ERRNO_IS_XATTR_ABSENT(errno))
|
||||||
log_debug_errno(errno, "Failed to get SELinux file context from '%s', ignoring: %m", de->d_name);
|
log_debug_errno(errno, "Failed to get SELinux file context from '%s', ignoring: %m", de->d_name);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (socket_fd >= 0) {
|
if (socket_fd >= 0) {
|
||||||
|
|||||||
@ -2809,7 +2809,7 @@ static int partition_read_definition(Partition *p, const char *path, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Verity partitions are read only, let's imply the RO flag hence, unless explicitly configured otherwise. */
|
/* Verity partitions are read only, let's imply the RO flag hence, unless explicitly configured otherwise. */
|
||||||
if ((partition_designator_is_verity_hash(p->type.designator) || p->verity == VERITY_DATA) && p->read_only < 0)
|
if ((partition_designator_is_verity(p->type.designator) || p->verity == VERITY_DATA) && p->read_only < 0)
|
||||||
p->read_only = true;
|
p->read_only = true;
|
||||||
|
|
||||||
/* Default to "growfs" on, unless read-only */
|
/* Default to "growfs" on, unless read-only */
|
||||||
@ -7500,7 +7500,7 @@ static int resolve_copy_blocks_auto_candidate_harder(
|
|||||||
* verity/verity-sig partition for it, based on udev metadata. */
|
* verity/verity-sig partition for it, based on udev metadata. */
|
||||||
|
|
||||||
const char *property;
|
const char *property;
|
||||||
if (partition_designator_is_verity_hash(partition_type.designator))
|
if (partition_designator_is_verity(partition_type.designator))
|
||||||
property = "ID_DISSECT_PART_VERITY_DEVICE";
|
property = "ID_DISSECT_PART_VERITY_DEVICE";
|
||||||
else if (partition_designator_is_verity_sig(partition_type.designator))
|
else if (partition_designator_is_verity_sig(partition_type.designator))
|
||||||
property = "ID_DISSECT_PART_VERITY_SIG_DEVICE";
|
property = "ID_DISSECT_PART_VERITY_SIG_DEVICE";
|
||||||
|
|||||||
@ -1060,31 +1060,9 @@ static int dissect_image(
|
|||||||
if (!image_filter_test(filter, type.designator, label))
|
if (!image_filter_test(filter, type.designator, label))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
log_debug("Dissecting %s partition with label %s and UUID %s.",
|
log_debug("Dissecting %s partition with label %s and UUID %s",
|
||||||
strna(partition_designator_to_string(type.designator)), strna(label), SD_ID128_TO_UUID_STRING(id));
|
strna(partition_designator_to_string(type.designator)), strna(label), SD_ID128_TO_UUID_STRING(id));
|
||||||
|
|
||||||
/* Note that we don't check the SD_GPT_FLAG_NO_AUTO flag for the ESP, as it is
|
|
||||||
* not defined there. We instead check the SD_GPT_FLAG_NO_BLOCK_IO_PROTOCOL, as
|
|
||||||
* recommended by the UEFI spec (See "12.3.3 Number and Location of System
|
|
||||||
* Partitions"). */
|
|
||||||
if (FLAGS_SET(pflags, SD_GPT_FLAG_NO_AUTO) && type.designator != PARTITION_ESP) {
|
|
||||||
log_debug("Partition has 'no auto' flag set, ignoring.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!verity && partition_designator_is_verity(type.designator)) {
|
|
||||||
log_debug("Partition is a verity hash or verity signature partition but no verity was requested, ignoring.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PartitionDesignator vd = partition_verity_to_data(type.designator);
|
|
||||||
if (verity && verity->designator >= 0 && vd >= 0 && vd != verity->designator) {
|
|
||||||
log_debug("Partition is a %s partition but verity was only requested for the %s partition, ignoring.",
|
|
||||||
partition_designator_to_string(type.designator),
|
|
||||||
partition_designator_to_string(verity->designator));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IN_SET(type.designator,
|
if (IN_SET(type.designator,
|
||||||
PARTITION_HOME,
|
PARTITION_HOME,
|
||||||
PARTITION_SRV,
|
PARTITION_SRV,
|
||||||
@ -1094,15 +1072,21 @@ static int dissect_image(
|
|||||||
check_partition_flags(node, pflags,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
||||||
|
|
||||||
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
|
continue;
|
||||||
|
|
||||||
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
||||||
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
|
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
|
||||||
|
|
||||||
} else if (type.designator == PARTITION_ESP) {
|
} else if (type.designator == PARTITION_ESP) {
|
||||||
|
|
||||||
if (FLAGS_SET(pflags, SD_GPT_FLAG_NO_BLOCK_IO_PROTOCOL)) {
|
/* Note that we don't check the SD_GPT_FLAG_NO_AUTO flag for the ESP, as it is
|
||||||
log_debug("ESP Partition has 'no block io' flag set, ignoring.");
|
* not defined there. We instead check the SD_GPT_FLAG_NO_BLOCK_IO_PROTOCOL, as
|
||||||
|
* recommended by the UEFI spec (See "12.3.3 Number and Location of System
|
||||||
|
* Partitions"). */
|
||||||
|
|
||||||
|
if (pflags & SD_GPT_FLAG_NO_BLOCK_IO_PROTOCOL)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
fstype = "vfat";
|
fstype = "vfat";
|
||||||
|
|
||||||
@ -1111,13 +1095,12 @@ static int dissect_image(
|
|||||||
check_partition_flags(node, pflags,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
||||||
|
|
||||||
/* If a root ID is specified, ignore everything but the root id */
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id)) {
|
continue;
|
||||||
log_debug("Partition UUID '%s' does not match expected UUID '%s' derived from root verity hash, ignoring.",
|
|
||||||
SD_ID128_TO_UUID_STRING(id),
|
/* If a root ID is specified, ignore everything but the root id */
|
||||||
SD_ID128_TO_UUID_STRING(root_uuid));
|
if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id))
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
||||||
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
|
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
|
||||||
@ -1127,15 +1110,20 @@ static int dissect_image(
|
|||||||
check_partition_flags(node, pflags,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
|
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
|
||||||
|
|
||||||
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
|
continue;
|
||||||
|
|
||||||
m->has_verity = true;
|
m->has_verity = true;
|
||||||
|
|
||||||
/* If root hash is specified, then ignore everything but the root id */
|
/* If no verity configuration is specified, then don't do verity */
|
||||||
if (!sd_id128_is_null(root_verity_uuid) && !sd_id128_equal(root_verity_uuid, id)) {
|
if (!verity)
|
||||||
log_debug("Partition UUID '%s' does not match expected UUID '%s' derived from root verity hash, ignoring.",
|
continue;
|
||||||
SD_ID128_TO_UUID_STRING(id),
|
if (verity->designator >= 0 && verity->designator != PARTITION_ROOT)
|
||||||
SD_ID128_TO_UUID_STRING(root_verity_uuid));
|
continue;
|
||||||
|
|
||||||
|
/* If root hash is specified, then ignore everything but the root id */
|
||||||
|
if (!sd_id128_is_null(root_verity_uuid) && !sd_id128_equal(root_verity_uuid, id))
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
fstype = "DM_verity_hash";
|
fstype = "DM_verity_hash";
|
||||||
rw = false;
|
rw = false;
|
||||||
@ -1145,7 +1133,16 @@ static int dissect_image(
|
|||||||
check_partition_flags(node, pflags,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
|
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
|
||||||
|
|
||||||
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
|
continue;
|
||||||
|
|
||||||
m->has_verity_sig = true;
|
m->has_verity_sig = true;
|
||||||
|
|
||||||
|
if (!verity)
|
||||||
|
continue;
|
||||||
|
if (verity->designator >= 0 && verity->designator != PARTITION_ROOT)
|
||||||
|
continue;
|
||||||
|
|
||||||
fstype = "verity_hash_signature";
|
fstype = "verity_hash_signature";
|
||||||
rw = false;
|
rw = false;
|
||||||
|
|
||||||
@ -1154,13 +1151,12 @@ static int dissect_image(
|
|||||||
check_partition_flags(node, pflags,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
||||||
|
|
||||||
/* If a usr ID is specified, ignore everything but the usr id */
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
if (!sd_id128_is_null(usr_uuid) && !sd_id128_equal(usr_uuid, id)) {
|
continue;
|
||||||
log_debug("Partition UUID '%s' does not match expected UUID '%s' derived from usr verity hash, ignoring.",
|
|
||||||
SD_ID128_TO_UUID_STRING(id),
|
/* If a usr ID is specified, ignore everything but the usr id */
|
||||||
SD_ID128_TO_UUID_STRING(usr_uuid));
|
if (!sd_id128_is_null(usr_uuid) && !sd_id128_equal(usr_uuid, id))
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
||||||
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
|
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
|
||||||
@ -1170,15 +1166,19 @@ static int dissect_image(
|
|||||||
check_partition_flags(node, pflags,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
|
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
|
||||||
|
|
||||||
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
|
continue;
|
||||||
|
|
||||||
m->has_verity = true;
|
m->has_verity = true;
|
||||||
|
|
||||||
/* If usr hash is specified, then ignore everything but the usr id */
|
if (!verity)
|
||||||
if (!sd_id128_is_null(usr_verity_uuid) && !sd_id128_equal(usr_verity_uuid, id)) {
|
continue;
|
||||||
log_debug("Partition UUID '%s' does not match expected UUID '%s' derived from usr verity hash, ignoring.",
|
if (verity->designator >= 0 && verity->designator != PARTITION_USR)
|
||||||
SD_ID128_TO_UUID_STRING(id),
|
continue;
|
||||||
SD_ID128_TO_UUID_STRING(usr_uuid));
|
|
||||||
|
/* If usr hash is specified, then ignore everything but the usr id */
|
||||||
|
if (!sd_id128_is_null(usr_verity_uuid) && !sd_id128_equal(usr_verity_uuid, id))
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
fstype = "DM_verity_hash";
|
fstype = "DM_verity_hash";
|
||||||
rw = false;
|
rw = false;
|
||||||
@ -1188,7 +1188,16 @@ static int dissect_image(
|
|||||||
check_partition_flags(node, pflags,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
|
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
|
||||||
|
|
||||||
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
|
continue;
|
||||||
|
|
||||||
m->has_verity_sig = true;
|
m->has_verity_sig = true;
|
||||||
|
|
||||||
|
if (!verity)
|
||||||
|
continue;
|
||||||
|
if (verity->designator >= 0 && verity->designator != PARTITION_USR)
|
||||||
|
continue;
|
||||||
|
|
||||||
fstype = "verity_hash_signature";
|
fstype = "verity_hash_signature";
|
||||||
rw = false;
|
rw = false;
|
||||||
|
|
||||||
@ -1196,6 +1205,9 @@ static int dissect_image(
|
|||||||
|
|
||||||
check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO);
|
check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO);
|
||||||
|
|
||||||
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Note: we don't set fstype = "swap" here, because we still need to probe if
|
/* Note: we don't set fstype = "swap" here, because we still need to probe if
|
||||||
* it might be encrypted (i.e. fstype "crypt_LUKS") or unencrypted
|
* it might be encrypted (i.e. fstype "crypt_LUKS") or unencrypted
|
||||||
* (i.e. fstype "swap"), and the only way to figure that out is via fstype
|
* (i.e. fstype "swap"), and the only way to figure that out is via fstype
|
||||||
@ -1210,6 +1222,9 @@ static int dissect_image(
|
|||||||
check_partition_flags(node, pflags,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
||||||
|
|
||||||
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (generic_node)
|
if (generic_node)
|
||||||
multiple_generic = true;
|
multiple_generic = true;
|
||||||
else {
|
else {
|
||||||
@ -1225,6 +1240,9 @@ static int dissect_image(
|
|||||||
check_partition_flags(node, pflags,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
||||||
|
|
||||||
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!FLAGS_SET(flags, DISSECT_IMAGE_RELAX_VAR_CHECK)) {
|
if (!FLAGS_SET(flags, DISSECT_IMAGE_RELAX_VAR_CHECK)) {
|
||||||
sd_id128_t var_uuid;
|
sd_id128_t var_uuid;
|
||||||
|
|
||||||
@ -1428,12 +1446,12 @@ static int dissect_image(
|
|||||||
m->partitions[PARTITION_ROOT_VERITY_SIG].found))
|
m->partitions[PARTITION_ROOT_VERITY_SIG].found))
|
||||||
return log_debug_errno(
|
return log_debug_errno(
|
||||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||||
"Found root verity hash partition without matching root data partition.");
|
"Found root verity hash partition without matching root data partition");
|
||||||
|
|
||||||
/* Hmm, we found a signature partition but no Verity data? Something is off. */
|
/* Hmm, we found a signature partition but no Verity data? Something is off. */
|
||||||
if (m->partitions[PARTITION_ROOT_VERITY_SIG].found && !m->partitions[PARTITION_ROOT_VERITY].found)
|
if (m->partitions[PARTITION_ROOT_VERITY_SIG].found && !m->partitions[PARTITION_ROOT_VERITY].found)
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||||
"Found root verity signature partition without matching root verity hash partition.");
|
"Found root verity signature partition without matching root verity hash partition");
|
||||||
|
|
||||||
/* as above */
|
/* as above */
|
||||||
if (!m->partitions[PARTITION_USR].found &&
|
if (!m->partitions[PARTITION_USR].found &&
|
||||||
@ -1441,12 +1459,12 @@ static int dissect_image(
|
|||||||
m->partitions[PARTITION_USR_VERITY_SIG].found))
|
m->partitions[PARTITION_USR_VERITY_SIG].found))
|
||||||
return log_debug_errno(
|
return log_debug_errno(
|
||||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||||
"Found usr verity hash partition without matching usr data partition.");
|
"Found usr verity hash partition without matching usr data partition");
|
||||||
|
|
||||||
/* as above */
|
/* as above */
|
||||||
if (m->partitions[PARTITION_USR_VERITY_SIG].found && !m->partitions[PARTITION_USR_VERITY].found)
|
if (m->partitions[PARTITION_USR_VERITY_SIG].found && !m->partitions[PARTITION_USR_VERITY].found)
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||||
"Found usr verity signature partition without matching usr verity hash partition.");
|
"Found usr verity signature partition without matching usr verity hash partition");
|
||||||
|
|
||||||
/* If root and /usr are combined then insist that the architecture matches */
|
/* If root and /usr are combined then insist that the architecture matches */
|
||||||
if (m->partitions[PARTITION_ROOT].found &&
|
if (m->partitions[PARTITION_ROOT].found &&
|
||||||
@ -1455,7 +1473,7 @@ static int dissect_image(
|
|||||||
m->partitions[PARTITION_USR].architecture >= 0 &&
|
m->partitions[PARTITION_USR].architecture >= 0 &&
|
||||||
m->partitions[PARTITION_ROOT].architecture != m->partitions[PARTITION_USR].architecture))
|
m->partitions[PARTITION_ROOT].architecture != m->partitions[PARTITION_USR].architecture))
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EREMOTE),
|
return log_debug_errno(SYNTHETIC_ERRNO(EREMOTE),
|
||||||
"Found root and usr partitions with different architectures (%s vs %s).",
|
"Found root and usr partitions with different architectures (%s vs %s)",
|
||||||
architecture_to_string(m->partitions[PARTITION_ROOT].architecture),
|
architecture_to_string(m->partitions[PARTITION_ROOT].architecture),
|
||||||
architecture_to_string(m->partitions[PARTITION_USR].architecture));
|
architecture_to_string(m->partitions[PARTITION_USR].architecture));
|
||||||
|
|
||||||
@ -1525,17 +1543,17 @@ static int dissect_image(
|
|||||||
/* Check if we have a root fs if we are told to do check. /usr alone is fine too, but only if appropriate flag for that is set too */
|
/* Check if we have a root fs if we are told to do check. /usr alone is fine too, but only if appropriate flag for that is set too */
|
||||||
if (FLAGS_SET(flags, DISSECT_IMAGE_REQUIRE_ROOT) &&
|
if (FLAGS_SET(flags, DISSECT_IMAGE_REQUIRE_ROOT) &&
|
||||||
!(m->partitions[PARTITION_ROOT].found || (m->partitions[PARTITION_USR].found && FLAGS_SET(flags, DISSECT_IMAGE_USR_NO_ROOT))))
|
!(m->partitions[PARTITION_ROOT].found || (m->partitions[PARTITION_USR].found && FLAGS_SET(flags, DISSECT_IMAGE_USR_NO_ROOT))))
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Root or usr partition requested but found neither.");
|
return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Root or usr partition requested but found neither");
|
||||||
|
|
||||||
if (m->partitions[PARTITION_ROOT_VERITY].found) {
|
if (m->partitions[PARTITION_ROOT_VERITY].found) {
|
||||||
/* We only support one verity partition per image, i.e. can't do for both /usr and root fs */
|
/* We only support one verity partition per image, i.e. can't do for both /usr and root fs */
|
||||||
if (m->partitions[PARTITION_USR_VERITY].found)
|
if (m->partitions[PARTITION_USR_VERITY].found)
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOTUNIQ), "Found both root and usr verity enabled partitions which is not supported.");
|
return log_debug_errno(SYNTHETIC_ERRNO(ENOTUNIQ), "Found both root and usr verity enabled partitions which is not supported");
|
||||||
|
|
||||||
/* We don't support verity enabled root with a split out /usr. Neither with nor without
|
/* We don't support verity enabled root with a split out /usr. Neither with nor without
|
||||||
* verity there. (Note that we do support verity-less root with verity-full /usr, though.) */
|
* verity there. (Note that we do support verity-less root with verity-full /usr, though.) */
|
||||||
if (m->partitions[PARTITION_USR].found)
|
if (m->partitions[PARTITION_USR].found)
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL), "Found verity enabled root partition with split usr partition which is not supported.");
|
return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL), "Found verity enabled root partition with split usr partition which is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verity) {
|
if (verity) {
|
||||||
@ -1543,7 +1561,7 @@ static int dissect_image(
|
|||||||
if (verity->designator >= 0 && !m->partitions[verity->designator].found)
|
if (verity->designator >= 0 && !m->partitions[verity->designator].found)
|
||||||
return log_debug_errno(
|
return log_debug_errno(
|
||||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||||
"Explicit %s verity designator was specified but did not find %s partition.",
|
"Explicit %s verity designator was specified but did not find %s partition",
|
||||||
partition_designator_to_string(verity->designator),
|
partition_designator_to_string(verity->designator),
|
||||||
partition_designator_to_string(verity->designator));
|
partition_designator_to_string(verity->designator));
|
||||||
|
|
||||||
@ -1555,12 +1573,12 @@ static int dissect_image(
|
|||||||
if (!m->partitions[PARTITION_ROOT].found)
|
if (!m->partitions[PARTITION_ROOT].found)
|
||||||
return log_debug_errno(
|
return log_debug_errno(
|
||||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||||
"Verity enabled root partition was requested but did not find a root data partition.");
|
"Verity enabled root partition was requested but did not find a root data partition");
|
||||||
|
|
||||||
if (!m->partitions[PARTITION_ROOT_VERITY].found)
|
if (!m->partitions[PARTITION_ROOT_VERITY].found)
|
||||||
return log_debug_errno(
|
return log_debug_errno(
|
||||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||||
"Verity enabled root partition was requested but did not find a root verity hash partition.");
|
"Verity enabled root partition was requested but did not find a root verity hash partition");
|
||||||
|
|
||||||
/* If we found a verity setup, then the root partition is necessarily read-only. */
|
/* If we found a verity setup, then the root partition is necessarily read-only. */
|
||||||
m->partitions[PARTITION_ROOT].rw = false;
|
m->partitions[PARTITION_ROOT].rw = false;
|
||||||
@ -1570,12 +1588,12 @@ static int dissect_image(
|
|||||||
if (!m->partitions[PARTITION_USR].found)
|
if (!m->partitions[PARTITION_USR].found)
|
||||||
return log_debug_errno(
|
return log_debug_errno(
|
||||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||||
"Verity enabled usr partition was requested but did not find a usr data partition.");
|
"Verity enabled usr partition was requested but did not find a usr data partition");
|
||||||
|
|
||||||
if (!m->partitions[PARTITION_USR_VERITY].found)
|
if (!m->partitions[PARTITION_USR_VERITY].found)
|
||||||
return log_debug_errno(
|
return log_debug_errno(
|
||||||
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
SYNTHETIC_ERRNO(EADDRNOTAVAIL),
|
||||||
"Verity enabled usr partition was requested but did not find a usr verity hash partition.");
|
"Verity enabled usr partition was requested but did not find a usr verity hash partition");
|
||||||
|
|
||||||
|
|
||||||
m->partitions[PARTITION_USR].rw = false;
|
m->partitions[PARTITION_USR].rw = false;
|
||||||
@ -1601,7 +1619,7 @@ static int dissect_image(
|
|||||||
if (m->partitions[di].found) {
|
if (m->partitions[di].found) {
|
||||||
found_flags = PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_UNUSED;
|
found_flags = PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_UNUSED;
|
||||||
|
|
||||||
PartitionDesignator vi = partition_verity_hash_of(di);
|
PartitionDesignator vi = partition_verity_of(di);
|
||||||
if (vi >= 0 && m->partitions[vi].found) {
|
if (vi >= 0 && m->partitions[vi].found) {
|
||||||
found_flags |= PARTITION_POLICY_VERITY;
|
found_flags |= PARTITION_POLICY_VERITY;
|
||||||
|
|
||||||
@ -1615,7 +1633,7 @@ static int dissect_image(
|
|||||||
if (DEBUG_LOGGING) {
|
if (DEBUG_LOGGING) {
|
||||||
_cleanup_free_ char *s = NULL;
|
_cleanup_free_ char *s = NULL;
|
||||||
(void) partition_policy_flags_to_string(found_flags, /* simplify= */ false, &s);
|
(void) partition_policy_flags_to_string(found_flags, /* simplify= */ false, &s);
|
||||||
log_debug("Found for designator %s: %s.", partition_designator_to_string(di), strna(s));
|
log_debug("Found for designator %s: %s", partition_designator_to_string(di), strna(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
r = image_policy_check_protection(policy, di, found_flags);
|
r = image_policy_check_protection(policy, di, found_flags);
|
||||||
@ -3101,7 +3119,7 @@ int dissected_image_decrypt(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
k = partition_verity_hash_of(i);
|
k = partition_verity_of(i);
|
||||||
if (k >= 0) {
|
if (k >= 0) {
|
||||||
flags |= getenv_bool("SYSTEMD_VERITY_SHARING") != 0 ? DISSECT_IMAGE_VERITY_SHARE : 0;
|
flags |= getenv_bool("SYSTEMD_VERITY_SHARING") != 0 ? DISSECT_IMAGE_VERITY_SHARE : 0;
|
||||||
|
|
||||||
@ -3590,7 +3608,7 @@ int dissected_image_load_verity_sig_partition(
|
|||||||
if (!m->partitions[dd].found)
|
if (!m->partitions[dd].found)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
PartitionDesignator dv = partition_verity_hash_of(dd);
|
PartitionDesignator dv = partition_verity_of(dd);
|
||||||
assert(dv >= 0);
|
assert(dv >= 0);
|
||||||
if (!m->partitions[dv].found)
|
if (!m->partitions[dv].found)
|
||||||
return 0;
|
return 0;
|
||||||
@ -3716,7 +3734,7 @@ int dissected_image_guess_verity_roothash(
|
|||||||
if (!d->found)
|
if (!d->found)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
PartitionDesignator dv = partition_verity_hash_of(dd);
|
PartitionDesignator dv = partition_verity_of(dd);
|
||||||
assert(dv >= 0);
|
assert(dv >= 0);
|
||||||
|
|
||||||
DissectedPartition *p = m->partitions + dv;
|
DissectedPartition *p = m->partitions + dv;
|
||||||
@ -4160,7 +4178,7 @@ bool dissected_image_verity_candidate(const DissectedImage *image, PartitionDesi
|
|||||||
if (image->single_file_system)
|
if (image->single_file_system)
|
||||||
return partition_designator == PARTITION_ROOT && image->has_verity;
|
return partition_designator == PARTITION_ROOT && image->has_verity;
|
||||||
|
|
||||||
return partition_verity_hash_of(partition_designator) >= 0;
|
return partition_verity_of(partition_designator) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dissected_image_verity_ready(const DissectedImage *image, PartitionDesignator partition_designator) {
|
bool dissected_image_verity_ready(const DissectedImage *image, PartitionDesignator partition_designator) {
|
||||||
@ -4177,7 +4195,7 @@ bool dissected_image_verity_ready(const DissectedImage *image, PartitionDesignat
|
|||||||
if (image->single_file_system)
|
if (image->single_file_system)
|
||||||
return partition_designator == PARTITION_ROOT;
|
return partition_designator == PARTITION_ROOT;
|
||||||
|
|
||||||
k = partition_verity_hash_of(partition_designator);
|
k = partition_verity_of(partition_designator);
|
||||||
return k >= 0 && image->partitions[k].found;
|
return k >= 0 && image->partitions[k].found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,7 @@ bool partition_designator_is_versioned(PartitionDesignator d) {
|
|||||||
PARTITION_USR_VERITY_SIG);
|
PARTITION_USR_VERITY_SIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionDesignator partition_verity_hash_of(PartitionDesignator p) {
|
PartitionDesignator partition_verity_of(PartitionDesignator p) {
|
||||||
switch (p) {
|
switch (p) {
|
||||||
|
|
||||||
case PARTITION_ROOT:
|
case PARTITION_ROOT:
|
||||||
@ -59,7 +59,7 @@ PartitionDesignator partition_verity_sig_of(PartitionDesignator p) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionDesignator partition_verity_hash_to_data(PartitionDesignator d) {
|
PartitionDesignator partition_verity_to_data(PartitionDesignator d) {
|
||||||
switch (d) {
|
switch (d) {
|
||||||
|
|
||||||
case PARTITION_ROOT_VERITY:
|
case PARTITION_ROOT_VERITY:
|
||||||
@ -87,14 +87,6 @@ PartitionDesignator partition_verity_sig_to_data(PartitionDesignator d) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionDesignator partition_verity_to_data(PartitionDesignator d) {
|
|
||||||
PartitionDesignator e = partition_verity_hash_to_data(d);
|
|
||||||
if (e >= 0)
|
|
||||||
return e;
|
|
||||||
|
|
||||||
return partition_verity_sig_to_data(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *const partition_designator_table[_PARTITION_DESIGNATOR_MAX] = {
|
static const char *const partition_designator_table[_PARTITION_DESIGNATOR_MAX] = {
|
||||||
[PARTITION_ROOT] = "root",
|
[PARTITION_ROOT] = "root",
|
||||||
[PARTITION_USR] = "usr",
|
[PARTITION_USR] = "usr",
|
||||||
|
|||||||
@ -31,24 +31,19 @@ typedef enum PartitionDesignator {
|
|||||||
|
|
||||||
bool partition_designator_is_versioned(PartitionDesignator d) _const_;
|
bool partition_designator_is_versioned(PartitionDesignator d) _const_;
|
||||||
|
|
||||||
PartitionDesignator partition_verity_hash_of(PartitionDesignator p) _const_;
|
PartitionDesignator partition_verity_of(PartitionDesignator p) _const_;
|
||||||
PartitionDesignator partition_verity_sig_of(PartitionDesignator p) _const_;
|
PartitionDesignator partition_verity_sig_of(PartitionDesignator p) _const_;
|
||||||
PartitionDesignator partition_verity_hash_to_data(PartitionDesignator d) _const_;
|
|
||||||
PartitionDesignator partition_verity_sig_to_data(PartitionDesignator d) _const_;
|
|
||||||
PartitionDesignator partition_verity_to_data(PartitionDesignator d) _const_;
|
PartitionDesignator partition_verity_to_data(PartitionDesignator d) _const_;
|
||||||
|
PartitionDesignator partition_verity_sig_to_data(PartitionDesignator d) _const_;
|
||||||
|
|
||||||
static inline bool partition_designator_is_verity_hash(PartitionDesignator d) {
|
static inline bool partition_designator_is_verity(PartitionDesignator d) {
|
||||||
return partition_verity_hash_to_data(d) >= 0;
|
return partition_verity_to_data(d) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool partition_designator_is_verity_sig(PartitionDesignator d) {
|
static inline bool partition_designator_is_verity_sig(PartitionDesignator d) {
|
||||||
return partition_verity_sig_to_data(d) >= 0;
|
return partition_verity_sig_to_data(d) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool partition_designator_is_verity(PartitionDesignator d) {
|
|
||||||
return partition_verity_to_data(d) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* partition_designator_to_string(PartitionDesignator d) _const_;
|
const char* partition_designator_to_string(PartitionDesignator d) _const_;
|
||||||
PartitionDesignator partition_designator_from_string(const char *name) _pure_;
|
PartitionDesignator partition_designator_from_string(const char *name) _pure_;
|
||||||
|
|
||||||
|
|||||||
@ -76,12 +76,12 @@ static PartitionPolicyFlags partition_policy_normalized_flags(const PartitionPol
|
|||||||
|
|
||||||
/* If this is a verity or verity signature designator, then mask off all protection bits, this after
|
/* If this is a verity or verity signature designator, then mask off all protection bits, this after
|
||||||
* all needs no protection, because it *is* the protection */
|
* all needs no protection, because it *is* the protection */
|
||||||
if (partition_verity_hash_to_data(policy->designator) >= 0 ||
|
if (partition_verity_to_data(policy->designator) >= 0 ||
|
||||||
partition_verity_sig_to_data(policy->designator) >= 0)
|
partition_verity_sig_to_data(policy->designator) >= 0)
|
||||||
flags &= ~(PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED);
|
flags &= ~(PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED);
|
||||||
|
|
||||||
/* if this designator has no verity concept, then mask off verity protection flags */
|
/* if this designator has no verity concept, then mask off verity protection flags */
|
||||||
if (partition_verity_hash_of(policy->designator) < 0)
|
if (partition_verity_of(policy->designator) < 0)
|
||||||
flags &= ~(PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED);
|
flags &= ~(PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED);
|
||||||
|
|
||||||
/* If the partition must be absent, then the gpt flags don't matter */
|
/* If the partition must be absent, then the gpt flags don't matter */
|
||||||
@ -110,7 +110,7 @@ PartitionPolicyFlags image_policy_get(const ImagePolicy *policy, PartitionDesign
|
|||||||
/* Hmm, so this didn't work, then let's see if we can derive some policy from the underlying data
|
/* Hmm, so this didn't work, then let's see if we can derive some policy from the underlying data
|
||||||
* partition in case of verity/signature partitions */
|
* partition in case of verity/signature partitions */
|
||||||
|
|
||||||
data_designator = partition_verity_hash_to_data(designator);
|
data_designator = partition_verity_to_data(designator);
|
||||||
if (data_designator >= 0) {
|
if (data_designator >= 0) {
|
||||||
PartitionPolicyFlags data_flags;
|
PartitionPolicyFlags data_flags;
|
||||||
|
|
||||||
|
|||||||
@ -154,7 +154,6 @@ shared_sources = files(
|
|||||||
'polkit-agent.c',
|
'polkit-agent.c',
|
||||||
'portable-util.c',
|
'portable-util.c',
|
||||||
'pretty-print.c',
|
'pretty-print.c',
|
||||||
'printk-util.c',
|
|
||||||
'prompt-util.c',
|
'prompt-util.c',
|
||||||
'ptyfwd.c',
|
'ptyfwd.c',
|
||||||
'qrcode-util.c',
|
'qrcode-util.c',
|
||||||
@ -202,7 +201,6 @@ shared_sources = files(
|
|||||||
'varlink-io.systemd.ManagedOOM.c',
|
'varlink-io.systemd.ManagedOOM.c',
|
||||||
'varlink-io.systemd.Manager.c',
|
'varlink-io.systemd.Manager.c',
|
||||||
'varlink-io.systemd.MountFileSystem.c',
|
'varlink-io.systemd.MountFileSystem.c',
|
||||||
'varlink-io.systemd.MuteConsole.c',
|
|
||||||
'varlink-io.systemd.NamespaceResource.c',
|
'varlink-io.systemd.NamespaceResource.c',
|
||||||
'varlink-io.systemd.Network.c',
|
'varlink-io.systemd.Network.c',
|
||||||
'varlink-io.systemd.PCRExtend.c',
|
'varlink-io.systemd.PCRExtend.c',
|
||||||
@ -330,7 +328,7 @@ libshared_deps = [threads,
|
|||||||
libpam_cflags,
|
libpam_cflags,
|
||||||
librt,
|
librt,
|
||||||
libseccomp_cflags,
|
libseccomp_cflags,
|
||||||
libselinux_cflags,
|
libselinux,
|
||||||
libxenctrl_cflags,
|
libxenctrl_cflags,
|
||||||
libxz_cflags,
|
libxz_cflags,
|
||||||
libzstd_cflags]
|
libzstd_cflags]
|
||||||
|
|||||||
@ -1,42 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
||||||
|
|
||||||
#include "alloc-util.h"
|
|
||||||
#include "extract-word.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "parse-util.h"
|
|
||||||
#include "printk-util.h"
|
|
||||||
#include "sysctl-util.h"
|
|
||||||
|
|
||||||
int sysctl_printk_read(void) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
_cleanup_free_ char *sysctl_printk_vals = NULL;
|
|
||||||
r = sysctl_read("kernel/printk", &sysctl_printk_vals);
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Cannot read sysctl kernel.printk: %m");
|
|
||||||
|
|
||||||
_cleanup_free_ char *sysctl_printk_curr = NULL;
|
|
||||||
const char *p = sysctl_printk_vals;
|
|
||||||
r = extract_first_word(&p, &sysctl_printk_curr, NULL, 0);
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Failed to split out kernel printk priority: %m");
|
|
||||||
if (r == 0)
|
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Short read while reading kernel.printk sysctl");
|
|
||||||
|
|
||||||
int current_lvl;
|
|
||||||
r = safe_atoi(sysctl_printk_curr, ¤t_lvl);
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Failed to parse kernel.printk sysctl: %s", sysctl_printk_vals);
|
|
||||||
|
|
||||||
return current_lvl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sysctl_printk_write(int l) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = sysctl_writef("kernel/printk", "%i", l);
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Failed to set kernel.printk to %i: %m", l);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
int sysctl_printk_read(void);
|
|
||||||
int sysctl_printk_write(int l);
|
|
||||||
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <sd-varlink.h>
|
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "glyph-util.h"
|
#include "glyph-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@ -332,60 +330,3 @@ void chrome_hide(void) {
|
|||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vl_on_reply(sd_varlink *link, sd_json_variant *parameters, const char *error_id, sd_varlink_reply_flags_t flags, void *userdata) {
|
|
||||||
assert(link);
|
|
||||||
|
|
||||||
/* We want to keep the link around (since its lifetime defines the lifetime of the console muting),
|
|
||||||
* hence let's detach it from the event loop now, and then exit the event loop. */
|
|
||||||
|
|
||||||
_cleanup_(sd_event_unrefp) sd_event *e = sd_event_ref(ASSERT_PTR(sd_varlink_get_event(link)));
|
|
||||||
sd_varlink_detach_event(link);
|
|
||||||
(void) sd_event_exit(e, (error_id || !FLAGS_SET(flags, SD_VARLINK_REPLY_CONTINUES)) ? -EBADR : 0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mute_console(sd_varlink **ret_link) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(ret_link);
|
|
||||||
|
|
||||||
/* Talks to the MuteConsole service, and asks for output to the console to be muted, as long as the
|
|
||||||
* connection is retained */
|
|
||||||
|
|
||||||
_cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *link = NULL;
|
|
||||||
r = sd_varlink_connect_address(&link, "/run/systemd/io.systemd.MuteConsole");
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Failed to connect to console muting service: %m");
|
|
||||||
|
|
||||||
_cleanup_(sd_event_unrefp) sd_event* event = NULL;
|
|
||||||
r = sd_event_new(&event);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = sd_varlink_attach_event(link, event, /* priority= */ 0);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = sd_varlink_bind_reply(link, vl_on_reply);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = sd_varlink_set_relative_timeout(link, UINT64_MAX);
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Failed to disable method call time-out: %m");
|
|
||||||
|
|
||||||
r = sd_varlink_observe(link, "io.systemd.MuteConsole.Mute", /* parameters= */ NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(r, "Failed to issue Mute() call to io.systemd.MuteConsole: %m");
|
|
||||||
|
|
||||||
/* Now run the event loop, it will exit on the first reply, which is when we know the console output
|
|
||||||
* is now muted. */
|
|
||||||
r = sd_event_loop(event);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
*ret_link = TAKE_PTR(link);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -29,5 +29,3 @@ int prompt_loop(const char *text,
|
|||||||
|
|
||||||
int chrome_show(const char *top, const char *bottom);
|
int chrome_show(const char *top, const char *bottom);
|
||||||
void chrome_hide(void);
|
void chrome_hide(void);
|
||||||
|
|
||||||
int mute_console(sd_varlink **ret_link);
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
|
|
||||||
#if HAVE_SELINUX
|
#if HAVE_SELINUX
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(context_t, sym_context_free, context_freep, NULL);
|
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(context_t, context_free, NULL);
|
||||||
|
|
||||||
typedef enum Initialized {
|
typedef enum Initialized {
|
||||||
UNINITIALIZED,
|
UNINITIALIZED,
|
||||||
@ -49,98 +49,12 @@ static int mac_selinux_label_post(int dir_fd, const char *path, bool created) {
|
|||||||
mac_selinux_create_file_clear();
|
mac_selinux_create_file_clear();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *libselinux_dl = NULL;
|
|
||||||
|
|
||||||
DLSYM_PROTOTYPE(avc_open) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(context_free) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(context_new) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(context_range_get) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(context_range_set) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(context_str) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(fgetfilecon_raw) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(fini_selinuxmnt) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(freecon) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(getcon_raw) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(getfilecon_raw) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(getpeercon_raw) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(getpidcon_raw) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(is_selinux_enabled) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(security_compute_create_raw) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(security_getenforce) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(selabel_close) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(selabel_lookup_raw) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(selabel_open) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(selinux_check_access) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(selinux_getenforcemode) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(selinux_init_load_policy) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(selinux_path) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(selinux_set_callback) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(selinux_status_close) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(selinux_status_getenforce) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(selinux_status_open) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(selinux_status_policyload) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(setcon_raw) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(setexeccon_raw) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(setfilecon_raw) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(setfscreatecon_raw) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(setsockcreatecon_raw) = NULL;
|
|
||||||
DLSYM_PROTOTYPE(string_to_security_class) = NULL;
|
|
||||||
|
|
||||||
int dlopen_libselinux(void) {
|
|
||||||
ELF_NOTE_DLOPEN("selinux",
|
|
||||||
"Support for SELinux",
|
|
||||||
ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED,
|
|
||||||
"libselinux.so.1");
|
|
||||||
|
|
||||||
return dlopen_many_sym_or_warn(
|
|
||||||
&libselinux_dl,
|
|
||||||
"libselinux.so.1",
|
|
||||||
LOG_DEBUG,
|
|
||||||
DLSYM_ARG(avc_open),
|
|
||||||
DLSYM_ARG(context_free),
|
|
||||||
DLSYM_ARG(context_new),
|
|
||||||
DLSYM_ARG(context_range_get),
|
|
||||||
DLSYM_ARG(context_range_set),
|
|
||||||
DLSYM_ARG(context_str),
|
|
||||||
DLSYM_ARG(fgetfilecon_raw),
|
|
||||||
DLSYM_ARG(fini_selinuxmnt),
|
|
||||||
DLSYM_ARG(freecon),
|
|
||||||
DLSYM_ARG(getcon_raw),
|
|
||||||
DLSYM_ARG(getfilecon_raw),
|
|
||||||
DLSYM_ARG(getpeercon_raw),
|
|
||||||
DLSYM_ARG(getpidcon_raw),
|
|
||||||
DLSYM_ARG(is_selinux_enabled),
|
|
||||||
DLSYM_ARG(security_compute_create_raw),
|
|
||||||
DLSYM_ARG(security_getenforce),
|
|
||||||
DLSYM_ARG(selabel_close),
|
|
||||||
DLSYM_ARG(selabel_lookup_raw),
|
|
||||||
DLSYM_ARG(selabel_open),
|
|
||||||
DLSYM_ARG(selinux_check_access),
|
|
||||||
DLSYM_ARG(selinux_getenforcemode),
|
|
||||||
DLSYM_ARG(selinux_init_load_policy),
|
|
||||||
DLSYM_ARG(selinux_path),
|
|
||||||
DLSYM_ARG(selinux_set_callback),
|
|
||||||
DLSYM_ARG(selinux_status_close),
|
|
||||||
DLSYM_ARG(selinux_status_getenforce),
|
|
||||||
DLSYM_ARG(selinux_status_open),
|
|
||||||
DLSYM_ARG(selinux_status_policyload),
|
|
||||||
DLSYM_ARG(setcon_raw),
|
|
||||||
DLSYM_ARG(setexeccon_raw),
|
|
||||||
DLSYM_ARG(setfilecon_raw),
|
|
||||||
DLSYM_ARG(setfscreatecon_raw),
|
|
||||||
DLSYM_ARG(setsockcreatecon_raw),
|
|
||||||
DLSYM_ARG(string_to_security_class));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool mac_selinux_use(void) {
|
bool mac_selinux_use(void) {
|
||||||
#if HAVE_SELINUX
|
#if HAVE_SELINUX
|
||||||
if (_unlikely_(cached_use < 0)) {
|
if (_unlikely_(cached_use < 0)) {
|
||||||
if (dlopen_libselinux() < 0)
|
cached_use = is_selinux_enabled() > 0;
|
||||||
return (cached_use = false);
|
|
||||||
|
|
||||||
cached_use = sym_is_selinux_enabled() > 0;
|
|
||||||
log_trace("SELinux enabled state cached to: %s", enabled_disabled(cached_use));
|
log_trace("SELinux enabled state cached to: %s", enabled_disabled(cached_use));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,13 +71,10 @@ bool mac_selinux_enforcing(void) {
|
|||||||
/* If the SELinux status page has been successfully opened, retrieve the enforcing
|
/* If the SELinux status page has been successfully opened, retrieve the enforcing
|
||||||
* status over it to avoid system calls in security_getenforce(). */
|
* status over it to avoid system calls in security_getenforce(). */
|
||||||
|
|
||||||
if (dlopen_libselinux() < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (have_status_page)
|
if (have_status_page)
|
||||||
r = sym_selinux_status_getenforce();
|
r = selinux_status_getenforce();
|
||||||
else
|
else
|
||||||
r = sym_security_getenforce();
|
r = security_getenforce();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return r != 0;
|
return r != 0;
|
||||||
@ -181,18 +92,13 @@ static int open_label_db(void) {
|
|||||||
/* Avoid maybe-uninitialized false positives */
|
/* Avoid maybe-uninitialized false positives */
|
||||||
usec_t before_timestamp = USEC_INFINITY, after_timestamp = USEC_INFINITY;
|
usec_t before_timestamp = USEC_INFINITY, after_timestamp = USEC_INFINITY;
|
||||||
struct mallinfo2 before_mallinfo = {};
|
struct mallinfo2 before_mallinfo = {};
|
||||||
int r;
|
|
||||||
|
|
||||||
r = dlopen_libselinux();
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (DEBUG_LOGGING) {
|
if (DEBUG_LOGGING) {
|
||||||
before_mallinfo = mallinfo2();
|
before_mallinfo = mallinfo2();
|
||||||
before_timestamp = now(CLOCK_MONOTONIC);
|
before_timestamp = now(CLOCK_MONOTONIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
hnd = sym_selabel_open(SELABEL_CTX_FILE, NULL, 0);
|
hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
|
||||||
if (!hnd)
|
if (!hnd)
|
||||||
return log_selinux_enforcing_errno(errno, "Failed to initialize SELinux labeling handle: %m");
|
return log_selinux_enforcing_errno(errno, "Failed to initialize SELinux labeling handle: %m");
|
||||||
|
|
||||||
@ -207,7 +113,7 @@ static int open_label_db(void) {
|
|||||||
|
|
||||||
/* release memory after measurement */
|
/* release memory after measurement */
|
||||||
if (label_hnd)
|
if (label_hnd)
|
||||||
sym_selabel_close(label_hnd);
|
selabel_close(label_hnd);
|
||||||
label_hnd = TAKE_PTR(hnd);
|
label_hnd = TAKE_PTR(hnd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -236,7 +142,7 @@ static int selinux_init(bool force) {
|
|||||||
|
|
||||||
mac_selinux_disable_logging();
|
mac_selinux_disable_logging();
|
||||||
|
|
||||||
r = sym_selinux_status_open(/* netlink fallback= */ 1);
|
r = selinux_status_open(/* netlink fallback= */ 1);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (!ERRNO_IS_PRIVILEGE(errno))
|
if (!ERRNO_IS_PRIVILEGE(errno))
|
||||||
return log_selinux_enforcing_errno(errno, "Failed to open SELinux status page: %m");
|
return log_selinux_enforcing_errno(errno, "Failed to open SELinux status page: %m");
|
||||||
@ -248,7 +154,7 @@ static int selinux_init(bool force) {
|
|||||||
|
|
||||||
r = open_label_db();
|
r = open_label_db();
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
sym_selinux_status_close();
|
selinux_status_close();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +164,7 @@ static int selinux_init(bool force) {
|
|||||||
|
|
||||||
/* Save the current policyload sequence number, so mac_selinux_maybe_reload() does not trigger on
|
/* Save the current policyload sequence number, so mac_selinux_maybe_reload() does not trigger on
|
||||||
* first call without any actual change. */
|
* first call without any actual change. */
|
||||||
last_policyload = sym_selinux_status_policyload();
|
last_policyload = selinux_status_policyload();
|
||||||
|
|
||||||
initialized = INITIALIZED;
|
initialized = INITIALIZED;
|
||||||
return 1;
|
return 1;
|
||||||
@ -297,9 +203,6 @@ void mac_selinux_maybe_reload(void) {
|
|||||||
if (!initialized)
|
if (!initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (dlopen_libselinux() < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Do not use selinux_status_updated(3), cause since libselinux 3.2 selinux_check_access(3),
|
/* Do not use selinux_status_updated(3), cause since libselinux 3.2 selinux_check_access(3),
|
||||||
* called in core and user instances, does also use it under the hood.
|
* called in core and user instances, does also use it under the hood.
|
||||||
* That can cause changes to be consumed by selinux_check_access(3) and not being visible here.
|
* That can cause changes to be consumed by selinux_check_access(3) and not being visible here.
|
||||||
@ -307,7 +210,7 @@ void mac_selinux_maybe_reload(void) {
|
|||||||
* invoked since libselinux 3.2 by selinux_status_updated(3).
|
* invoked since libselinux 3.2 by selinux_status_updated(3).
|
||||||
* Relevant libselinux commit: https://github.com/SELinuxProject/selinux/commit/05bdc03130d741e53e1fb45a958d0a2c184be503
|
* Relevant libselinux commit: https://github.com/SELinuxProject/selinux/commit/05bdc03130d741e53e1fb45a958d0a2c184be503
|
||||||
* Debian Bullseye is going to ship libselinux 3.1, so stay compatible for backports. */
|
* Debian Bullseye is going to ship libselinux 3.1, so stay compatible for backports. */
|
||||||
policyload = sym_selinux_status_policyload();
|
policyload = selinux_status_policyload();
|
||||||
if (policyload < 0) {
|
if (policyload < 0) {
|
||||||
log_debug_errno(errno, "Failed to get SELinux policyload from status page: %m");
|
log_debug_errno(errno, "Failed to get SELinux policyload from status page: %m");
|
||||||
return;
|
return;
|
||||||
@ -324,13 +227,11 @@ void mac_selinux_finish(void) {
|
|||||||
|
|
||||||
#if HAVE_SELINUX
|
#if HAVE_SELINUX
|
||||||
if (label_hnd) {
|
if (label_hnd) {
|
||||||
sym_selabel_close(label_hnd);
|
selabel_close(label_hnd);
|
||||||
label_hnd = NULL;
|
label_hnd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym_selinux_status_close)
|
selinux_status_close();
|
||||||
sym_selinux_status_close();
|
|
||||||
|
|
||||||
have_status_page = false;
|
have_status_page = false;
|
||||||
|
|
||||||
initialized = false;
|
initialized = false;
|
||||||
@ -347,10 +248,7 @@ static int selinux_log_glue(int type, const char *fmt, ...) {
|
|||||||
void mac_selinux_disable_logging(void) {
|
void mac_selinux_disable_logging(void) {
|
||||||
#if HAVE_SELINUX
|
#if HAVE_SELINUX
|
||||||
/* Turn off all of SELinux' own logging, we want to do that ourselves */
|
/* Turn off all of SELinux' own logging, we want to do that ourselves */
|
||||||
if (dlopen_libselinux() < 0)
|
selinux_set_callback(SELINUX_CB_LOG, (const union selinux_callback) { .func_log = selinux_log_glue });
|
||||||
return;
|
|
||||||
|
|
||||||
sym_selinux_set_callback(SELINUX_CB_LOG, (const union selinux_callback) { .func_log = selinux_log_glue });
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,7 +274,7 @@ static int selinux_fix_fd(
|
|||||||
if (!label_hnd)
|
if (!label_hnd)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (sym_selabel_lookup_raw(label_hnd, &fcon, label_path, st.st_mode) < 0) {
|
if (selabel_lookup_raw(label_hnd, &fcon, label_path, st.st_mode) < 0) {
|
||||||
/* If there's no label to set, then exit without warning */
|
/* If there's no label to set, then exit without warning */
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
return 0;
|
return 0;
|
||||||
@ -384,8 +282,11 @@ static int selinux_fix_fd(
|
|||||||
return log_selinux_enforcing_errno(errno, "Unable to lookup intended SELinux security context of %s: %m", label_path);
|
return log_selinux_enforcing_errno(errno, "Unable to lookup intended SELinux security context of %s: %m", label_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = RET_NERRNO(sym_setfilecon_raw(FORMAT_PROC_FD_PATH(fd), fcon));
|
if (setfilecon_raw(FORMAT_PROC_FD_PATH(fd), fcon) < 0) {
|
||||||
if (r < 0) {
|
_cleanup_freecon_ char *oldcon = NULL;
|
||||||
|
|
||||||
|
r = -errno;
|
||||||
|
|
||||||
/* If the FS doesn't support labels, then exit without warning */
|
/* If the FS doesn't support labels, then exit without warning */
|
||||||
if (ERRNO_IS_NOT_SUPPORTED(r))
|
if (ERRNO_IS_NOT_SUPPORTED(r))
|
||||||
return 0;
|
return 0;
|
||||||
@ -395,8 +296,7 @@ static int selinux_fix_fd(
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* If the old label is identical to the new one, suppress any kind of error */
|
/* If the old label is identical to the new one, suppress any kind of error */
|
||||||
_cleanup_freecon_ char *oldcon = NULL;
|
if (getfilecon_raw(FORMAT_PROC_FD_PATH(fd), &oldcon) >= 0 && streq_ptr(fcon, oldcon))
|
||||||
if (sym_getfilecon_raw(FORMAT_PROC_FD_PATH(fd), &oldcon) >= 0 && streq_ptr(fcon, oldcon))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return log_selinux_enforcing_errno(r, "Unable to fix SELinux security context of %s: %m", label_path);
|
return log_selinux_enforcing_errno(r, "Unable to fix SELinux security context of %s: %m", label_path);
|
||||||
@ -471,7 +371,7 @@ int mac_selinux_apply(const char *path, const char *label) {
|
|||||||
|
|
||||||
assert(label);
|
assert(label);
|
||||||
|
|
||||||
if (sym_setfilecon_raw(path, label) < 0)
|
if (setfilecon(path, label) < 0)
|
||||||
return log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, path);
|
return log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, path);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
@ -490,7 +390,7 @@ int mac_selinux_apply_fd(int fd, const char *path, const char *label) {
|
|||||||
|
|
||||||
assert(label);
|
assert(label);
|
||||||
|
|
||||||
if (sym_setfilecon_raw(FORMAT_PROC_FD_PATH(fd), label) < 0)
|
if (setfilecon(FORMAT_PROC_FD_PATH(fd), label) < 0)
|
||||||
return log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, strna(path));
|
return log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s on path %s: %m", label, strna(path));
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
@ -511,21 +411,21 @@ int mac_selinux_get_create_label_from_exe(const char *exe, char **ret_label) {
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (sym_getcon_raw(&mycon) < 0)
|
if (getcon_raw(&mycon) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (!mycon)
|
if (!mycon)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (sym_getfilecon_raw(exe, &fcon) < 0)
|
if (getfilecon_raw(exe, &fcon) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (!fcon)
|
if (!fcon)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
sclass = sym_string_to_security_class("process");
|
sclass = string_to_security_class("process");
|
||||||
if (sclass == 0)
|
if (sclass == 0)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
||||||
return RET_NERRNO(sym_security_compute_create_raw(mycon, fcon, sclass, ret_label));
|
return RET_NERRNO(security_compute_create_raw(mycon, fcon, sclass, ret_label));
|
||||||
#else
|
#else
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
#endif
|
#endif
|
||||||
@ -544,7 +444,7 @@ int mac_selinux_get_our_label(char **ret_label) {
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
_cleanup_freecon_ char *con = NULL;
|
_cleanup_freecon_ char *con = NULL;
|
||||||
if (sym_getcon_raw(&con) < 0)
|
if (getcon_raw(&con) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (!con)
|
if (!con)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
@ -570,7 +470,7 @@ int mac_selinux_get_peer_label(int socket_fd, char **ret_label) {
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
_cleanup_freecon_ char *con = NULL;
|
_cleanup_freecon_ char *con = NULL;
|
||||||
if (sym_getpeercon_raw(socket_fd, &con) < 0)
|
if (getpeercon_raw(socket_fd, &con) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (!con)
|
if (!con)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
@ -600,47 +500,47 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (sym_getcon_raw(&mycon) < 0)
|
if (getcon_raw(&mycon) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (!mycon)
|
if (!mycon)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (sym_getpeercon_raw(socket_fd, &peercon) < 0)
|
if (getpeercon_raw(socket_fd, &peercon) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (!peercon)
|
if (!peercon)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (!exec_label) { /* If there is no context set for next exec let's use context of target executable */
|
if (!exec_label) { /* If there is no context set for next exec let's use context of target executable */
|
||||||
if (sym_getfilecon_raw(exe, &fcon) < 0)
|
if (getfilecon_raw(exe, &fcon) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (!fcon)
|
if (!fcon)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
bcon = sym_context_new(mycon);
|
bcon = context_new(mycon);
|
||||||
if (!bcon)
|
if (!bcon)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
pcon = sym_context_new(peercon);
|
pcon = context_new(peercon);
|
||||||
if (!pcon)
|
if (!pcon)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
range = sym_context_range_get(pcon);
|
range = context_range_get(pcon);
|
||||||
if (!range)
|
if (!range)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (sym_context_range_set(bcon, range) != 0)
|
if (context_range_set(bcon, range) != 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
bcon_str = sym_context_str(bcon);
|
bcon_str = context_str(bcon);
|
||||||
if (!bcon_str)
|
if (!bcon_str)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
sclass = sym_string_to_security_class("process");
|
sclass = string_to_security_class("process");
|
||||||
if (sclass == 0)
|
if (sclass == 0)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
||||||
return RET_NERRNO(sym_security_compute_create_raw(bcon_str, fcon, sclass, ret_label));
|
return RET_NERRNO(security_compute_create_raw(bcon_str, fcon, sclass, ret_label));
|
||||||
#else
|
#else
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
#endif
|
#endif
|
||||||
@ -663,7 +563,7 @@ static int selinux_create_file_prepare_abspath(const char *abspath, mode_t mode)
|
|||||||
if (!label_hnd)
|
if (!label_hnd)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = sym_selabel_lookup_raw(label_hnd, &filecon, abspath, mode);
|
r = selabel_lookup_raw(label_hnd, &filecon, abspath, mode);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
/* No context specified by the policy? Proceed without setting it. */
|
/* No context specified by the policy? Proceed without setting it. */
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
@ -672,7 +572,7 @@ static int selinux_create_file_prepare_abspath(const char *abspath, mode_t mode)
|
|||||||
return log_selinux_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", abspath);
|
return log_selinux_enforcing_errno(errno, "Failed to determine SELinux security context for %s: %m", abspath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym_setfscreatecon_raw(filecon) < 0)
|
if (setfscreatecon_raw(filecon) < 0)
|
||||||
return log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", filecon, abspath);
|
return log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", filecon, abspath);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -725,7 +625,7 @@ int mac_selinux_create_file_prepare_label(const char *path, const char *label) {
|
|||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (sym_setfscreatecon_raw(label) < 0)
|
if (setfscreatecon_raw(label) < 0)
|
||||||
return log_selinux_enforcing_errno(errno, "Failed to set specified SELinux security context '%s' for '%s': %m", label, strna(path));
|
return log_selinux_enforcing_errno(errno, "Failed to set specified SELinux security context '%s' for '%s': %m", label, strna(path));
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
@ -739,7 +639,7 @@ void mac_selinux_create_file_clear(void) {
|
|||||||
if (selinux_init(/* force= */ false) <= 0)
|
if (selinux_init(/* force= */ false) <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
(void) sym_setfscreatecon_raw(NULL);
|
setfscreatecon_raw(NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,7 +654,7 @@ int mac_selinux_create_socket_prepare(const char *label) {
|
|||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (sym_setsockcreatecon_raw(label) < 0)
|
if (setsockcreatecon(label) < 0)
|
||||||
return log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s for sockets: %m", label);
|
return log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s for sockets: %m", label);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -769,7 +669,7 @@ void mac_selinux_create_socket_clear(void) {
|
|||||||
if (selinux_init(/* force= */ false) <= 0)
|
if (selinux_init(/* force= */ false) <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
(void) sym_setsockcreatecon_raw(NULL);
|
setsockcreatecon_raw(NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -819,7 +719,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
|||||||
goto skipped;
|
goto skipped;
|
||||||
|
|
||||||
if (path_is_absolute(path))
|
if (path_is_absolute(path))
|
||||||
r = sym_selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK);
|
r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK);
|
||||||
else {
|
else {
|
||||||
_cleanup_free_ char *newpath = NULL;
|
_cleanup_free_ char *newpath = NULL;
|
||||||
|
|
||||||
@ -827,7 +727,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sym_selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFSOCK);
|
r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFSOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@ -839,7 +739,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
} else {
|
} else {
|
||||||
if (sym_setfscreatecon_raw(fcon) < 0) {
|
if (setfscreatecon_raw(fcon) < 0) {
|
||||||
r = log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", fcon, path);
|
r = log_selinux_enforcing_errno(errno, "Failed to set SELinux security context %s for %s: %m", fcon, path);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -850,7 +750,7 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
|
|||||||
r = RET_NERRNO(bind(fd, addr, addrlen));
|
r = RET_NERRNO(bind(fd, addr, addrlen));
|
||||||
|
|
||||||
if (context_changed)
|
if (context_changed)
|
||||||
(void) sym_setfscreatecon_raw(NULL);
|
(void) setfscreatecon_raw(NULL);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|||||||
@ -6,58 +6,10 @@
|
|||||||
#include "forward.h"
|
#include "forward.h"
|
||||||
|
|
||||||
#if HAVE_SELINUX
|
#if HAVE_SELINUX
|
||||||
#include <selinux/avc.h>
|
|
||||||
#include <selinux/label.h>
|
|
||||||
#include <selinux/context.h>
|
|
||||||
#include <selinux/selinux.h> /* IWYU pragma: export */
|
#include <selinux/selinux.h> /* IWYU pragma: export */
|
||||||
|
|
||||||
#include "dlfcn-util.h"
|
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(char*, freecon, NULL);
|
||||||
|
|
||||||
int dlopen_libselinux(void);
|
|
||||||
|
|
||||||
extern DLSYM_PROTOTYPE(avc_open);
|
|
||||||
extern DLSYM_PROTOTYPE(context_free);
|
|
||||||
extern DLSYM_PROTOTYPE(context_new);
|
|
||||||
extern DLSYM_PROTOTYPE(context_range_get);
|
|
||||||
extern DLSYM_PROTOTYPE(context_range_set);
|
|
||||||
extern DLSYM_PROTOTYPE(context_str);
|
|
||||||
extern DLSYM_PROTOTYPE(fgetfilecon_raw);
|
|
||||||
extern DLSYM_PROTOTYPE(fini_selinuxmnt);
|
|
||||||
extern DLSYM_PROTOTYPE(freecon);
|
|
||||||
extern DLSYM_PROTOTYPE(getcon_raw);
|
|
||||||
extern DLSYM_PROTOTYPE(getfilecon_raw);
|
|
||||||
extern DLSYM_PROTOTYPE(getpeercon_raw);
|
|
||||||
extern DLSYM_PROTOTYPE(getpidcon_raw);
|
|
||||||
extern DLSYM_PROTOTYPE(is_selinux_enabled);
|
|
||||||
extern DLSYM_PROTOTYPE(security_compute_create_raw);
|
|
||||||
extern DLSYM_PROTOTYPE(security_getenforce);
|
|
||||||
extern DLSYM_PROTOTYPE(selabel_close);
|
|
||||||
extern DLSYM_PROTOTYPE(selabel_lookup_raw);
|
|
||||||
extern DLSYM_PROTOTYPE(selabel_open);
|
|
||||||
extern DLSYM_PROTOTYPE(selinux_check_access);
|
|
||||||
extern DLSYM_PROTOTYPE(selinux_getenforcemode);
|
|
||||||
extern DLSYM_PROTOTYPE(selinux_init_load_policy);
|
|
||||||
extern DLSYM_PROTOTYPE(selinux_path);
|
|
||||||
extern DLSYM_PROTOTYPE(selinux_set_callback);
|
|
||||||
extern DLSYM_PROTOTYPE(selinux_status_close);
|
|
||||||
extern DLSYM_PROTOTYPE(selinux_status_getenforce);
|
|
||||||
extern DLSYM_PROTOTYPE(selinux_status_open);
|
|
||||||
extern DLSYM_PROTOTYPE(selinux_status_policyload);
|
|
||||||
extern DLSYM_PROTOTYPE(setcon_raw);
|
|
||||||
extern DLSYM_PROTOTYPE(setexeccon_raw);
|
|
||||||
extern DLSYM_PROTOTYPE(setfilecon_raw);
|
|
||||||
extern DLSYM_PROTOTYPE(setfscreatecon_raw);
|
|
||||||
extern DLSYM_PROTOTYPE(setsockcreatecon_raw);
|
|
||||||
extern DLSYM_PROTOTYPE(string_to_security_class);
|
|
||||||
|
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(char*, sym_freecon, freeconp, NULL);
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static inline int dlopen_libselinux(void) {
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void freeconp(char **p) {
|
static inline void freeconp(char **p) {
|
||||||
assert(*p == NULL);
|
assert(*p == NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
||||||
|
|
||||||
#include "sd-varlink-idl.h"
|
|
||||||
|
|
||||||
#include "varlink-io.systemd.MuteConsole.h"
|
|
||||||
|
|
||||||
static SD_VARLINK_DEFINE_METHOD(
|
|
||||||
Mute,
|
|
||||||
SD_VARLINK_FIELD_COMMENT("Whether to mute the kernel's output to the console (defaults to true)."),
|
|
||||||
SD_VARLINK_DEFINE_INPUT(kernel, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
|
||||||
SD_VARLINK_FIELD_COMMENT("Whether to mute PID1's output to the console (defaults to true)."),
|
|
||||||
SD_VARLINK_DEFINE_INPUT(pid1, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE));
|
|
||||||
|
|
||||||
SD_VARLINK_DEFINE_INTERFACE(
|
|
||||||
io_systemd_MuteConsole,
|
|
||||||
"io.systemd.MuteConsole",
|
|
||||||
SD_VARLINK_INTERFACE_COMMENT("API for temporarily muting noisy output to the main kernel console"),
|
|
||||||
SD_VARLINK_SYMBOL_COMMENT("Mute kernel and PID 1 output to the main kernel console"),
|
|
||||||
&vl_method_Mute);
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "sd-varlink-idl.h"
|
|
||||||
|
|
||||||
extern const sd_varlink_interface vl_interface_io_systemd_MuteConsole;
|
|
||||||
@ -36,7 +36,6 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "pidref.h"
|
#include "pidref.h"
|
||||||
#include "printk-util.h"
|
|
||||||
#include "process-util.h"
|
#include "process-util.h"
|
||||||
#include "reboot-util.h"
|
#include "reboot-util.h"
|
||||||
#include "rlimit-util.h"
|
#include "rlimit-util.h"
|
||||||
@ -273,14 +272,42 @@ int sync_with_progress(int fd) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int read_current_sysctl_printk_log_level(void) {
|
||||||
|
_cleanup_free_ char *sysctl_printk_vals = NULL, *sysctl_printk_curr = NULL;
|
||||||
|
int current_lvl;
|
||||||
|
const char *p;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = sysctl_read("kernel/printk", &sysctl_printk_vals);
|
||||||
|
if (r < 0)
|
||||||
|
return log_debug_errno(r, "Cannot read sysctl kernel.printk: %m");
|
||||||
|
|
||||||
|
p = sysctl_printk_vals;
|
||||||
|
r = extract_first_word(&p, &sysctl_printk_curr, NULL, 0);
|
||||||
|
if (r < 0)
|
||||||
|
return log_debug_errno(r, "Failed to split out kernel printk priority: %m");
|
||||||
|
if (r == 0)
|
||||||
|
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Short read while reading kernel.printk sysctl");
|
||||||
|
|
||||||
|
r = safe_atoi(sysctl_printk_curr, ¤t_lvl);
|
||||||
|
if (r < 0)
|
||||||
|
return log_debug_errno(r, "Failed to parse kernel.printk sysctl: %s", sysctl_printk_vals);
|
||||||
|
|
||||||
|
return current_lvl;
|
||||||
|
}
|
||||||
|
|
||||||
static void bump_sysctl_printk_log_level(int min_level) {
|
static void bump_sysctl_printk_log_level(int min_level) {
|
||||||
|
int current_lvl, r;
|
||||||
|
|
||||||
/* Set the logging level to be able to see messages with log level smaller or equal to min_level */
|
/* Set the logging level to be able to see messages with log level smaller or equal to min_level */
|
||||||
|
|
||||||
int current_lvl = sysctl_printk_read();
|
current_lvl = read_current_sysctl_printk_log_level();
|
||||||
if (current_lvl < 0 || current_lvl >= min_level + 1)
|
if (current_lvl < 0 || current_lvl >= min_level + 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
(void) sysctl_printk_write(min_level + 1);
|
r = sysctl_writef("kernel/printk", "%i", min_level + 1);
|
||||||
|
if (r < 0)
|
||||||
|
log_debug_errno(r, "Failed to bump kernel.printk to %i: %m", min_level + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_watchdog(void) {
|
static void init_watchdog(void) {
|
||||||
|
|||||||
@ -10,10 +10,10 @@
|
|||||||
#include "iovec-util.h"
|
#include "iovec-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "main-func.h"
|
#include "main-func.h"
|
||||||
#include "path-lookup.h"
|
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
|
#include "varlink-util.h"
|
||||||
|
|
||||||
static int process_vsock_cid(unsigned cid, const char *port) {
|
static int process_vsock_cid(unsigned cid, const char *port) {
|
||||||
int r;
|
int r;
|
||||||
@ -135,57 +135,23 @@ static int process_vsock_mux(const char *path, const char *port) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fetch_machine(const char *machine, RuntimeScope scope, sd_json_variant **ret) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(machine);
|
|
||||||
assert(ret);
|
|
||||||
|
|
||||||
_cleanup_free_ char *addr = NULL;
|
|
||||||
r = runtime_directory_generic(scope, "machine/io.systemd.Machine", &addr);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
|
|
||||||
r = sd_varlink_connect_address(&vl, addr);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to connect to machined on %s: %m", addr);
|
|
||||||
|
|
||||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *result = NULL;
|
|
||||||
const char *error_id;
|
|
||||||
r = sd_varlink_callbo(
|
|
||||||
vl,
|
|
||||||
"io.systemd.Machine.List",
|
|
||||||
&result,
|
|
||||||
&error_id,
|
|
||||||
SD_JSON_BUILD_PAIR("name", SD_JSON_BUILD_STRING(machine)));
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to issue io.systemd.Machine.List() varlink call: %m");
|
|
||||||
if (error_id) {
|
|
||||||
if (streq(error_id, "io.systemd.Machine.NoSuchMachine"))
|
|
||||||
return -ESRCH;
|
|
||||||
|
|
||||||
r = sd_varlink_error_to_errno(error_id, result); /* If this is a system errno style error, output it with %m */
|
|
||||||
if (r != -EBADR)
|
|
||||||
return log_error_errno(r, "Failed to issue io.systemd.Machine.List() varlink call: %m");
|
|
||||||
|
|
||||||
return log_error_errno(r, "Failed to issue io.systemd.Machine.List() varlink call: %s", error_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
*ret = TAKE_PTR(result);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int process_machine(const char *machine, const char *port) {
|
static int process_machine(const char *machine, const char *port) {
|
||||||
|
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(machine);
|
assert(machine);
|
||||||
assert(port);
|
assert(port);
|
||||||
|
|
||||||
|
r = sd_varlink_connect_address(&vl, "/run/systemd/machine/io.systemd.Machine");
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to connect to machined on /run/systemd/machine/io.systemd.Machine: %m");
|
||||||
|
|
||||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *result = NULL;
|
_cleanup_(sd_json_variant_unrefp) sd_json_variant *result = NULL;
|
||||||
r = fetch_machine(machine, RUNTIME_SCOPE_USER, &result);
|
r = varlink_callbo_and_log(
|
||||||
if (r == -ESRCH)
|
vl,
|
||||||
r = fetch_machine(machine, RUNTIME_SCOPE_SYSTEM, &result);
|
"io.systemd.Machine.List",
|
||||||
|
&result,
|
||||||
|
SD_JSON_BUILD_PAIR("name", SD_JSON_BUILD_STRING(machine)));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -201,7 +167,7 @@ static int process_machine(const char *machine, const char *port) {
|
|||||||
return log_error_errno(r, "Failed to parse Varlink reply: %m");
|
return log_error_errno(r, "Failed to parse Varlink reply: %m");
|
||||||
|
|
||||||
if (cid == VMADDR_CID_ANY)
|
if (cid == VMADDR_CID_ANY)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Machine %s has no AF_VSOCK CID assigned.", machine);
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Machine has no AF_VSOCK CID assigned.");
|
||||||
|
|
||||||
return process_vsock_cid(cid, port);
|
return process_vsock_cid(cid, port);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,6 +58,7 @@ executables += [
|
|||||||
'dependencies' : [
|
'dependencies' : [
|
||||||
libcap,
|
libcap,
|
||||||
liblz4_cflags,
|
liblz4_cflags,
|
||||||
|
libselinux,
|
||||||
libxz_cflags,
|
libxz_cflags,
|
||||||
libzstd_cflags,
|
libzstd_cflags,
|
||||||
threads,
|
threads,
|
||||||
|
|||||||
@ -218,7 +218,7 @@ common_test_dependencies = [
|
|||||||
libmount_cflags,
|
libmount_cflags,
|
||||||
librt,
|
librt,
|
||||||
libseccomp_cflags,
|
libseccomp_cflags,
|
||||||
libselinux_cflags,
|
libselinux,
|
||||||
threads,
|
threads,
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -432,7 +432,7 @@ executables += [
|
|||||||
},
|
},
|
||||||
test_template + {
|
test_template + {
|
||||||
'sources' : files('test-selinux.c'),
|
'sources' : files('test-selinux.c'),
|
||||||
'dependencies' : libselinux_cflags,
|
'dependencies' : libselinux,
|
||||||
},
|
},
|
||||||
test_template + {
|
test_template + {
|
||||||
'sources' : files('test-set-disable-mempool.c'),
|
'sources' : files('test-set-disable-mempool.c'),
|
||||||
|
|||||||
@ -22,7 +22,6 @@
|
|||||||
#include "pkcs11-util.h"
|
#include "pkcs11-util.h"
|
||||||
#include "qrcode-util.h"
|
#include "qrcode-util.h"
|
||||||
#include "seccomp-util.h"
|
#include "seccomp-util.h"
|
||||||
#include "selinux-util.h"
|
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
#include "tpm2-util.h"
|
#include "tpm2-util.h"
|
||||||
|
|
||||||
@ -61,7 +60,6 @@ static int run(int argc, char **argv) {
|
|||||||
ASSERT_DLOPEN(dlopen_libblkid, HAVE_BLKID);
|
ASSERT_DLOPEN(dlopen_libblkid, HAVE_BLKID);
|
||||||
ASSERT_DLOPEN(dlopen_libseccomp, HAVE_SECCOMP);
|
ASSERT_DLOPEN(dlopen_libseccomp, HAVE_SECCOMP);
|
||||||
ASSERT_DLOPEN(dlopen_libmount, true);
|
ASSERT_DLOPEN(dlopen_libmount, true);
|
||||||
ASSERT_DLOPEN(dlopen_libselinux, HAVE_SELINUX);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,20 +48,17 @@ TEST(verity_mappings) {
|
|||||||
for (PartitionDesignator p = 0; p < _PARTITION_DESIGNATOR_MAX; p++) {
|
for (PartitionDesignator p = 0; p < _PARTITION_DESIGNATOR_MAX; p++) {
|
||||||
PartitionDesignator q;
|
PartitionDesignator q;
|
||||||
|
|
||||||
q = partition_verity_hash_of(p);
|
q = partition_verity_of(p);
|
||||||
assert_se(q < 0 || partition_verity_hash_to_data(q) == p);
|
assert_se(q < 0 || partition_verity_to_data(q) == p);
|
||||||
|
|
||||||
q = partition_verity_sig_of(p);
|
q = partition_verity_sig_of(p);
|
||||||
assert_se(q < 0 || partition_verity_sig_to_data(q) == p);
|
assert_se(q < 0 || partition_verity_sig_to_data(q) == p);
|
||||||
|
|
||||||
q = partition_verity_hash_to_data(p);
|
q = partition_verity_to_data(p);
|
||||||
assert_se(q < 0 || partition_verity_hash_of(q) == p);
|
assert_se(q < 0 || partition_verity_of(q) == p);
|
||||||
|
|
||||||
q = partition_verity_sig_to_data(p);
|
q = partition_verity_sig_to_data(p);
|
||||||
assert_se(q < 0 || partition_verity_sig_of(q) == p);
|
assert_se(q < 0 || partition_verity_sig_of(q) == p);
|
||||||
|
|
||||||
q = partition_verity_to_data(p);
|
|
||||||
assert_se(q < 0 || partition_verity_hash_of(q) == p || partition_verity_sig_of(q) == p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,6 @@
|
|||||||
#include "varlink-io.systemd.Manager.h"
|
#include "varlink-io.systemd.Manager.h"
|
||||||
#include "varlink-io.systemd.ManagedOOM.h"
|
#include "varlink-io.systemd.ManagedOOM.h"
|
||||||
#include "varlink-io.systemd.MountFileSystem.h"
|
#include "varlink-io.systemd.MountFileSystem.h"
|
||||||
#include "varlink-io.systemd.MuteConsole.h"
|
|
||||||
#include "varlink-io.systemd.NamespaceResource.h"
|
#include "varlink-io.systemd.NamespaceResource.h"
|
||||||
#include "varlink-io.systemd.Network.h"
|
#include "varlink-io.systemd.Network.h"
|
||||||
#include "varlink-io.systemd.PCRExtend.h"
|
#include "varlink-io.systemd.PCRExtend.h"
|
||||||
@ -167,8 +166,6 @@ TEST(parse_format) {
|
|||||||
print_separator();
|
print_separator();
|
||||||
test_parse_format_one(&vl_interface_io_systemd_UserDatabase);
|
test_parse_format_one(&vl_interface_io_systemd_UserDatabase);
|
||||||
print_separator();
|
print_separator();
|
||||||
test_parse_format_one(&vl_interface_io_systemd_MuteConsole);
|
|
||||||
print_separator();
|
|
||||||
test_parse_format_one(&vl_interface_io_systemd_NamespaceResource);
|
test_parse_format_one(&vl_interface_io_systemd_NamespaceResource);
|
||||||
print_separator();
|
print_separator();
|
||||||
test_parse_format_one(&vl_interface_io_systemd_Journal);
|
test_parse_format_one(&vl_interface_io_systemd_Journal);
|
||||||
|
|||||||
@ -232,7 +232,7 @@ executables += [
|
|||||||
udev_test_template + {
|
udev_test_template + {
|
||||||
'sources' : files('test-udev-rule-runner.c'),
|
'sources' : files('test-udev-rule-runner.c'),
|
||||||
'dependencies' : udev_dependencies + [
|
'dependencies' : udev_dependencies + [
|
||||||
libselinux_cflags,
|
libselinux,
|
||||||
],
|
],
|
||||||
'type' : 'manual',
|
'type' : 'manual',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -103,8 +103,7 @@ static int run(int argc, char *argv[]) {
|
|||||||
|
|
||||||
/* Let's make sure the test runs with selinux assumed disabled. */
|
/* Let's make sure the test runs with selinux assumed disabled. */
|
||||||
#if HAVE_SELINUX
|
#if HAVE_SELINUX
|
||||||
if (dlopen_libselinux() >= 0)
|
fini_selinuxmnt();
|
||||||
sym_fini_selinuxmnt();
|
|
||||||
#endif
|
#endif
|
||||||
mac_selinux_retest();
|
mac_selinux_retest();
|
||||||
|
|
||||||
|
|||||||
@ -265,7 +265,7 @@ static int verb_probe(UdevEvent *event, sd_device *dev) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Indicate whether this partition has verity protection */
|
/* Indicate whether this partition has verity protection */
|
||||||
PartitionDesignator dv = partition_verity_hash_of(d);
|
PartitionDesignator dv = partition_verity_of(d);
|
||||||
if (dv >= 0 && image->partitions[dv].found) {
|
if (dv >= 0 && image->partitions[dv].found) {
|
||||||
/* Add one property that indicates as a boolean whether Verity is available at all for this */
|
/* Add one property that indicates as a boolean whether Verity is available at all for this */
|
||||||
_cleanup_free_ char *f = NULL;
|
_cleanup_free_ char *f = NULL;
|
||||||
|
|||||||
@ -587,13 +587,8 @@ static int reply_callback(
|
|||||||
else
|
else
|
||||||
r = *ret = log_error_errno(SYNTHETIC_ERRNO(EBADE), "Method call failed: %s", error);
|
r = *ret = log_error_errno(SYNTHETIC_ERRNO(EBADE), "Method call failed: %s", error);
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
/* Let the caller know we have received at least one reply now. This is useful for
|
|
||||||
* subscription style interfaces where the first reply indicates the subscription being
|
|
||||||
* successfully enabled. */
|
|
||||||
(void) sd_notify(/* unset_environment= */ false, "READY=1");
|
|
||||||
r = 0;
|
r = 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (!arg_quiet)
|
if (!arg_quiet)
|
||||||
sd_json_variant_dump(parameters, arg_json_format_flags, stdout, NULL);
|
sd_json_variant_dump(parameters, arg_json_format_flags, stdout, NULL);
|
||||||
|
|||||||
@ -1,40 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
set -eux
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
if ! command -v systemd-mute-console >/dev/null; then
|
|
||||||
echo "systemd-mute-console is not installed, skipping the test"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
PID="$(systemd-notify --fork -- systemd-mute-console)"
|
|
||||||
sleep .5
|
|
||||||
kill "$PID"
|
|
||||||
unset PID
|
|
||||||
|
|
||||||
(! systemd-mute-console --kernel=no --pid1=no)
|
|
||||||
|
|
||||||
PID="$(systemd-notify --fork -- systemd-mute-console --kernel=yes --pid1=yes)"
|
|
||||||
sleep .5
|
|
||||||
kill "$PID"
|
|
||||||
unset PID
|
|
||||||
|
|
||||||
varlinkctl introspect "$(which systemd-mute-console)"
|
|
||||||
|
|
||||||
PID="$(systemd-notify --fork -- varlinkctl call -E "$(which systemd-mute-console)" io.systemd.MuteConsole.Mute '{}')"
|
|
||||||
sleep .5
|
|
||||||
kill "$PID"
|
|
||||||
unset PID
|
|
||||||
|
|
||||||
PID="$(systemd-notify --fork -- varlinkctl call -E "$(which systemd-mute-console)" io.systemd.MuteConsole.Mute '{"pid1":true, "kernel":true}')"
|
|
||||||
sleep .5
|
|
||||||
kill "$PID"
|
|
||||||
unset PID
|
|
||||||
|
|
||||||
varlinkctl introspect /run/systemd/io.systemd.MuteConsole
|
|
||||||
|
|
||||||
PID="$(systemd-notify --fork -- varlinkctl call -E /run/systemd/io.systemd.MuteConsole io.systemd.MuteConsole.Mute '{}')"
|
|
||||||
sleep .5
|
|
||||||
kill "$PID"
|
|
||||||
unset PID
|
|
||||||
@ -143,12 +143,6 @@ units = [
|
|||||||
},
|
},
|
||||||
{ 'file' : 'modprobe@.service' },
|
{ 'file' : 'modprobe@.service' },
|
||||||
{ 'file' : 'multi-user.target' },
|
{ 'file' : 'multi-user.target' },
|
||||||
{
|
|
||||||
'file' : 'systemd-mute-console.socket',
|
|
||||||
'symlinks' : ['sockets.target.wants/']
|
|
||||||
},
|
|
||||||
{ 'file' : 'systemd-mute-console@.service' },
|
|
||||||
{ 'file' : 'system-systemd\\x2dmute\\x2dconsole.slice' },
|
|
||||||
{ 'file' : 'network-online.target' },
|
{ 'file' : 'network-online.target' },
|
||||||
{ 'file' : 'network-pre.target' },
|
{ 'file' : 'network-pre.target' },
|
||||||
{ 'file' : 'network.target' },
|
{ 'file' : 'network.target' },
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
#
|
|
||||||
# This file is part of systemd.
|
|
||||||
#
|
|
||||||
# systemd is free software; you can redistribute it and/or modify it
|
|
||||||
# under the terms of the GNU Lesser General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
|
|
||||||
[Unit]
|
|
||||||
Description=Console Output Muting Service Slice
|
|
||||||
Documentation=man:systemd-mute-console(8)
|
|
||||||
DefaultDependencies=no
|
|
||||||
Conflicts=shutdown.target
|
|
||||||
Before=shutdown.target
|
|
||||||
|
|
||||||
[Slice]
|
|
||||||
# Serialize requests to mute the console.
|
|
||||||
ConcurrencySoftMax=1
|
|
||||||
@ -22,7 +22,6 @@ After=systemd-remount-fs.service
|
|||||||
After=systemd-sysusers.service systemd-tmpfiles-setup.service
|
After=systemd-sysusers.service systemd-tmpfiles-setup.service
|
||||||
# Let vconsole-setup do its setup before starting user interaction:
|
# Let vconsole-setup do its setup before starting user interaction:
|
||||||
After=systemd-vconsole-setup.service
|
After=systemd-vconsole-setup.service
|
||||||
After=systemd-mute-console.socket
|
|
||||||
|
|
||||||
Wants=first-boot-complete.target
|
Wants=first-boot-complete.target
|
||||||
Before=first-boot-complete.target sysinit.target
|
Before=first-boot-complete.target sysinit.target
|
||||||
@ -32,7 +31,7 @@ Before=shutdown.target
|
|||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
RemainAfterExit=yes
|
RemainAfterExit=yes
|
||||||
ExecStart=systemd-firstboot --prompt-locale --prompt-keymap --prompt-timezone --prompt-root-password --mute-console=yes
|
ExecStart=systemd-firstboot --prompt-locale --prompt-keymap --prompt-timezone --prompt-root-password
|
||||||
StandardOutput=tty
|
StandardOutput=tty
|
||||||
StandardInput=tty
|
StandardInput=tty
|
||||||
StandardError=tty
|
StandardError=tty
|
||||||
|
|||||||
@ -1,22 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
#
|
|
||||||
# This file is part of systemd.
|
|
||||||
#
|
|
||||||
# systemd is free software; you can redistribute it and/or modify it
|
|
||||||
# under the terms of the GNU Lesser General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
|
|
||||||
[Unit]
|
|
||||||
Description=Console Output Muting Service Socket
|
|
||||||
Documentation=man:systemd-mute-console(8)
|
|
||||||
DefaultDependencies=no
|
|
||||||
Before=sockets.target
|
|
||||||
Conflicts=shutdown.target
|
|
||||||
Before=shutdown.target
|
|
||||||
|
|
||||||
[Socket]
|
|
||||||
ListenStream=/run/systemd/io.systemd.MuteConsole
|
|
||||||
FileDescriptorName=varlink
|
|
||||||
SocketMode=0600
|
|
||||||
Accept=yes
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
#
|
|
||||||
# This file is part of systemd.
|
|
||||||
#
|
|
||||||
# systemd is free software; you can redistribute it and/or modify it
|
|
||||||
# under the terms of the GNU Lesser General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
|
|
||||||
[Unit]
|
|
||||||
Description=Console Output Muting Service
|
|
||||||
Documentation=man:systemd-mute-console(8)
|
|
||||||
DefaultDependencies=no
|
|
||||||
Conflicts=shutdown.target
|
|
||||||
Before=shutdown.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart=systemd-mute-console
|
|
||||||
Loading…
x
Reference in New Issue
Block a user