Merge branch 'main' into inode-ref
This commit is contained in:
@@ -285,6 +285,10 @@ jobs:
|
||||
- Instructions to return ONLY a raw JSON array of findings. No markdown,
|
||||
no explanation, no code fences — just the JSON array. If there are no
|
||||
findings, return `[]`.
|
||||
- Instructions that `severity` is a separate structured field — do NOT
|
||||
repeat it inside `body` (no "must-fix:", "**suggestion**:", etc.
|
||||
prefix). The posting step adds the severity label itself, so
|
||||
including it in `body` produces duplicates.
|
||||
|
||||
## Phase 2: Collect, deduplicate, and summarize
|
||||
|
||||
@@ -488,7 +492,7 @@ jobs:
|
||||
...(c.side != null && { side: c.side }),
|
||||
...(c.start_line != null && { start_line: c.start_line }),
|
||||
...(c.start_side != null && { start_side: c.start_side }),
|
||||
body: c.body,
|
||||
body: `Claude: **${c.severity}**: ${c.body}`,
|
||||
});
|
||||
posted++;
|
||||
} catch (e) {
|
||||
|
||||
@@ -264,9 +264,9 @@ REQUIREMENTS:
|
||||
During runtime, you need the following additional
|
||||
dependencies:
|
||||
|
||||
util-linux >= v2.41 required (including but not limited to: mount,
|
||||
umount, swapon, swapoff, sulogin,
|
||||
agetty, fsck)
|
||||
util-linux >= v2.27.1 required (including but not limited to: mount,
|
||||
umount, swapon, swapoff, sulogin,
|
||||
agetty, fsck)
|
||||
dbus >= 1.4.0 (strictly speaking optional, but recommended)
|
||||
NOTE: If using dbus < 1.9.18, you should override the default
|
||||
policy directory (--with-dbuspolicydir=/etc/dbus-1/system.d).
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/* Disable this transformation for iovec-util.h and the unit test */
|
||||
@ depends on !(file in "src/basic/iovec-util.h")
|
||||
&& !(file in "src/test/test-iovec-util.c") @
|
||||
expression a, b;
|
||||
@@
|
||||
(
|
||||
- iovec_memcmp(a, b) == 0
|
||||
+ iovec_equal(a, b)
|
||||
|
|
||||
- iovec_memcmp(a, b) != 0
|
||||
+ !iovec_equal(a, b)
|
||||
|
|
||||
- ASSERT_EQ(iovec_memcmp(a, b), 0)
|
||||
+ ASSERT_TRUE(iovec_equal(a, b))
|
||||
|
|
||||
- ASSERT_NE(iovec_memcmp(a, b), 0)
|
||||
+ ASSERT_FALSE(iovec_equal(a, b))
|
||||
)
|
||||
@@ -679,6 +679,11 @@ SYSTEMD_HOME_DEBUG_SUFFIX=foo \
|
||||
string format. Overrides the default maximum allowed size for a file-descriptor
|
||||
based input record to be stored in the journal.
|
||||
|
||||
* `$SYSTEMD_JOURNAL_REMOTE_CONFIG_FILE` – path to a configuration file for
|
||||
`systemd-journal-remote`. When set, the specified file is used instead of the
|
||||
default configuration file and drop-in directories. If set to the empty string
|
||||
or `/dev/null`, configuration file parsing is skipped entirely.
|
||||
|
||||
* `$SYSTEMD_CATALOG` – path to the compiled catalog database file to use for
|
||||
`journalctl -x`, `journalctl --update-catalog`, `journalctl --list-catalog`
|
||||
and related calls.
|
||||
|
||||
@@ -103,3 +103,29 @@ dmi:*:svnScaleway:*
|
||||
IMDS_ADDRESS_IPV4=169.254.42.42
|
||||
IMDS_ADDRESS_IPV6=fd00:42::42
|
||||
IMDS_KEY_USERDATA=/user_data
|
||||
|
||||
# https://www.tencentcloud.com/document/product/213/4934?lang=en
|
||||
dmi:*:svnTencentCloud:*
|
||||
IMDS_VENDOR=tencent-cloud
|
||||
IMDS_DATA_URL=http://metadata.tencentyun.com
|
||||
IMDS_KEY_HOSTNAME=/meta-data/hostname
|
||||
IMDS_KEY_REGION=/meta-data/placement/region
|
||||
IMDS_KEY_ZONE=/meta-data/placement/zone
|
||||
IMDS_KEY_IPV4_PUBLIC=/meta-data/public-ipv4
|
||||
IMDS_KEY_SSH_KEY=/meta-data/public-keys/0/openssh-key
|
||||
IMDS_KEY_USERDATA=/user-data
|
||||
|
||||
# https://help.aliyun.com/zh/ecs/user-guide/view-instance-metadata
|
||||
dmi:*:svnAlibabaCloud:*
|
||||
IMDS_VENDOR=alibaba-ecs
|
||||
IMDS_TOKEN_URL=http://100.100.100.200/latest/api/token
|
||||
IMDS_REFRESH_HEADER_NAME=X-aliyun-ecs-metadata-token-ttl-seconds
|
||||
IMDS_DATA_URL=http://100.100.100.200/latest
|
||||
IMDS_TOKEN_HEADER_NAME=X-aliyun-ecs-metadata-token
|
||||
IMDS_ADDRESS_IPV4=100.100.100.200
|
||||
IMDS_KEY_HOSTNAME=/meta-data/hostname
|
||||
IMDS_KEY_REGION=/meta-data/region-id
|
||||
IMDS_KEY_ZONE=/meta-data/zone-id
|
||||
IMDS_KEY_IPV4_PUBLIC=/meta-data/eipv4
|
||||
IMDS_KEY_SSH_KEY=/meta-data/public-keys/0/openssh-key
|
||||
IMDS_KEY_USERDATA=/user-data
|
||||
|
||||
@@ -515,10 +515,6 @@ sensor:modalias:acpi:KIOX000A:*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd03/20/20
|
||||
sensor:modalias:acpi:KIOX000A:*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/25/2017:*:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
|
||||
ACCEL_LOCATION=base
|
||||
|
||||
sensor:modalias:acpi:MXC6655:*:dmi:*:svnGPD:pnG1621-02:* # Pocket 3
|
||||
sensor:modalias:acpi:MXC6655:*:dmi:*:svnGPD:pnG1628-04:* # Pocket 4
|
||||
ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1
|
||||
|
||||
sensor:modalias:acpi:BMI0160:*:dmi:*:svnGPD:pnG1619-04:* # Win Max 2
|
||||
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
|
||||
|
||||
|
||||
@@ -406,6 +406,15 @@
|
||||
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--print-efi-architecture</option></term>
|
||||
|
||||
<listitem><para>Print the EFI architecture string of the local firmware. This is useful to
|
||||
generically format filenames such as <filename>boot<replaceable>x64</replaceable>.efi</filename> that
|
||||
include the local firmware architecture in the name.</para>
|
||||
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--variables=yes|no|auto</option></term>
|
||||
<listitem><para>Controls whether to touch the firmware's boot loader list stored in EFI variables,
|
||||
|
||||
@@ -711,8 +711,8 @@
|
||||
<term><varname>systemd.allow_userspace_verity=</varname></term>
|
||||
|
||||
<listitem><para>Takes a boolean argument. Controls whether disk images that are Verity protected may
|
||||
be authenticated in userspace signature checks via <filename>/etc/verity.d/</filename> (and related
|
||||
directories) public key drop-ins, or whether in-kernel signature checking only. Defaults to
|
||||
be authenticated in userspace signature checks via <filename>/etc/verity.d/*.crt</filename> (and
|
||||
related directories) public key drop-ins, or whether in-kernel signature checking only. Defaults to
|
||||
on.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
|
||||
|
||||
@@ -458,6 +458,10 @@ node /org/freedesktop/network1/link/_1 {
|
||||
interface org.freedesktop.network1.DHCPServer {
|
||||
properties:
|
||||
readonly a(uayayayayt) Leases = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly u PoolSize = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly u PoolOffset = ...;
|
||||
};
|
||||
interface org.freedesktop.DBus.Peer { ... };
|
||||
interface org.freedesktop.DBus.Introspectable { ... };
|
||||
@@ -466,8 +470,6 @@ node /org/freedesktop/network1/link/_1 {
|
||||
};
|
||||
</programlisting>
|
||||
|
||||
<!--property Leases is not documented!-->
|
||||
|
||||
<!--Autogenerated cross-references for systemd.directives, do not edit-->
|
||||
|
||||
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.network1.Link"/>
|
||||
@@ -480,10 +482,23 @@ node /org/freedesktop/network1/link/_1 {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Leases"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="PoolSize"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="PoolOffset"/>
|
||||
|
||||
<!--End of Autogenerated section-->
|
||||
|
||||
<para>
|
||||
Provides information about leases.
|
||||
Provides information about the DHCP server. The <varname>Leases</varname> property contains
|
||||
the currently active leases. The <varname>PoolSize</varname> property contains the total number
|
||||
of addresses in the dynamic address pool. The <varname>PoolOffset</varname> property contains
|
||||
the offset from the subnet base address where the pool starts. These correspond to the
|
||||
<varname>PoolSize=</varname> and <varname>PoolOffset=</varname> settings in
|
||||
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
<constant>UINT32_MAX</constant> is used as a sentinel value for <varname>PoolSize</varname>
|
||||
and <varname>PoolOffset</varname> to indicate that the information is unavailable (i.e. no
|
||||
DHCP server is configured or the link is in relay mode), rather than a valid pool size or
|
||||
offset.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
@@ -589,6 +604,10 @@ $ gdbus introspect --system \
|
||||
|
||||
<refsect1>
|
||||
<title>History</title>
|
||||
<refsect2>
|
||||
<title>DHCP Server Object</title>
|
||||
<para><varname>PoolSize</varname> and <varname>PoolOffset</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>DHCPv4 Client Object</title>
|
||||
<para><varname>State</varname> was added in version 255.</para>
|
||||
|
||||
@@ -333,6 +333,19 @@
|
||||
<xi:include href="version-info.xml" xpointer="v239"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--max-use=</option></term>
|
||||
<term><option>--keep-free=</option></term>
|
||||
<term><option>--max-file-size=</option></term>
|
||||
<term><option>--max-files=</option></term>
|
||||
|
||||
<listitem><para>These options override the corresponding settings from the configuration file
|
||||
(see <citerefentry><refentrytitle>journal-remote.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
|
||||
See that page for the descriptions of these options.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<filename>/usr/lib/</filename> it is assumed to be trusted.</para></listitem>
|
||||
|
||||
<listitem><para>If the disk image contains a Verity enabled disk image, along with a signature
|
||||
partition with a key in the kernel keyring or in <filename>/etc/verity.d/</filename> (and related
|
||||
partition with a key in the kernel keyring or in <filename>/etc/verity.d/*.crt</filename> (and related
|
||||
directories) the disk image is considered trusted.</para></listitem>
|
||||
</orderedlist>
|
||||
|
||||
|
||||
@@ -1590,6 +1590,36 @@ After=sys-subsystem-net-devices-ens1.device</programlisting>
|
||||
<xi:include href="version-info.xml" xpointer="v187"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--forward-journal=</option></term>
|
||||
|
||||
<listitem><para>Forward the container's journal to the host by starting
|
||||
<citerefentry><refentrytitle>systemd-journal-remote</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
listening on a Unix socket that is bind-mounted into the container. The container's
|
||||
<citerefentry><refentrytitle>systemd-journald</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
connects to the socket via the <varname>journal.forward_to_socket</varname> credential and streams
|
||||
journal entries to the host in real-time. Takes a path to a journal file or directory where the received
|
||||
entries will be stored. If the path ends in <literal>.journal</literal>, entries are written to a single
|
||||
file; otherwise, entries are split per host into the specified directory.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--forward-journal-max-use=<replaceable>BYTES</replaceable></option></term>
|
||||
<term><option>--forward-journal-keep-free=<replaceable>BYTES</replaceable></option></term>
|
||||
<term><option>--forward-journal-max-file-size=<replaceable>BYTES</replaceable></option></term>
|
||||
<term><option>--forward-journal-max-files=<replaceable>N</replaceable></option></term>
|
||||
|
||||
<listitem><para>These options configure the corresponding settings of
|
||||
<citerefentry><refentrytitle>systemd-journal-remote</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
when forwarding journal entries from the container. See
|
||||
<citerefentry><refentrytitle>journal-remote.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for the descriptions of these settings.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</refsect2><refsect2>
|
||||
|
||||
@@ -668,6 +668,21 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--forward-journal-max-use=<replaceable>BYTES</replaceable></option></term>
|
||||
<term><option>--forward-journal-keep-free=<replaceable>BYTES</replaceable></option></term>
|
||||
<term><option>--forward-journal-max-file-size=<replaceable>BYTES</replaceable></option></term>
|
||||
<term><option>--forward-journal-max-files=<replaceable>N</replaceable></option></term>
|
||||
|
||||
<listitem><para>These options configure the corresponding settings of
|
||||
<citerefentry><refentrytitle>systemd-journal-remote</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
when forwarding journal entries from the VM. See
|
||||
<citerefentry><refentrytitle>journal-remote.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for the descriptions of these settings.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--pass-ssh-key=<replaceable>BOOL</replaceable></option></term>
|
||||
|
||||
|
||||
@@ -1086,6 +1086,19 @@ DuplicateAddressDetection=none</programlisting></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>IPv4SrcValidMark=</varname></term>
|
||||
<listitem>
|
||||
<para>Takes a boolean. When enabled, the packet's firewall mark (fwmark) is included in the
|
||||
reverse path filter route lookup for source address validation on this interface. This is
|
||||
particularly useful for policy routing setups where packets may arrive with source addresses
|
||||
that are only valid in routing tables selected by their fwmark. When unset, the kernel's
|
||||
default will be used.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v261"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>IPv4ProxyARP=</varname></term>
|
||||
<listitem>
|
||||
|
||||
+22
-321
@@ -1067,86 +1067,6 @@ libbpf = dependency('libbpf',
|
||||
libbpf_cflags = libbpf.partial_dependency(includes: true, compile_args: true)
|
||||
conf.set10('HAVE_LIBBPF', libbpf.found())
|
||||
|
||||
if not libbpf.found()
|
||||
conf.set10('BPF_FRAMEWORK', false)
|
||||
else
|
||||
clang_found = false
|
||||
clang_supports_bpf = false
|
||||
bpf_gcc_found = false
|
||||
bpftool_strip = false
|
||||
deps_found = false
|
||||
|
||||
if bpf_compiler == 'clang'
|
||||
# Support 'versioned' clang/llvm-strip binaries, as seen on Debian/Ubuntu
|
||||
# (like clang-10/llvm-strip-10)
|
||||
if meson.is_cross_build() or cc.get_id() != 'clang' or cc.cmd_array()[0].contains('afl-clang') or cc.cmd_array()[0].contains('hfuzz-clang')
|
||||
r = find_program('clang',
|
||||
required : bpf_framework,
|
||||
version : '>= 10.0.0')
|
||||
clang_found = r.found()
|
||||
if clang_found
|
||||
clang = r.full_path()
|
||||
endif
|
||||
else
|
||||
clang_found = true
|
||||
clang = cc.cmd_array()
|
||||
endif
|
||||
|
||||
if clang_found
|
||||
# Check if 'clang -target bpf' is supported.
|
||||
clang_supports_bpf = run_command(clang, '-target', 'bpf', '--print-supported-cpus', check : false).returncode() == 0
|
||||
endif
|
||||
if bpf_framework.enabled() and not clang_supports_bpf
|
||||
error('bpf-framework was enabled but clang does not support bpf')
|
||||
endif
|
||||
elif bpf_compiler == 'gcc'
|
||||
bpf_gcc = find_program('bpf-gcc',
|
||||
'bpf-none-gcc',
|
||||
'bpf-unknown-none-gcc',
|
||||
required : true,
|
||||
version : '>= 13.1.0')
|
||||
bpf_gcc_found = bpf_gcc.found()
|
||||
endif
|
||||
|
||||
if clang_supports_bpf or bpf_gcc_found
|
||||
# Debian installs this in /usr/sbin/ which is not in $PATH.
|
||||
# We check for 'bpftool' first, honouring $PATH, and in /usr/sbin/ for Debian.
|
||||
# We use 'bpftool gen object' subcommand for bpftool strip, it was added by d80b2fcbe0a023619e0fc73112f2a02c2662f6ab (v5.13).
|
||||
bpftool = find_program('bpftool',
|
||||
'/usr/sbin/bpftool',
|
||||
required : bpf_framework.enabled() and bpf_compiler == 'gcc',
|
||||
version : bpf_compiler == 'gcc' ? '>= 7.0.0' : '>= 5.13.0')
|
||||
|
||||
if bpftool.found()
|
||||
bpftool_strip = true
|
||||
deps_found = true
|
||||
elif bpf_compiler == 'clang'
|
||||
# We require the 'bpftool gen skeleton' subcommand, it was added by 985ead416df39d6fe8e89580cc1db6aa273e0175 (v5.6).
|
||||
bpftool = find_program('bpftool',
|
||||
'/usr/sbin/bpftool',
|
||||
required : bpf_framework,
|
||||
version : '>= 5.6.0')
|
||||
endif
|
||||
|
||||
# We use `llvm-strip` as a fallback if `bpftool gen object` strip support is not available.
|
||||
if not bpftool_strip and bpftool.found() and clang_supports_bpf
|
||||
if not meson.is_cross_build()
|
||||
llvm_strip_bin = run_command(clang, '--print-prog-name', 'llvm-strip',
|
||||
check : true).stdout().strip()
|
||||
else
|
||||
llvm_strip_bin = 'llvm-strip'
|
||||
endif
|
||||
llvm_strip = find_program(llvm_strip_bin,
|
||||
required : bpf_framework,
|
||||
version : '>= 10.0.0')
|
||||
deps_found = llvm_strip.found()
|
||||
endif
|
||||
endif
|
||||
|
||||
# Can build BPF program from source code in restricted C
|
||||
conf.set10('BPF_FRAMEWORK', deps_found)
|
||||
endif
|
||||
|
||||
libmount = dependency('mount',
|
||||
version : fuzzer_build ? '>= 0' : '>= 2.30',
|
||||
required : get_option('libmount'))
|
||||
@@ -1156,8 +1076,8 @@ libmount_cflags = libmount.partial_dependency(includes: true, compile_args: true
|
||||
|
||||
libfdisk = dependency('fdisk',
|
||||
version : '>= 2.32',
|
||||
disabler : true,
|
||||
required : get_option('fdisk'))
|
||||
libfdisk_cflags = libfdisk.partial_dependency(includes: true, compile_args: true)
|
||||
conf.set10('HAVE_LIBFDISK', libfdisk.found())
|
||||
|
||||
# This prefers pwquality if both are enabled or auto.
|
||||
@@ -1261,6 +1181,7 @@ libmicrohttpd = dependency('libmicrohttpd',
|
||||
version : '>= 0.9.33',
|
||||
required : get_option('microhttpd'))
|
||||
conf.set10('HAVE_MICROHTTPD', libmicrohttpd.found())
|
||||
libmicrohttpd_cflags = libmicrohttpd.partial_dependency(includes: true, compile_args: true)
|
||||
|
||||
libcryptsetup = get_option('libcryptsetup')
|
||||
libcryptsetup_plugins = get_option('libcryptsetup-plugins')
|
||||
@@ -1332,6 +1253,7 @@ libgnutls = dependency('gnutls',
|
||||
version : '>= 3.1.4',
|
||||
required : get_option('gnutls'))
|
||||
conf.set10('HAVE_GNUTLS', libgnutls.found())
|
||||
libgnutls_cflags = libgnutls.partial_dependency(includes: true, compile_args: true)
|
||||
|
||||
libopenssl = dependency('openssl',
|
||||
version : '>= 3.0.0',
|
||||
@@ -1730,171 +1652,6 @@ endif
|
||||
|
||||
#####################################################################
|
||||
|
||||
if conf.get('BPF_FRAMEWORK') == 1
|
||||
bpf_clang_flags = [
|
||||
'-std=gnu17',
|
||||
'-Wno-compare-distinct-pointer-types',
|
||||
'-Wno-microsoft-anon-tag',
|
||||
'-fms-extensions',
|
||||
'-fno-stack-protector',
|
||||
'-O2',
|
||||
'-target',
|
||||
'bpf',
|
||||
'-g',
|
||||
'-c',
|
||||
]
|
||||
|
||||
bpf_gcc_flags = [
|
||||
'-std=gnu17',
|
||||
'-fms-extensions',
|
||||
'-fno-stack-protector',
|
||||
'-fno-ssa-phiopt',
|
||||
'-O2',
|
||||
'-mcpu=v3',
|
||||
'-mco-re',
|
||||
'-gbtf',
|
||||
'-c',
|
||||
]
|
||||
|
||||
# If c_args contains these flags copy them along with the values, in order to avoid breaking
|
||||
# reproducible builds and other functionality
|
||||
propagate_cflags = [
|
||||
'-ffile-prefix-map=',
|
||||
'-fdebug-prefix-map=',
|
||||
'-fmacro-prefix-map=',
|
||||
'--sysroot=',
|
||||
]
|
||||
|
||||
foreach opt : c_args
|
||||
foreach flag : propagate_cflags
|
||||
if opt.startswith(flag)
|
||||
bpf_clang_flags += [opt]
|
||||
bpf_gcc_flags += [opt]
|
||||
break
|
||||
endif
|
||||
endforeach
|
||||
endforeach
|
||||
|
||||
# Generate defines that are appropriate to tell the compiler what architecture
|
||||
# we're compiling for. By default we just map meson's cpu_family to __<cpu_family>__.
|
||||
# This dictionary contains the exceptions where this doesn't work.
|
||||
#
|
||||
# C.f. https://mesonbuild.com/Reference-tables.html#cpu-families
|
||||
# and src/basic/missing_syscall_def.h.
|
||||
|
||||
# Start with older ABI. When define is missing, we're likely targeting that.
|
||||
ppc64_elf_version = '1'
|
||||
|
||||
if host_machine.cpu_family() == 'ppc64'
|
||||
# cc doesn't have to be bpf_compiler, but they should be targeting the same ABI
|
||||
call_elf_value = cc.get_define('_CALL_ELF')
|
||||
if call_elf_value != ''
|
||||
ppc64_elf_version = call_elf_value
|
||||
endif
|
||||
endif
|
||||
|
||||
cpu_arch_defines = {
|
||||
'ppc' : ['-D__powerpc__', '-D__TARGET_ARCH_powerpc'],
|
||||
'ppc64' : ['-D__powerpc64__', '-D__TARGET_ARCH_powerpc', '-D_CALL_ELF=' + ppc64_elf_version],
|
||||
'riscv32' : ['-D__riscv', '-D__riscv_xlen=32', '-D__TARGET_ARCH_riscv'],
|
||||
'riscv64' : ['-D__riscv', '-D__riscv_xlen=64', '-D__TARGET_ARCH_riscv'],
|
||||
'x86' : ['-D__i386__', '-D__TARGET_ARCH_x86'],
|
||||
's390x' : ['-D__s390__', '-D__s390x__', '-D__TARGET_ARCH_s390'],
|
||||
|
||||
# For arm, assume hardware fp is available.
|
||||
'arm' : ['-D__arm__', '-D__ARM_PCS_VFP', '-D__TARGET_ARCH_arm'],
|
||||
'loongarch64' : ['-D__loongarch__', '-D__loongarch_grlen=64', '-D__TARGET_ARCH_loongarch']
|
||||
}
|
||||
|
||||
bpf_arch_flags = cpu_arch_defines.get(host_machine.cpu_family(),
|
||||
['-D__@0@__'.format(host_machine.cpu_family())])
|
||||
if bpf_compiler == 'gcc'
|
||||
bpf_arch_flags += ['-m' + host_machine.endian() + '-endian']
|
||||
endif
|
||||
|
||||
libbpf_include_dir = libbpf.get_variable(pkgconfig : 'includedir')
|
||||
|
||||
bpf_o_unstripped_cmd = []
|
||||
if bpf_compiler == 'clang'
|
||||
bpf_o_unstripped_cmd += [
|
||||
clang,
|
||||
bpf_clang_flags,
|
||||
bpf_arch_flags,
|
||||
]
|
||||
elif bpf_compiler == 'gcc'
|
||||
bpf_o_unstripped_cmd += [
|
||||
bpf_gcc,
|
||||
bpf_gcc_flags,
|
||||
bpf_arch_flags,
|
||||
]
|
||||
endif
|
||||
|
||||
bpf_o_unstripped_cmd += ['-I.', '-include', 'config.h']
|
||||
|
||||
if cc.get_id() == 'gcc' or meson.is_cross_build()
|
||||
if cc.get_id() != 'gcc'
|
||||
warning('Cross compiler is not gcc. Guessing the target triplet for bpf likely fails.')
|
||||
endif
|
||||
target_triplet_cmd = run_command(cc.cmd_array(), '-print-multiarch', check: false)
|
||||
else
|
||||
# clang does not support -print-multiarch (D133170) and its -dump-machine
|
||||
# does not match multiarch. Query gcc instead.
|
||||
target_triplet_cmd = run_command('gcc', '-print-multiarch', check: false)
|
||||
endif
|
||||
if target_triplet_cmd.returncode() == 0
|
||||
sysroot = meson.get_external_property('sys_root', '/')
|
||||
target_triplet = target_triplet_cmd.stdout().strip()
|
||||
target_include_dir = sysroot / 'usr' / 'include'
|
||||
target_triple_include_dir = target_include_dir / target_triplet
|
||||
isystem_dir = ''
|
||||
if fs.is_dir(target_triple_include_dir)
|
||||
isystem_dir = target_triple_include_dir
|
||||
elif fs.is_dir(target_include_dir)
|
||||
isystem_dir = target_include_dir
|
||||
endif
|
||||
if isystem_dir != ''
|
||||
bpf_o_unstripped_cmd += [
|
||||
'-isystem', isystem_dir
|
||||
]
|
||||
endif
|
||||
endif
|
||||
|
||||
bpf_o_unstripped_cmd += [
|
||||
'-idirafter',
|
||||
libbpf_include_dir,
|
||||
'@INPUT@',
|
||||
'-o',
|
||||
'@OUTPUT@'
|
||||
]
|
||||
|
||||
if bpftool_strip
|
||||
bpf_o_cmd = [
|
||||
bpftool,
|
||||
'gen',
|
||||
'object',
|
||||
'@OUTPUT@',
|
||||
'@INPUT@'
|
||||
]
|
||||
elif bpf_compiler == 'clang'
|
||||
bpf_o_cmd = [
|
||||
llvm_strip,
|
||||
'-g',
|
||||
'@INPUT@',
|
||||
'-o',
|
||||
'@OUTPUT@'
|
||||
]
|
||||
endif
|
||||
|
||||
skel_h_cmd = [
|
||||
bpftool,
|
||||
'gen',
|
||||
'skeleton',
|
||||
'@INPUT@'
|
||||
]
|
||||
endif
|
||||
|
||||
#####################################################################
|
||||
|
||||
efi_arch = {
|
||||
'aarch64' : 'aa64',
|
||||
'arm' : 'arm',
|
||||
@@ -1932,77 +1689,6 @@ conf.set10('ENABLE_UKIFY', want_ukify)
|
||||
|
||||
#####################################################################
|
||||
|
||||
use_provided_vmlinux_h = false
|
||||
use_generated_vmlinux_h = false
|
||||
provided_vmlinux_h_path = get_option('vmlinux-h-path')
|
||||
|
||||
# For the more complex BPF programs we really want a vmlinux.h (which is arch
|
||||
# specific, but only somewhat bound to kernel version). Ideally the kernel
|
||||
# development headers would ship that, but right now they don't. Hence address
|
||||
# this in two ways:
|
||||
#
|
||||
# 1. Provide a vmlinux.h at build time
|
||||
# 2. Generate the file on the fly where possible (which requires /sys/ to be mounted)
|
||||
#
|
||||
# We generally prefer the former (to support reproducible builds), but will
|
||||
# fallback to the latter.
|
||||
|
||||
if conf.get('BPF_FRAMEWORK') == 1
|
||||
enable_vmlinux_h = get_option('vmlinux-h')
|
||||
|
||||
if enable_vmlinux_h == 'auto'
|
||||
if provided_vmlinux_h_path != ''
|
||||
use_provided_vmlinux_h = true
|
||||
elif fs.exists('/sys/kernel/btf/vmlinux') and \
|
||||
bpftool.found() and \
|
||||
(host_machine.cpu_family() == build_machine.cpu_family()) and \
|
||||
host_machine.cpu_family() in ['x86_64', 'aarch64']
|
||||
|
||||
# We will only generate a vmlinux.h from the running
|
||||
# kernel if the host and build machine are of the same
|
||||
# family. Also for now we focus on x86_64 and aarch64,
|
||||
# since other archs don't seem to be ready yet.
|
||||
|
||||
use_generated_vmlinux_h = true
|
||||
endif
|
||||
elif enable_vmlinux_h == 'provided'
|
||||
use_provided_vmlinux_h = true
|
||||
elif enable_vmlinux_h == 'generated'
|
||||
if not fs.exists('/sys/kernel/btf/vmlinux')
|
||||
error('BTF data from kernel not available (/sys/kernel/btf/vmlinux missing), cannot generate vmlinux.h, but was asked to.')
|
||||
endif
|
||||
if not bpftool.found()
|
||||
error('bpftool not available, cannot generate vmlinux.h, but was asked to.')
|
||||
endif
|
||||
use_generated_vmlinux_h = true
|
||||
endif
|
||||
endif
|
||||
|
||||
vmlinux_h_dependency = []
|
||||
if use_provided_vmlinux_h
|
||||
if not fs.exists(provided_vmlinux_h_path)
|
||||
error('Path to provided vmlinux.h does not exist.')
|
||||
endif
|
||||
bpf_o_unstripped_cmd += ['-I' + fs.parent(provided_vmlinux_h_path)]
|
||||
message(f'Using provided @provided_vmlinux_h_path@')
|
||||
elif use_generated_vmlinux_h
|
||||
vmlinux_h_dependency = custom_target(
|
||||
output: 'vmlinux.h',
|
||||
command : [ bpftool, 'btf', 'dump', 'file', '/sys/kernel/btf/vmlinux', 'format', 'c' ],
|
||||
capture : true)
|
||||
|
||||
bpf_o_unstripped_cmd += ['-I' + fs.parent(vmlinux_h_dependency.full_path())]
|
||||
message('Using generated @0@'.format(vmlinux_h_dependency.full_path()))
|
||||
else
|
||||
message('Using neither provided nor generated vmlinux.h, some features will not be available.')
|
||||
endif
|
||||
|
||||
conf.set10('HAVE_VMLINUX_H', use_provided_vmlinux_h or use_generated_vmlinux_h)
|
||||
|
||||
conf.set10('ENABLE_SYSCTL_BPF', conf.get('HAVE_VMLINUX_H') == 1 and libbpf.version().version_compare('>= 0.7'))
|
||||
|
||||
#####################################################################
|
||||
|
||||
version_tag = get_option('version-tag')
|
||||
if version_tag == ''
|
||||
version_tag = meson.project_version()
|
||||
@@ -2010,8 +1696,11 @@ endif
|
||||
|
||||
conf.set_quoted('VERSION_TAG', version_tag)
|
||||
|
||||
generated_sources = []
|
||||
|
||||
subdir('tools')
|
||||
subdir('src/version')
|
||||
subdir('src/bpf')
|
||||
|
||||
shared_lib_tag = get_option('shared-lib-tag')
|
||||
if shared_lib_tag == ''
|
||||
@@ -2051,7 +1740,6 @@ executables = []
|
||||
executables_by_name = {}
|
||||
objects_by_name = {}
|
||||
fuzzer_exes = []
|
||||
generated_sources = [version_h, vmlinux_h_dependency]
|
||||
sources = []
|
||||
|
||||
# binaries that have --help and are intended for use by humans,
|
||||
@@ -2118,7 +1806,13 @@ libsystemd_includes = [basic_includes, include_directories(
|
||||
'src/libsystemd/sd-resolve',
|
||||
'src/libsystemd/sd-varlink')]
|
||||
|
||||
includes = [libsystemd_includes, include_directories('src/shared')]
|
||||
includes = [
|
||||
libsystemd_includes,
|
||||
include_directories(
|
||||
'src/shared',
|
||||
'src/bpf',
|
||||
),
|
||||
]
|
||||
|
||||
subdir('po')
|
||||
subdir('catalog')
|
||||
@@ -2519,11 +2213,18 @@ foreach dict : executables
|
||||
|
||||
exe_sources = dict.get('sources', []) + dict.get('extract', [])
|
||||
|
||||
foreach bpf_name : dict.get('bpf_programs', [])
|
||||
if bpf_name in bpf_programs_by_name
|
||||
exe_sources += bpf_programs_by_name[bpf_name]
|
||||
endif
|
||||
endforeach
|
||||
|
||||
kwargs = {}
|
||||
foreach key, val : dict
|
||||
if key in ['name', 'dbus', 'public', 'conditions', 'type', 'suite',
|
||||
'timeout', 'parallel', 'objects', 'sources', 'extract',
|
||||
'include_directories', 'build_by_default', 'install']
|
||||
'include_directories', 'build_by_default', 'install',
|
||||
'bpf_programs']
|
||||
continue
|
||||
endif
|
||||
|
||||
@@ -2541,7 +2242,7 @@ foreach dict : executables
|
||||
|
||||
foreach val : dict.get('objects', [])
|
||||
obj = objects_by_name[val]
|
||||
kwargs += { 'objects' : obj['objects'] }
|
||||
kwargs += { 'objects' : kwargs.get('objects', []) + obj['objects'] }
|
||||
include_directories += obj['include_directories']
|
||||
endforeach
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ Packages=
|
||||
kernel-core
|
||||
knot
|
||||
libcap-ng-utils
|
||||
libmicrohttpd
|
||||
libucontext
|
||||
man-db
|
||||
nmap-ncat
|
||||
|
||||
@@ -57,6 +57,7 @@ Packages=
|
||||
libcap-progs
|
||||
libdw-devel
|
||||
libdw1
|
||||
libmicrohttpd12
|
||||
libtss2-tcti-device0
|
||||
libz1
|
||||
man
|
||||
@@ -84,6 +85,7 @@ Packages=
|
||||
softhsm
|
||||
squashfs
|
||||
stress-ng
|
||||
system-user-bin
|
||||
tgt
|
||||
timezone
|
||||
tpm2.0-tools
|
||||
|
||||
@@ -9,5 +9,5 @@ Environment=
|
||||
GIT_URL=https://salsa.debian.org/systemd-team/systemd.git
|
||||
GIT_SUBDIR=debian
|
||||
GIT_BRANCH=debian/master
|
||||
GIT_COMMIT=23ef56be0050f78be704f288ed1ce30ace47cbfe
|
||||
GIT_COMMIT=94af257c72ac3e9bf20e324ff31c3bd5d8197f0e
|
||||
PKG_SUBDIR=debian
|
||||
|
||||
@@ -27,8 +27,9 @@ mountpoint -q /etc/resolv.conf && umount /etc/resolv.conf
|
||||
rm -f /etc/resolv.conf
|
||||
|
||||
for f in "$BUILDROOT"/usr/share/*.verity.sig; do
|
||||
jq --join-output '.rootHash' "$f" >"${f%.verity.sig}.roothash"
|
||||
jq --join-output '.signature' "$f" | base64 --decode >"${f%.verity.sig}.roothash.p7s"
|
||||
# jq started refusing input with NUL bytes padding
|
||||
strings "$f" | jq --join-output '.rootHash' >"${f%.verity.sig}.roothash"
|
||||
strings "$f" | jq --join-output '.signature' | base64 --decode >"${f%.verity.sig}.roothash.p7s"
|
||||
done
|
||||
|
||||
# We want /var/log/journal to be created on first boot so it can be created with the right chattr settings by
|
||||
|
||||
@@ -84,6 +84,7 @@ wrap=(
|
||||
mdadm
|
||||
mkfs.btrfs
|
||||
mksquashfs
|
||||
mount
|
||||
multipath
|
||||
multipathd
|
||||
nvme
|
||||
@@ -99,6 +100,7 @@ wrap=(
|
||||
su
|
||||
tar
|
||||
tgtd
|
||||
umount
|
||||
unix_chkpwd
|
||||
useradd
|
||||
userdel
|
||||
|
||||
+9
-8
@@ -3,17 +3,18 @@
|
||||
# Brazilian Portuguese translation for systemd.
|
||||
# Enrico Nicoletto <liverig@gmail.com>, 2014.
|
||||
# Filipe Brandenburger <filbranden@gmail.com>, 2018.
|
||||
# Rafael Fontenelle <rafaelff@gnome.org>, 2015-2020, 2025.
|
||||
# Rafael Fontenelle <rafaelff@gnome.org>, 2015-2020, 2025, 2026.
|
||||
# Gustavo Costa <xfgusta@gmail.com>, 2021.
|
||||
# Tiago Rocha Cunha <tiagocunha.me@gmail.com>, 2024.
|
||||
# Gabriel Elyas <gabrielelyas@protonmail.com>, 2024.
|
||||
# Fábio Rodrigues Ribeiro <farribeiro@gmail.com>, 2024.
|
||||
# "Geraldo S. Simião Kutz" <geraldo.simiao.kutz@gmail.com>, 2024.
|
||||
# Weblate Translation Memory <noreply-mt-weblate-translation-memory@weblate.org>, 2026.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-06 03:46+0900\n"
|
||||
"PO-Revision-Date: 2025-10-29 18:54+0000\n"
|
||||
"PO-Revision-Date: 2026-04-22 10:58+0000\n"
|
||||
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
|
||||
"Language-Team: Portuguese (Brazil) <https://translate.fedoraproject.org/"
|
||||
"projects/systemd/main/pt_BR/>\n"
|
||||
@@ -22,7 +23,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 5.13.3\n"
|
||||
"X-Generator: Weblate 5.17\n"
|
||||
|
||||
#: src/core/org.freedesktop.systemd1.policy.in:22
|
||||
msgid "Send passphrase back to system"
|
||||
@@ -1051,12 +1052,12 @@ msgid "DHCP server sends force renew message"
|
||||
msgstr "Servidor DHCP envia mensagem de renovação forçada"
|
||||
|
||||
#: src/network/org.freedesktop.network1.policy:144
|
||||
#, fuzzy
|
||||
#| msgid "Authentication is required to send force renew message."
|
||||
msgid ""
|
||||
"Authentication is required to send a force renew message from the DHCP "
|
||||
"server."
|
||||
msgstr "É necessária autenticação para enviar mensagem de renovação forçada."
|
||||
msgstr ""
|
||||
"É necessária autenticação para enviar uma mensagem de renovação forçada a "
|
||||
"partir do servidor DHCP."
|
||||
|
||||
#: src/network/org.freedesktop.network1.policy:154
|
||||
msgid "Renew dynamic addresses"
|
||||
@@ -1098,11 +1099,11 @@ msgstr ""
|
||||
|
||||
#: src/network/org.freedesktop.network1.policy:198
|
||||
msgid "Manage network links"
|
||||
msgstr ""
|
||||
msgstr "Gerenciar conexões de rede"
|
||||
|
||||
#: src/network/org.freedesktop.network1.policy:199
|
||||
msgid "Authentication is required to manage network links."
|
||||
msgstr ""
|
||||
msgstr "A autenticação é necessária para gerenciar conexões de rede."
|
||||
|
||||
#: src/portable/org.freedesktop.portable1.policy:13
|
||||
msgid "Inspect a portable service image"
|
||||
|
||||
@@ -35,6 +35,7 @@ _bootctl() {
|
||||
[STANDALONE]='-h --help --version
|
||||
-p --print-esp-path -x --print-boot-path --print-loader-path
|
||||
--print-stub-path -R --print-root-device -RR
|
||||
--print-efi-architecture
|
||||
--no-pager --graceful -q --quiet --all-architectures
|
||||
--dry-run'
|
||||
[ARG]='--esp-path --boot-path --root --image --image-policy --install-source
|
||||
|
||||
@@ -78,7 +78,9 @@ _systemd_nspawn() {
|
||||
--network-ipvlan --network-veth-extra --network-zone -p --port --system-call-filter --overlay
|
||||
--overlay-ro --settings --rlimit --hostname --no-new-privileges --oom-score-adjust --cpu-affinity
|
||||
--resolv-conf --timezone --root-hash-sig --background --oci-bundle --verity-data
|
||||
--restrict-address-families'
|
||||
--restrict-address-families
|
||||
--forward-journal --forward-journal-max-use --forward-journal-keep-free
|
||||
--forward-journal-max-file-size --forward-journal-max-files'
|
||||
)
|
||||
|
||||
_init_completion || return
|
||||
|
||||
@@ -38,7 +38,7 @@ _systemd_vmspawn() {
|
||||
[BIND]='--bind --bind-ro'
|
||||
[SSH_KEY]='--ssh-key'
|
||||
[CONSOLE]='--console'
|
||||
[ARG]='--cpus --ram --vsock-cid -M --machine --uuid --private-users --background --set-credential --load-credential'
|
||||
[ARG]='--cpus --ram --vsock-cid -M --machine --uuid --private-users --background --set-credential --load-credential --forward-journal-max-use --forward-journal-keep-free --forward-journal-max-file-size --forward-journal-max-files'
|
||||
[IMAGE_FORMAT]='--image-format'
|
||||
[IMAGE_DISK_TYPE]='--image-disk-type'
|
||||
)
|
||||
|
||||
@@ -74,6 +74,7 @@ _arguments \
|
||||
'--boot-path=[Path to the $BOOT partition]:path:_directories' \
|
||||
'(-p --print-esp-path)'{-p,--print-esp-path}'[Print path to the EFI system partition]' \
|
||||
'(-x --print-boot-path)'{-x,--print-boot-path}'[Print path to the $BOOT partition]' \
|
||||
'--print-efi-architecture[Print the EFI architecture identifier]' \
|
||||
'--make-machine-id-directory=[Control creation and deletion of the top-level machine ID directory.]:options:(yes no auto)' \
|
||||
'--no-pager[Do not pipe output into a pager]' \
|
||||
'--graceful[Do not fail when locating ESP or writing fails]' \
|
||||
|
||||
@@ -54,4 +54,9 @@ _arguments \
|
||||
"--notify-ready=[Control when the ready notification is sent]:options:(yes no)" \
|
||||
"--suppress-sync=[Control whether to suppress disk synchronization for the container payload]:options:(yes no)" \
|
||||
'--restrict-address-families=[Restrict socket address families accessible in the container.]: : _message "address families"' \
|
||||
'--forward-journal=[Forward the container journal to the host via systemd-journal-remote.]: : _files' \
|
||||
'--forward-journal-max-use=[Maximum disk space used by forwarded journal files.]: : _message bytes' \
|
||||
'--forward-journal-keep-free=[Disk space to keep free for forwarded journal files.]: : _message bytes' \
|
||||
'--forward-journal-max-file-size=[Maximum size of individual forwarded journal files.]: : _message bytes' \
|
||||
'--forward-journal-max-files=[Maximum number of forwarded journal files.]: : _message number' \
|
||||
'*:: : _normal'
|
||||
|
||||
@@ -605,7 +605,7 @@ static int assess_system_call_filter(
|
||||
uint64_t b;
|
||||
int r;
|
||||
|
||||
r = dlopen_libseccomp();
|
||||
r = dlopen_libseccomp(LOG_DEBUG);
|
||||
if (r < 0) {
|
||||
*ret_badness = UINT64_MAX;
|
||||
*ret_description = NULL;
|
||||
@@ -2578,7 +2578,7 @@ static int get_security_info(Unit *u, ExecContext *c, CGroupContext *g, Security
|
||||
info->_umask = c->umask;
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
if (dlopen_libseccomp() >= 0) {
|
||||
if (dlopen_libseccomp(LOG_DEBUG) >= 0) {
|
||||
SET_FOREACH(key, c->syscall_archs) {
|
||||
const char *name;
|
||||
|
||||
|
||||
+51
-46
@@ -284,7 +284,7 @@ Compression compression_detect_from_magic(const uint8_t data[static COMPRESSION_
|
||||
return _COMPRESSION_INVALID;
|
||||
}
|
||||
|
||||
int dlopen_xz(void) {
|
||||
int dlopen_xz(int log_level) {
|
||||
#if HAVE_XZ
|
||||
SD_ELF_NOTE_DLOPEN(
|
||||
"lzma",
|
||||
@@ -294,7 +294,7 @@ int dlopen_xz(void) {
|
||||
|
||||
return dlopen_many_sym_or_warn(
|
||||
&lzma_dl,
|
||||
"liblzma.so.5", LOG_DEBUG,
|
||||
"liblzma.so.5", log_level,
|
||||
DLSYM_ARG(lzma_code),
|
||||
DLSYM_ARG(lzma_easy_encoder),
|
||||
DLSYM_ARG(lzma_end),
|
||||
@@ -302,11 +302,12 @@ int dlopen_xz(void) {
|
||||
DLSYM_ARG(lzma_lzma_preset),
|
||||
DLSYM_ARG(lzma_stream_decoder));
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"lzma support is not compiled in.");
|
||||
#endif
|
||||
}
|
||||
|
||||
int dlopen_lz4(void) {
|
||||
int dlopen_lz4(int log_level) {
|
||||
#if HAVE_LZ4
|
||||
SD_ELF_NOTE_DLOPEN(
|
||||
"lz4",
|
||||
@@ -316,7 +317,7 @@ int dlopen_lz4(void) {
|
||||
|
||||
return dlopen_many_sym_or_warn(
|
||||
&lz4_dl,
|
||||
"liblz4.so.1", LOG_DEBUG,
|
||||
"liblz4.so.1", log_level,
|
||||
DLSYM_ARG(LZ4F_compressBegin),
|
||||
DLSYM_ARG(LZ4F_compressBound),
|
||||
DLSYM_ARG(LZ4F_compressEnd),
|
||||
@@ -333,11 +334,12 @@ int dlopen_lz4(void) {
|
||||
DLSYM_ARG(LZ4_decompress_safe_partial),
|
||||
DLSYM_ARG(LZ4_versionNumber));
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"lz4 support is not compiled in.");
|
||||
#endif
|
||||
}
|
||||
|
||||
int dlopen_zstd(void) {
|
||||
int dlopen_zstd(int log_level) {
|
||||
#if HAVE_ZSTD
|
||||
SD_ELF_NOTE_DLOPEN(
|
||||
"zstd",
|
||||
@@ -347,7 +349,7 @@ int dlopen_zstd(void) {
|
||||
|
||||
return dlopen_many_sym_or_warn(
|
||||
&zstd_dl,
|
||||
"libzstd.so.1", LOG_DEBUG,
|
||||
"libzstd.so.1", log_level,
|
||||
DLSYM_ARG(ZSTD_getErrorCode),
|
||||
DLSYM_ARG(ZSTD_compress),
|
||||
DLSYM_ARG(ZSTD_getFrameContentSize),
|
||||
@@ -365,11 +367,12 @@ int dlopen_zstd(void) {
|
||||
DLSYM_ARG(ZSTD_createDCtx),
|
||||
DLSYM_ARG(ZSTD_createCCtx));
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"zstd support is not compiled in.");
|
||||
#endif
|
||||
}
|
||||
|
||||
int dlopen_zlib(void) {
|
||||
int dlopen_zlib(int log_level) {
|
||||
#if HAVE_ZLIB
|
||||
SD_ELF_NOTE_DLOPEN(
|
||||
"zlib",
|
||||
@@ -379,7 +382,7 @@ int dlopen_zlib(void) {
|
||||
|
||||
return dlopen_many_sym_or_warn(
|
||||
&zlib_dl,
|
||||
"libz.so.1", LOG_DEBUG,
|
||||
"libz.so.1", log_level,
|
||||
DLSYM_ARG(deflateInit2_),
|
||||
DLSYM_ARG(deflate),
|
||||
DLSYM_ARG(deflateEnd),
|
||||
@@ -387,11 +390,12 @@ int dlopen_zlib(void) {
|
||||
DLSYM_ARG(inflate),
|
||||
DLSYM_ARG(inflateEnd));
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"zlib support is not compiled in.");
|
||||
#endif
|
||||
}
|
||||
|
||||
int dlopen_bzip2(void) {
|
||||
int dlopen_bzip2(int log_level) {
|
||||
#if HAVE_BZIP2
|
||||
SD_ELF_NOTE_DLOPEN(
|
||||
"bzip2",
|
||||
@@ -401,7 +405,7 @@ int dlopen_bzip2(void) {
|
||||
|
||||
return dlopen_many_sym_or_warn(
|
||||
&bzip2_dl,
|
||||
"libbz2.so.1", LOG_DEBUG,
|
||||
"libbz2.so.1", log_level,
|
||||
DLSYM_ARG(BZ2_bzCompressInit),
|
||||
DLSYM_ARG(BZ2_bzCompress),
|
||||
DLSYM_ARG(BZ2_bzCompressEnd),
|
||||
@@ -409,7 +413,8 @@ int dlopen_bzip2(void) {
|
||||
DLSYM_ARG(BZ2_bzDecompress),
|
||||
DLSYM_ARG(BZ2_bzDecompressEnd));
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"bzip2 support is not compiled in.");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -440,7 +445,7 @@ static int compress_blob_xz(
|
||||
size_t out_pos = 0;
|
||||
int r;
|
||||
|
||||
r = dlopen_xz();
|
||||
r = dlopen_xz(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -485,7 +490,7 @@ static int compress_blob_lz4(
|
||||
#if HAVE_LZ4
|
||||
int r;
|
||||
|
||||
r = dlopen_lz4();
|
||||
r = dlopen_lz4(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
/* Returns < 0 if we couldn't compress the data or the
|
||||
@@ -533,7 +538,7 @@ static int compress_blob_zstd(
|
||||
size_t k;
|
||||
int r;
|
||||
|
||||
r = dlopen_zstd();
|
||||
r = dlopen_zstd(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -560,7 +565,7 @@ static int compress_blob_gzip(const void *src, uint64_t src_size,
|
||||
#if HAVE_ZLIB
|
||||
int r;
|
||||
|
||||
r = dlopen_zlib();
|
||||
r = dlopen_zlib(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -609,7 +614,7 @@ static int compress_blob_bzip2(
|
||||
#if HAVE_BZIP2
|
||||
int r;
|
||||
|
||||
r = dlopen_bzip2();
|
||||
r = dlopen_bzip2(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -677,7 +682,7 @@ static int decompress_blob_xz(
|
||||
#if HAVE_XZ
|
||||
int r;
|
||||
|
||||
r = dlopen_xz();
|
||||
r = dlopen_xz(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -744,7 +749,7 @@ static int decompress_blob_lz4(
|
||||
char* out;
|
||||
int r, size; /* LZ4 uses int for size */
|
||||
|
||||
r = dlopen_lz4();
|
||||
r = dlopen_lz4(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -790,7 +795,7 @@ static int decompress_blob_zstd(
|
||||
uint64_t size;
|
||||
int r;
|
||||
|
||||
r = dlopen_zstd();
|
||||
r = dlopen_zstd(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -847,7 +852,7 @@ static int decompress_blob_gzip(
|
||||
#if HAVE_ZLIB
|
||||
int r;
|
||||
|
||||
r = dlopen_zlib();
|
||||
r = dlopen_zlib(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -914,7 +919,7 @@ static int decompress_blob_bzip2(
|
||||
#if HAVE_BZIP2
|
||||
int r;
|
||||
|
||||
r = dlopen_bzip2();
|
||||
r = dlopen_bzip2(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1010,7 +1015,7 @@ int decompress_zlib_raw(
|
||||
#if HAVE_ZLIB
|
||||
int r;
|
||||
|
||||
r = dlopen_zlib();
|
||||
r = dlopen_zlib(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1061,7 +1066,7 @@ static int decompress_startswith_xz(
|
||||
#if HAVE_XZ
|
||||
int r;
|
||||
|
||||
r = dlopen_xz();
|
||||
r = dlopen_xz(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1128,7 +1133,7 @@ static int decompress_startswith_lz4(
|
||||
size_t allocated;
|
||||
int r;
|
||||
|
||||
r = dlopen_lz4();
|
||||
r = dlopen_lz4(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1200,7 +1205,7 @@ static int decompress_startswith_zstd(
|
||||
#if HAVE_ZSTD
|
||||
int r;
|
||||
|
||||
r = dlopen_zstd();
|
||||
r = dlopen_zstd(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1257,7 +1262,7 @@ static int decompress_startswith_gzip(
|
||||
#if HAVE_ZLIB
|
||||
int r;
|
||||
|
||||
r = dlopen_zlib();
|
||||
r = dlopen_zlib(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1324,7 +1329,7 @@ static int decompress_startswith_bzip2(
|
||||
#if HAVE_BZIP2
|
||||
int r;
|
||||
|
||||
r = dlopen_bzip2();
|
||||
r = dlopen_bzip2(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1561,7 +1566,7 @@ static int decompressor_new(Decompressor **ret, Compression type) {
|
||||
|
||||
#if HAVE_XZ
|
||||
case COMPRESSION_XZ:
|
||||
r = dlopen_xz();
|
||||
r = dlopen_xz(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1572,7 +1577,7 @@ static int decompressor_new(Decompressor **ret, Compression type) {
|
||||
|
||||
#if HAVE_LZ4
|
||||
case COMPRESSION_LZ4: {
|
||||
r = dlopen_lz4();
|
||||
r = dlopen_lz4(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1586,7 +1591,7 @@ static int decompressor_new(Decompressor **ret, Compression type) {
|
||||
|
||||
#if HAVE_ZSTD
|
||||
case COMPRESSION_ZSTD:
|
||||
r = dlopen_zstd();
|
||||
r = dlopen_zstd(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1598,7 +1603,7 @@ static int decompressor_new(Decompressor **ret, Compression type) {
|
||||
|
||||
#if HAVE_ZLIB
|
||||
case COMPRESSION_GZIP:
|
||||
r = dlopen_zlib();
|
||||
r = dlopen_zlib(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1610,7 +1615,7 @@ static int decompressor_new(Decompressor **ret, Compression type) {
|
||||
|
||||
#if HAVE_BZIP2
|
||||
case COMPRESSION_BZIP2:
|
||||
r = dlopen_bzip2();
|
||||
r = dlopen_bzip2(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1791,7 +1796,7 @@ int decompressor_detect(Decompressor **ret, const void *data, size_t size) {
|
||||
|
||||
#if HAVE_XZ
|
||||
case COMPRESSION_XZ: {
|
||||
r = dlopen_xz();
|
||||
r = dlopen_xz(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1805,7 +1810,7 @@ int decompressor_detect(Decompressor **ret, const void *data, size_t size) {
|
||||
|
||||
#if HAVE_LZ4
|
||||
case COMPRESSION_LZ4: {
|
||||
r = dlopen_lz4();
|
||||
r = dlopen_lz4(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1819,7 +1824,7 @@ int decompressor_detect(Decompressor **ret, const void *data, size_t size) {
|
||||
|
||||
#if HAVE_ZSTD
|
||||
case COMPRESSION_ZSTD: {
|
||||
r = dlopen_zstd();
|
||||
r = dlopen_zstd(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1833,7 +1838,7 @@ int decompressor_detect(Decompressor **ret, const void *data, size_t size) {
|
||||
|
||||
#if HAVE_ZLIB
|
||||
case COMPRESSION_GZIP: {
|
||||
r = dlopen_zlib();
|
||||
r = dlopen_zlib(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1847,7 +1852,7 @@ int decompressor_detect(Decompressor **ret, const void *data, size_t size) {
|
||||
|
||||
#if HAVE_BZIP2
|
||||
case COMPRESSION_BZIP2: {
|
||||
r = dlopen_bzip2();
|
||||
r = dlopen_bzip2(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -2092,7 +2097,7 @@ int compressor_new(Compressor **ret, Compression type) {
|
||||
|
||||
#if HAVE_XZ
|
||||
case COMPRESSION_XZ: {
|
||||
r = dlopen_xz();
|
||||
r = dlopen_xz(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -2107,7 +2112,7 @@ int compressor_new(Compressor **ret, Compression type) {
|
||||
|
||||
#if HAVE_LZ4
|
||||
case COMPRESSION_LZ4: {
|
||||
r = dlopen_lz4();
|
||||
r = dlopen_lz4(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -2133,7 +2138,7 @@ int compressor_new(Compressor **ret, Compression type) {
|
||||
|
||||
#if HAVE_ZSTD
|
||||
case COMPRESSION_ZSTD:
|
||||
r = dlopen_zstd();
|
||||
r = dlopen_zstd(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -2156,7 +2161,7 @@ int compressor_new(Compressor **ret, Compression type) {
|
||||
|
||||
#if HAVE_ZLIB
|
||||
case COMPRESSION_GZIP:
|
||||
r = dlopen_zlib();
|
||||
r = dlopen_zlib(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -2176,7 +2181,7 @@ int compressor_new(Compressor **ret, Compression type) {
|
||||
|
||||
#if HAVE_BZIP2
|
||||
case COMPRESSION_BZIP2:
|
||||
r = dlopen_bzip2();
|
||||
r = dlopen_bzip2(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -80,11 +80,11 @@ int compress_stream(Compression type, int fdf, int fdt, uint64_t max_bytes, uint
|
||||
int decompress_stream(Compression type, int fdf, int fdt, uint64_t max_bytes);
|
||||
int decompress_stream_by_filename(const char *filename, int fdf, int fdt, uint64_t max_bytes);
|
||||
|
||||
int dlopen_xz(void);
|
||||
int dlopen_lz4(void);
|
||||
int dlopen_zstd(void);
|
||||
int dlopen_zlib(void);
|
||||
int dlopen_bzip2(void);
|
||||
int dlopen_xz(int log_level);
|
||||
int dlopen_lz4(int log_level);
|
||||
int dlopen_zstd(int log_level);
|
||||
int dlopen_zlib(int log_level);
|
||||
int dlopen_bzip2(int log_level);
|
||||
|
||||
static inline const char* default_compression_extension(void) {
|
||||
return compression_extension_to_string(DEFAULT_COMPRESSION) ?: "";
|
||||
|
||||
@@ -47,7 +47,7 @@ int dlsym_many_or_warn_sentinel(void *dl, int log_level, ...) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int dlopen_verbose(void **dlp, const char *filename) {
|
||||
int dlopen_verbose(void **dlp, const char *filename, int log_level) {
|
||||
int r;
|
||||
|
||||
assert(dlp);
|
||||
@@ -58,10 +58,9 @@ int dlopen_verbose(void **dlp, const char *filename) {
|
||||
_cleanup_(dlclosep) void *dl = NULL;
|
||||
const char *dle = NULL;
|
||||
r = dlopen_safe(filename, &dl, &dle);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Shared library '%s' is not available: %s", filename, dle ?: STRERROR(r));
|
||||
return -EOPNOTSUPP; /* Turn into recognizable error */
|
||||
}
|
||||
if (r < 0)
|
||||
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Shared library '%s' is not available: %s", filename, dle ?: STRERROR(r));
|
||||
|
||||
log_debug("Loaded shared library '%s' via dlopen().", filename);
|
||||
*dlp = TAKE_PTR(dl);
|
||||
@@ -77,7 +76,7 @@ int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_l
|
||||
return 0; /* Already loaded */
|
||||
|
||||
_cleanup_(dlclosep) void *dl = NULL;
|
||||
r = dlopen_verbose(&dl, filename);
|
||||
r = dlopen_verbose(&dl, filename, log_level);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ static inline void dlclosep(void **dlp) {
|
||||
safe_dlclose(*dlp);
|
||||
}
|
||||
|
||||
int dlopen_verbose(void **dlp, const char *filename);
|
||||
int dlopen_verbose(void **dlp, const char *filename, int log_level);
|
||||
int dlsym_many_or_warn_sentinel(void *dl, int log_level, ...) _sentinel_;
|
||||
int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_level, ...) _sentinel_;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "sd-dlopen.h"
|
||||
|
||||
#include "gcrypt-util.h"
|
||||
#include "log.h" /* IWYU pragma: keep */
|
||||
|
||||
#if HAVE_GCRYPT
|
||||
|
||||
@@ -44,7 +45,7 @@ DLSYM_PROTOTYPE(gcry_randomize) = NULL;
|
||||
DLSYM_PROTOTYPE(gcry_strerror) = NULL;
|
||||
#endif
|
||||
|
||||
int dlopen_gcrypt(void) {
|
||||
int dlopen_gcrypt(int log_level) {
|
||||
#if HAVE_GCRYPT
|
||||
SD_ELF_NOTE_DLOPEN(
|
||||
"gcrypt",
|
||||
@@ -54,7 +55,7 @@ int dlopen_gcrypt(void) {
|
||||
|
||||
return dlopen_many_sym_or_warn(
|
||||
&gcrypt_dl,
|
||||
"libgcrypt.so.20", LOG_DEBUG,
|
||||
"libgcrypt.so.20", log_level,
|
||||
DLSYM_ARG(gcry_control),
|
||||
DLSYM_ARG(gcry_check_version),
|
||||
DLSYM_ARG(gcry_md_close),
|
||||
@@ -88,7 +89,8 @@ int dlopen_gcrypt(void) {
|
||||
DLSYM_ARG(gcry_randomize),
|
||||
DLSYM_ARG(gcry_strerror));
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"gcrypt support is not compiled in.");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -96,7 +98,7 @@ int initialize_libgcrypt(bool secmem) {
|
||||
#if HAVE_GCRYPT
|
||||
int r;
|
||||
|
||||
r = dlopen_gcrypt();
|
||||
r = dlopen_gcrypt(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "basic-forward.h"
|
||||
|
||||
int dlopen_gcrypt(void);
|
||||
int dlopen_gcrypt(int log_level);
|
||||
|
||||
int initialize_libgcrypt(bool secmem);
|
||||
|
||||
|
||||
+12
-8
@@ -21,35 +21,39 @@ size_t iovec_total_size(const struct iovec *iovec, size_t n) {
|
||||
|
||||
assert(iovec || n == 0);
|
||||
|
||||
FOREACH_ARRAY(j, iovec, n)
|
||||
FOREACH_ARRAY(j, iovec, n) {
|
||||
if (j->iov_len > SIZE_MAX - sum)
|
||||
return SIZE_MAX; /* Indicate overflow. */
|
||||
sum += j->iov_len;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
bool iovec_increment(struct iovec *iovec, size_t n, size_t k) {
|
||||
bool iovec_inc_many(struct iovec *iovec, size_t n, size_t k) {
|
||||
assert(iovec || n == 0);
|
||||
|
||||
/* Returns true if there is nothing else to send (bytes written cover all of the iovec),
|
||||
* false if there's still work to do. */
|
||||
|
||||
bool have = false;
|
||||
FOREACH_ARRAY(j, iovec, n) {
|
||||
size_t sub;
|
||||
|
||||
if (j->iov_len == 0)
|
||||
continue;
|
||||
if (k == 0)
|
||||
return false;
|
||||
|
||||
sub = MIN(j->iov_len, k);
|
||||
j->iov_len -= sub;
|
||||
j->iov_base = (uint8_t*) j->iov_base + sub;
|
||||
size_t sub = MIN(j->iov_len, k);
|
||||
iovec_inc(j, sub);
|
||||
k -= sub;
|
||||
|
||||
have = have || iovec_is_set(j);
|
||||
}
|
||||
|
||||
assert(k == 0); /* Anything else would mean that we wrote more bytes than available,
|
||||
* or the kernel reported writing more bytes than sent. */
|
||||
return true;
|
||||
|
||||
return !have;
|
||||
}
|
||||
|
||||
struct iovec* iovec_make_string(struct iovec *iovec, const char *s) {
|
||||
|
||||
@@ -11,7 +11,7 @@ extern const struct iovec iovec_empty; /* Points to an empty, but valid (i.e.
|
||||
|
||||
size_t iovec_total_size(const struct iovec *iovec, size_t n) _nonnull_if_nonzero_(1, 2);
|
||||
|
||||
bool iovec_increment(struct iovec *iovec, size_t n, size_t k) _nonnull_if_nonzero_(1, 2);
|
||||
bool iovec_inc_many(struct iovec *iovec, size_t n, size_t k) _nonnull_if_nonzero_(1, 2);
|
||||
|
||||
struct iovec* iovec_make_string(struct iovec *iovec, const char *s);
|
||||
|
||||
@@ -38,6 +38,9 @@ char* set_iovec_string_field_free(struct iovec *iovec, size_t *n_iovec, const ch
|
||||
void iovec_array_free(struct iovec *iovec, size_t n_iovec) _nonnull_if_nonzero_(1, 2);
|
||||
|
||||
int iovec_memcmp(const struct iovec *a, const struct iovec *b) _pure_;
|
||||
static inline bool iovec_equal(const struct iovec *a, const struct iovec *b) {
|
||||
return iovec_memcmp(a, b) == 0;
|
||||
}
|
||||
|
||||
struct iovec* iovec_memdup(const struct iovec *source, struct iovec *ret);
|
||||
|
||||
|
||||
+1
-1
@@ -557,7 +557,7 @@ static int write_to_syslog(
|
||||
if (!syslog_is_stream)
|
||||
break;
|
||||
|
||||
if (iovec_increment(iovec, ELEMENTSOF(iovec), n))
|
||||
if (iovec_inc_many(iovec, ELEMENTSOF(iovec), n))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+24
-9
@@ -1099,25 +1099,40 @@ int strdup_to_full(char **ret, const char *src) {
|
||||
}
|
||||
};
|
||||
|
||||
bool string_is_safe(const char *p) {
|
||||
if (!p)
|
||||
bool string_is_safe(const char *p, StringSafeFlags flags) {
|
||||
|
||||
/* Baseline checks are:
|
||||
* • No control characters (i.e. 0…31 + 127)
|
||||
* • UTF-8 valid (well, technically we skip this test if STRING_ASCII is set, since that is a tighter test)
|
||||
*/
|
||||
|
||||
if (FLAGS_SET(flags, STRING_ALLOW_EMPTY) ? !p : isempty(p))
|
||||
return false;
|
||||
|
||||
/* Checks if the specified string contains no quotes or control characters */
|
||||
if (!FLAGS_SET(flags, STRING_ASCII) && !utf8_is_valid(p))
|
||||
return false;
|
||||
|
||||
for (const char *t = p; *t; t++) {
|
||||
if (*t > 0 && *t < ' ') /* no control characters */
|
||||
if ((*t > 0 && *t < ' ') || *t == 0x7f) /* never allow control characters */
|
||||
return false;
|
||||
|
||||
if (strchr(QUOTES "\\\x7f", *t))
|
||||
if (!FLAGS_SET(flags, STRING_ALLOW_BACKSLASHES) && *t == '\\')
|
||||
return false;
|
||||
|
||||
if (!FLAGS_SET(flags, STRING_ALLOW_QUOTES) && strchr(QUOTES, *t))
|
||||
return false;
|
||||
|
||||
if (!FLAGS_SET(flags, STRING_ALLOW_GLOBS) && strchr(GLOB_CHARS, *t))
|
||||
return false;
|
||||
|
||||
if (FLAGS_SET(flags, STRING_ASCII) && (uint8_t) *t >= 0x80)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
if (FLAGS_SET(flags, STRING_FILENAME) && !filename_is_valid(p))
|
||||
return false;
|
||||
|
||||
bool string_is_safe_ascii(const char *p) {
|
||||
return ascii_is_valid(p) && string_is_safe(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
char* str_realloc(char *p) {
|
||||
|
||||
+10
-2
@@ -220,8 +220,16 @@ static inline int strdup_to(char **ret, const char *src) {
|
||||
return r < 0 ? r : 0; /* Suppress return value of 1. */
|
||||
}
|
||||
|
||||
bool string_is_safe(const char *p) _pure_;
|
||||
bool string_is_safe_ascii(const char *p) _pure_;
|
||||
typedef enum StringSafeFlags {
|
||||
STRING_ASCII = 1 << 0, /* Verify string is 7-Bit ASCII (rather than just UTF-8) */
|
||||
STRING_ALLOW_EMPTY = 1 << 1, /* Allow empty strings */
|
||||
STRING_ALLOW_BACKSLASHES = 1 << 2, /* Allow backslashes (\) */
|
||||
STRING_ALLOW_QUOTES = 1 << 3, /* Allow quotes (" or ') */
|
||||
STRING_ALLOW_GLOBS = 1 << 4, /* Allow globs (?, * or [) */
|
||||
STRING_FILENAME = 1 << 5, /* Verify the string is valid as regular filename */
|
||||
} StringSafeFlags;
|
||||
|
||||
bool string_is_safe(const char *p, StringSafeFlags flags) _pure_;
|
||||
|
||||
DISABLE_WARNING_STRINGOP_TRUNCATION;
|
||||
static inline void strncpy_exact(char *buf, const char *src, size_t buf_len) {
|
||||
|
||||
+2
-10
@@ -4,9 +4,7 @@
|
||||
|
||||
#include "sd-id128.h"
|
||||
|
||||
#include "glob-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "path-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "syslog-util.h"
|
||||
@@ -111,7 +109,8 @@ bool log_namespace_name_valid(const char *s) {
|
||||
* (so that /var/log/journal/<machine-id>.<namespace> can be created based on it). Also make sure it
|
||||
* is suitable as unit instance name, and does not contain fishy characters. */
|
||||
|
||||
if (!filename_is_valid(s))
|
||||
/* Let's avoid globbing for now */
|
||||
if (!string_is_safe(s, STRING_FILENAME))
|
||||
return false;
|
||||
|
||||
if (strlen(s) > LOG_NAMESPACE_MAX)
|
||||
@@ -120,12 +119,5 @@ bool log_namespace_name_valid(const char *s) {
|
||||
if (!unit_instance_is_valid(s))
|
||||
return false;
|
||||
|
||||
if (!string_is_safe(s))
|
||||
return false;
|
||||
|
||||
/* Let's avoid globbing for now */
|
||||
if (string_is_glob(s))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -72,6 +72,14 @@ const char* unit_dbus_interface_from_name(const char *name) {
|
||||
return unit_dbus_interface_from_type(t);
|
||||
}
|
||||
|
||||
const char* unit_type_to_capitalized_string(UnitType t) {
|
||||
const char *di = unit_dbus_interface_from_type(t);
|
||||
if (!di)
|
||||
return NULL;
|
||||
|
||||
return ASSERT_PTR(startswith(di, "org.freedesktop.systemd1."));
|
||||
}
|
||||
|
||||
static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
|
||||
[UNIT_SERVICE] = "service",
|
||||
[UNIT_SOCKET] = "socket",
|
||||
|
||||
@@ -321,6 +321,7 @@ void unit_types_list(void);
|
||||
|
||||
DECLARE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState);
|
||||
DECLARE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
|
||||
const char* unit_type_to_capitalized_string(UnitType t);
|
||||
|
||||
DECLARE_STRING_TABLE_LOOKUP(freezer_state, FreezerState);
|
||||
FreezerState freezer_state_finish(FreezerState state) _const_;
|
||||
|
||||
+77
-33
@@ -52,12 +52,11 @@ static char *pad4(char *p, const char *start) {
|
||||
return p;
|
||||
}
|
||||
|
||||
static EFI_STATUS pack_cpio_one(
|
||||
EFI_STATUS pack_cpio_one(
|
||||
const char16_t *fname,
|
||||
const void *contents,
|
||||
size_t contents_size,
|
||||
const char *target_dir_prefix,
|
||||
uint32_t access_mode,
|
||||
const CpioTarget *target,
|
||||
uint32_t *inode_counter,
|
||||
void **cpio_buffer,
|
||||
size_t *cpio_buffer_size) {
|
||||
@@ -67,7 +66,7 @@ static EFI_STATUS pack_cpio_one(
|
||||
|
||||
assert(fname);
|
||||
assert(contents || contents_size == 0);
|
||||
assert(target_dir_prefix);
|
||||
assert(target);
|
||||
assert(inode_counter);
|
||||
assert(cpio_buffer);
|
||||
assert(cpio_buffer_size);
|
||||
@@ -84,7 +83,7 @@ static EFI_STATUS pack_cpio_one(
|
||||
|
||||
l = 6 + 13*8 + 1 + 1; /* Fixed CPIO header size, slash separator, and NUL byte after the file name */
|
||||
|
||||
target_dir_prefix_size = strlen8(target_dir_prefix);
|
||||
target_dir_prefix_size = strlen8(target->directory);
|
||||
if (l > SIZE_MAX - target_dir_prefix_size)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
l += target_dir_prefix_size;
|
||||
@@ -121,11 +120,11 @@ static EFI_STATUS pack_cpio_one(
|
||||
|
||||
a = mempcpy(a, "070701", 6); /* magic ID */
|
||||
|
||||
a = write_cpio_word(a, (*inode_counter)++); /* inode */
|
||||
a = write_cpio_word(a, access_mode | 0100000 /* = S_IFREG */); /* mode */
|
||||
a = write_cpio_word(a, 0); /* uid */
|
||||
a = write_cpio_word(a, 0); /* gid */
|
||||
a = write_cpio_word(a, 1); /* nlink */
|
||||
a = write_cpio_word(a, (*inode_counter)++); /* inode */
|
||||
a = write_cpio_word(a, target->access_mode | 0100000 /* = S_IFREG */); /* mode */
|
||||
a = write_cpio_word(a, 0); /* uid */
|
||||
a = write_cpio_word(a, 0); /* gid */
|
||||
a = write_cpio_word(a, 1); /* nlink */
|
||||
|
||||
/* Note: we don't make any attempt to propagate the mtime here, for two reasons: it's a mess given
|
||||
* that FAT usually is assumed to operate with timezoned timestamps, while UNIX does not. More
|
||||
@@ -141,7 +140,7 @@ static EFI_STATUS pack_cpio_one(
|
||||
a = write_cpio_word(a, target_dir_prefix_size + fname_size + 2); /* fname size */
|
||||
a = write_cpio_word(a, 0); /* "crc" */
|
||||
|
||||
a = mempcpy(a, target_dir_prefix, target_dir_prefix_size);
|
||||
a = mempcpy(a, target->directory, target_dir_prefix_size);
|
||||
*(a++) = '/';
|
||||
a = mangle_filename(a, fname);
|
||||
|
||||
@@ -225,16 +224,15 @@ static EFI_STATUS pack_cpio_dir(
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static EFI_STATUS pack_cpio_prefix(
|
||||
const char *path,
|
||||
uint32_t dir_mode,
|
||||
EFI_STATUS pack_cpio_prefix(
|
||||
const CpioTarget *target,
|
||||
uint32_t *inode_counter,
|
||||
void **cpio_buffer,
|
||||
size_t *cpio_buffer_size) {
|
||||
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(path);
|
||||
assert(target);
|
||||
assert(inode_counter);
|
||||
assert(cpio_buffer);
|
||||
assert(cpio_buffer_size);
|
||||
@@ -243,7 +241,7 @@ static EFI_STATUS pack_cpio_prefix(
|
||||
* (similar to mkdir -p behaviour) all leading paths are created with 0555 access mode, only the
|
||||
* final dir is created with the specified directory access mode. */
|
||||
|
||||
for (const char *p = path;;) {
|
||||
for (const char *p = target->directory;;) {
|
||||
const char *e;
|
||||
|
||||
e = strchr8(p, '/');
|
||||
@@ -253,7 +251,7 @@ static EFI_STATUS pack_cpio_prefix(
|
||||
if (e > p) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
|
||||
t = xstrndup8(path, e - path);
|
||||
t = xstrndup8(target->directory, e - target->directory);
|
||||
if (!t)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
@@ -265,10 +263,10 @@ static EFI_STATUS pack_cpio_prefix(
|
||||
p = e + 1;
|
||||
}
|
||||
|
||||
return pack_cpio_dir(path, dir_mode, inode_counter, cpio_buffer, cpio_buffer_size);
|
||||
return pack_cpio_dir(target->directory, target->dir_mode, inode_counter, cpio_buffer, cpio_buffer_size);
|
||||
}
|
||||
|
||||
static EFI_STATUS pack_cpio_trailer(
|
||||
EFI_STATUS pack_cpio_trailer(
|
||||
void **cpio_buffer,
|
||||
size_t *cpio_buffer_size) {
|
||||
|
||||
@@ -307,9 +305,7 @@ EFI_STATUS pack_cpio(
|
||||
const char16_t *dropin_dir,
|
||||
const char16_t *match_suffix,
|
||||
const char16_t *exclude_suffix,
|
||||
const char *target_dir_prefix,
|
||||
uint32_t dir_mode,
|
||||
uint32_t access_mode,
|
||||
const CpioTarget *target,
|
||||
uint32_t tpm_pcr,
|
||||
const char16_t *tpm_description,
|
||||
struct iovec *ret_buffer,
|
||||
@@ -325,7 +321,7 @@ EFI_STATUS pack_cpio(
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(loaded_image);
|
||||
assert(target_dir_prefix);
|
||||
assert(target);
|
||||
assert(ret_buffer);
|
||||
|
||||
if (!loaded_image->DeviceHandle)
|
||||
@@ -400,7 +396,7 @@ EFI_STATUS pack_cpio(
|
||||
|
||||
/* Generate the leading directory inodes right before adding the first files, to the
|
||||
* archive. Otherwise the cpio archive cannot be unpacked, since the leading dirs won't exist. */
|
||||
err = pack_cpio_prefix(target_dir_prefix, dir_mode, &inode, &buffer, &buffer_size);
|
||||
err = pack_cpio_prefix(target, &inode, &buffer, &buffer_size);
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status(err, "Failed to pack cpio prefix: %m");
|
||||
|
||||
@@ -417,8 +413,7 @@ EFI_STATUS pack_cpio(
|
||||
err = pack_cpio_one(
|
||||
items[i],
|
||||
content, contentsize,
|
||||
target_dir_prefix,
|
||||
access_mode,
|
||||
target,
|
||||
&inode,
|
||||
&buffer, &buffer_size);
|
||||
if (err != EFI_SUCCESS)
|
||||
@@ -453,10 +448,8 @@ nothing:
|
||||
EFI_STATUS pack_cpio_literal(
|
||||
const void *data,
|
||||
size_t data_size,
|
||||
const char *target_dir_prefix,
|
||||
const CpioTarget *target,
|
||||
const char16_t *target_filename,
|
||||
uint32_t dir_mode,
|
||||
uint32_t access_mode,
|
||||
uint32_t tpm_pcr,
|
||||
const char16_t *tpm_description,
|
||||
struct iovec *ret_buffer,
|
||||
@@ -468,22 +461,21 @@ EFI_STATUS pack_cpio_literal(
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(data || data_size == 0);
|
||||
assert(target_dir_prefix);
|
||||
assert(target);
|
||||
assert(target_filename);
|
||||
assert(ret_buffer);
|
||||
|
||||
/* Generate the leading directory inodes right before adding the first files, to the
|
||||
* archive. Otherwise the cpio archive cannot be unpacked, since the leading dirs won't exist. */
|
||||
|
||||
err = pack_cpio_prefix(target_dir_prefix, dir_mode, &inode, &buffer, &buffer_size);
|
||||
err = pack_cpio_prefix(target, &inode, &buffer, &buffer_size);
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status(err, "Failed to pack cpio prefix: %m");
|
||||
|
||||
err = pack_cpio_one(
|
||||
target_filename,
|
||||
data, data_size,
|
||||
target_dir_prefix,
|
||||
access_mode,
|
||||
target,
|
||||
&inode,
|
||||
&buffer, &buffer_size);
|
||||
if (err != EFI_SUCCESS)
|
||||
@@ -505,3 +497,55 @@ EFI_STATUS pack_cpio_literal(
|
||||
*ret_buffer = IOVEC_MAKE(TAKE_PTR(buffer), buffer_size);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* The following are canonical definitions of the various cpio target directories we place resources in. We
|
||||
* define them here in a single canonical list of targets because we need to reuse them at various places
|
||||
* (well, some of them at least), and we don't want the access modes to deviate slightly on each use. */
|
||||
|
||||
const CpioTarget cpio_target_credentials = {
|
||||
.directory = ".extra/credentials",
|
||||
.dir_mode = 0500,
|
||||
.access_mode = 0400,
|
||||
};
|
||||
|
||||
const CpioTarget cpio_target_global_credentials = {
|
||||
.directory = ".extra/global_credentials",
|
||||
.dir_mode = 0500,
|
||||
.access_mode = 0400,
|
||||
};
|
||||
|
||||
const CpioTarget cpio_target_sysext = {
|
||||
.directory = ".extra/sysext",
|
||||
.dir_mode = 0555,
|
||||
.access_mode = 0444,
|
||||
};
|
||||
|
||||
const CpioTarget cpio_target_global_sysext = {
|
||||
.directory = ".extra/global_sysext",
|
||||
.dir_mode = 0555,
|
||||
.access_mode = 0444,
|
||||
};
|
||||
|
||||
const CpioTarget cpio_target_confext = {
|
||||
.directory = ".extra/confext",
|
||||
.dir_mode = 0555,
|
||||
.access_mode = 0444,
|
||||
};
|
||||
|
||||
const CpioTarget cpio_target_global_confext = {
|
||||
.directory = ".extra/global_confext",
|
||||
.dir_mode = 0555,
|
||||
.access_mode = 0444,
|
||||
};
|
||||
|
||||
const CpioTarget cpio_target_meta = {
|
||||
.directory = ".extra",
|
||||
.dir_mode = 0555,
|
||||
.access_mode = 0444,
|
||||
};
|
||||
|
||||
const CpioTarget cpio_target_meta_secret = {
|
||||
.directory = ".extra",
|
||||
.dir_mode = 0555,
|
||||
.access_mode = 0400,
|
||||
};
|
||||
|
||||
+36
-6
@@ -4,14 +4,37 @@
|
||||
#include "efi.h"
|
||||
#include "proto/loaded-image.h"
|
||||
|
||||
typedef struct CpioTarget {
|
||||
const char *directory; /* Path to directory where to place resources */
|
||||
uint32_t dir_mode; /* Access mode for the directory */
|
||||
uint32_t access_mode; /* Access mode for the files in the directory */
|
||||
} CpioTarget;
|
||||
|
||||
EFI_STATUS pack_cpio_one(
|
||||
const char16_t *fname,
|
||||
const void *contents,
|
||||
size_t contents_size,
|
||||
const CpioTarget *target,
|
||||
uint32_t *inode_counter,
|
||||
void **cpio_buffer,
|
||||
size_t *cpio_buffer_size);
|
||||
|
||||
EFI_STATUS pack_cpio_prefix(
|
||||
const CpioTarget *target,
|
||||
uint32_t *inode_counter,
|
||||
void **cpio_buffer,
|
||||
size_t *cpio_buffer_size);
|
||||
|
||||
EFI_STATUS pack_cpio_trailer(
|
||||
void **cpio_buffer,
|
||||
size_t *cpio_buffer_size);
|
||||
|
||||
EFI_STATUS pack_cpio(
|
||||
EFI_LOADED_IMAGE_PROTOCOL *loaded_image,
|
||||
const char16_t *dropin_dir,
|
||||
const char16_t *match_suffix,
|
||||
const char16_t *exclude_suffix,
|
||||
const char *target_dir_prefix,
|
||||
uint32_t dir_mode,
|
||||
uint32_t access_mode,
|
||||
const CpioTarget *target,
|
||||
uint32_t tpm_pcr,
|
||||
const char16_t *tpm_description,
|
||||
struct iovec *ret_buffer,
|
||||
@@ -20,11 +43,18 @@ EFI_STATUS pack_cpio(
|
||||
EFI_STATUS pack_cpio_literal(
|
||||
const void *data,
|
||||
size_t data_size,
|
||||
const char *target_dir_prefix,
|
||||
const CpioTarget *target,
|
||||
const char16_t *target_filename,
|
||||
uint32_t dir_mode,
|
||||
uint32_t access_mode,
|
||||
uint32_t tpm_pcr,
|
||||
const char16_t *tpm_description,
|
||||
struct iovec *ret_buffer,
|
||||
bool *ret_measured);
|
||||
|
||||
extern const CpioTarget cpio_target_credentials;
|
||||
extern const CpioTarget cpio_target_global_credentials;
|
||||
extern const CpioTarget cpio_target_sysext;
|
||||
extern const CpioTarget cpio_target_global_sysext;
|
||||
extern const CpioTarget cpio_target_confext;
|
||||
extern const CpioTarget cpio_target_global_confext;
|
||||
extern const CpioTarget cpio_target_meta;
|
||||
extern const CpioTarget cpio_target_meta_secret;
|
||||
|
||||
+139
-13
@@ -71,8 +71,6 @@ EFI_STATUS initrd_register(
|
||||
EFI_HANDLE *ret_initrd_handle) {
|
||||
|
||||
EFI_STATUS err;
|
||||
EFI_DEVICE_PATH *dp = (EFI_DEVICE_PATH *) &efi_initrd_device_path;
|
||||
EFI_HANDLE handle;
|
||||
|
||||
assert(ret_initrd_handle);
|
||||
|
||||
@@ -82,12 +80,43 @@ EFI_STATUS initrd_register(
|
||||
if (!iovec_is_set(initrd))
|
||||
return EFI_SUCCESS;
|
||||
|
||||
/* Check if a LINUX_INITRD_MEDIA_GUID DevicePath is already registered. LocateDevicePath checks for
|
||||
* the "closest DevicePath" and returns its handle, whereas InstallMultipleProtocolInterfaces() only
|
||||
* matches identical DevicePaths. */
|
||||
err = BS->LocateDevicePath(MAKE_GUID_PTR(EFI_LOAD_FILE2_PROTOCOL), &dp, &handle);
|
||||
if (err != EFI_NOT_FOUND) /* InitrdMedia is already registered */
|
||||
return EFI_ALREADY_STARTED;
|
||||
/* We want to override the LINUX_INITRD_MEDIA device, let's hence first unregister any existing
|
||||
* one. We don't really expect multiple of these to be registered, but who knows? Let's kill all we
|
||||
* can find. */
|
||||
for (unsigned attempt = 0;; attempt++) {
|
||||
|
||||
if (attempt >= 16)
|
||||
return log_debug_status(EFI_DEVICE_ERROR, "Unable to free LINUX_INITRD_MEDIA device path after %u attempts, giving up.", attempt);
|
||||
|
||||
EFI_DEVICE_PATH *dp = (EFI_DEVICE_PATH *) &efi_initrd_device_path;
|
||||
EFI_HANDLE handle = NULL;
|
||||
err = BS->LocateDevicePath(MAKE_GUID_PTR(EFI_LOAD_FILE2_PROTOCOL), &dp, &handle);
|
||||
if (err == EFI_NOT_FOUND) /* Yay! All gone */
|
||||
break;
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_debug_status(err, "Failed to locate LINUX_INITRD_MEDIA device: %m");
|
||||
|
||||
/* Get the *actually* installed pointer for the device path */
|
||||
err = BS->HandleProtocol(handle, MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL), (void**) &dp);
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_debug_status(err, "Failed to acquire DevicePath protocol on LINUX_INITRD_MEDIA device: %m");
|
||||
|
||||
/* Take away the device path protocol */
|
||||
err = BS->UninstallMultipleProtocolInterfaces(
|
||||
handle,
|
||||
MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL), dp,
|
||||
/* sentinel= */ NULL);
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_debug_status(err, "Unable to release DevicePath protocol from old handle: %m");
|
||||
|
||||
/* NB: we leave the handle around (and thus leave the LoadFile2 protocol installed), because
|
||||
* the owner might be unhappy if we destroy it for them. It will no longer have the device
|
||||
* path we want to take possession of on it though. The assumption here is that whoever
|
||||
* registered the device path is OK with the device path being taken away, even if it might
|
||||
* not be OK with the handle being invalidated as a whole. */
|
||||
|
||||
log_debug("Successfully unregistered previous LINUX_INITRD_MEDIA device.");
|
||||
}
|
||||
|
||||
_cleanup_free_ struct initrd_loader *loader = xnew(struct initrd_loader, 1);
|
||||
*loader = (struct initrd_loader) {
|
||||
@@ -122,15 +151,112 @@ EFI_STATUS initrd_unregister(EFI_HANDLE initrd_handle) {
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_debug_status(err, "Failed to acquire LoadFile2 protocol on our own initrd handle: %m");
|
||||
|
||||
/* uninstall all protocols thus destroying the handle */
|
||||
/* We uninstall the DevicePath and the LoadFile2 protocol in separate steps. That's because we want
|
||||
* to gracefully handle the former (because it's OK if something else takes over the device path),
|
||||
* but be strict on the latter, because that's genuinely ours */
|
||||
|
||||
(void) BS->UninstallMultipleProtocolInterfaces(
|
||||
initrd_handle,
|
||||
MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL), &efi_initrd_device_path,
|
||||
/* sentinel= */ NULL);
|
||||
|
||||
/* This second call will also invalidate the handle, because it should be the last protocol on the handle */
|
||||
err = BS->UninstallMultipleProtocolInterfaces(
|
||||
initrd_handle, MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL),
|
||||
&efi_initrd_device_path, MAKE_GUID_PTR(EFI_LOAD_FILE2_PROTOCOL),
|
||||
loader,
|
||||
NULL);
|
||||
initrd_handle,
|
||||
MAKE_GUID_PTR(EFI_LOAD_FILE2_PROTOCOL), loader,
|
||||
/* sentinel= */ NULL);
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_debug_status(err, "Failed to uninstall LoadFile2 protocol from our own initrd handle: %m");
|
||||
|
||||
free(loader);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS initrd_read_previous(struct iovec *ret_initrd) {
|
||||
EFI_STATUS err;
|
||||
|
||||
/* If there's already an initrd registered, read it out, so that we can incorporate it in ours */
|
||||
|
||||
assert(ret_initrd);
|
||||
|
||||
/* Get from the device path to the handle */
|
||||
EFI_DEVICE_PATH *dp = (EFI_DEVICE_PATH *) &efi_initrd_device_path;
|
||||
EFI_HANDLE handle;
|
||||
err = BS->LocateDevicePath(MAKE_GUID_PTR(EFI_LOAD_FILE2_PROTOCOL), &dp, &handle);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Get from the handle to the protocol */
|
||||
EFI_LOAD_FILE2_PROTOCOL *protocol = NULL;
|
||||
err = BS->HandleProtocol(handle, MAKE_GUID_PTR(EFI_LOAD_FILE2_PROTOCOL), (void**) &protocol);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
size_t size = 0;
|
||||
err = protocol->LoadFile(protocol, dp, /* bootPolicy= */ false, &size, /* Buffer= */ NULL);
|
||||
if (err == EFI_SUCCESS) /* Success? Kinda unexpected given we set Buffer to NULL, but it probably
|
||||
* means, that the file is zero-sized, let's treat it as such. */
|
||||
size = 0;
|
||||
else if (err != EFI_BUFFER_TOO_SMALL)
|
||||
return err;
|
||||
|
||||
if (size == 0)
|
||||
return EFI_NOT_FOUND; /* Treat empty initrds like missing ones */
|
||||
|
||||
_cleanup_free_ void *data = xmalloc(size);
|
||||
err = protocol->LoadFile(protocol, dp, /* bootPolicy= */ false, &size, data);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
*ret_initrd = (struct iovec) {
|
||||
.iov_base = TAKE_PTR(data),
|
||||
.iov_len = size,
|
||||
};
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS combine_initrds(
|
||||
const struct iovec initrds[], size_t n_initrds,
|
||||
Pages *ret_initrd_pages, size_t *ret_initrd_size) {
|
||||
|
||||
size_t n = 0;
|
||||
|
||||
/* Combine initrds by concatenation in memory */
|
||||
|
||||
assert(initrds || n_initrds == 0);
|
||||
assert(ret_initrd_pages);
|
||||
assert(ret_initrd_size);
|
||||
|
||||
FOREACH_ARRAY(i, initrds, n_initrds) {
|
||||
/* some initrds (the ones from UKI sections) need padding, pad all to be safe */
|
||||
size_t initrd_size = ALIGN4(i->iov_len);
|
||||
if (n > SIZE_MAX - initrd_size)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
n += initrd_size;
|
||||
}
|
||||
|
||||
_cleanup_pages_ Pages pages = xmalloc_initrd_pages(n);
|
||||
uint8_t *p = PHYSICAL_ADDRESS_TO_POINTER(pages.addr);
|
||||
|
||||
FOREACH_ARRAY(i, initrds, n_initrds) {
|
||||
size_t pad;
|
||||
|
||||
p = mempcpy(p, i->iov_base, i->iov_len);
|
||||
|
||||
pad = ALIGN4(i->iov_len) - i->iov_len;
|
||||
if (pad == 0)
|
||||
continue;
|
||||
|
||||
memzero(p, pad);
|
||||
p += pad;
|
||||
}
|
||||
|
||||
assert(PHYSICAL_ADDRESS_TO_POINTER(pages.addr + n) == p);
|
||||
|
||||
*ret_initrd_pages = TAKE_STRUCT(pages);
|
||||
*ret_initrd_size = n;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "efi.h"
|
||||
#include "iovec-util-fundamental.h"
|
||||
#include "util.h"
|
||||
|
||||
EFI_STATUS initrd_register(
|
||||
const struct iovec *initrd,
|
||||
@@ -13,3 +15,7 @@ static inline void cleanup_initrd(EFI_HANDLE *initrd_handle) {
|
||||
(void) initrd_unregister(*initrd_handle);
|
||||
*initrd_handle = NULL;
|
||||
}
|
||||
|
||||
EFI_STATUS initrd_read_previous(struct iovec *ret_initrd);
|
||||
|
||||
EFI_STATUS combine_initrds(const struct iovec initrds[], size_t n_initrds, Pages *ret_initrd_pages, size_t *ret_initrd_size);
|
||||
|
||||
+39
-81
@@ -10,6 +10,7 @@
|
||||
#include "efi-string.h"
|
||||
#include "export-vars.h"
|
||||
#include "graphics.h"
|
||||
#include "initrd.h"
|
||||
#include "iovec-util-fundamental.h"
|
||||
#include "linux.h"
|
||||
#include "measure.h"
|
||||
@@ -32,13 +33,10 @@
|
||||
|
||||
/* The list of initrds we combine into one, in the order we want to merge them */
|
||||
enum {
|
||||
/* The first two are part of the PE binary */
|
||||
INITRD_UCODE,
|
||||
INITRD_BASE,
|
||||
|
||||
/* The rest are dynamically generated, and hence in dynamic memory */
|
||||
_INITRD_DYNAMIC_FIRST,
|
||||
INITRD_CREDENTIAL = _INITRD_DYNAMIC_FIRST,
|
||||
INITRD_UCODE, /* Part of the PE binary */
|
||||
INITRD_PREVIOUS, /* initrd already configured via the EFI protocol before we were invoked */
|
||||
INITRD_BASE, /* Part of the PE binary */
|
||||
INITRD_CREDENTIAL,
|
||||
INITRD_GLOBAL_CREDENTIAL,
|
||||
INITRD_SYSEXT,
|
||||
INITRD_GLOBAL_SYSEXT,
|
||||
@@ -52,6 +50,8 @@ enum {
|
||||
_INITRD_MAX,
|
||||
};
|
||||
|
||||
#define INITRD_IS_STATIC(idx) IN_SET(idx, INITRD_UCODE, INITRD_BASE)
|
||||
|
||||
/* magic string to find in the binary image */
|
||||
DECLARE_NOALLOC_SECTION(".sdmagic", "#### LoaderInfo: systemd-stub " GIT_VERSION " ####");
|
||||
|
||||
@@ -102,50 +102,6 @@ static void combine_measured_flag(int *value, int measured) {
|
||||
*value = *value < 0 ? measured : *value && measured;
|
||||
}
|
||||
|
||||
/* Combine initrds by concatenation in memory */
|
||||
static EFI_STATUS combine_initrds(
|
||||
const struct iovec initrds[], size_t n_initrds,
|
||||
Pages *ret_initrd_pages, size_t *ret_initrd_size) {
|
||||
|
||||
size_t n = 0;
|
||||
|
||||
assert(initrds || n_initrds == 0);
|
||||
assert(ret_initrd_pages);
|
||||
assert(ret_initrd_size);
|
||||
|
||||
FOREACH_ARRAY(i, initrds, n_initrds) {
|
||||
/* some initrds (the ones from UKI sections) need padding, pad all to be safe */
|
||||
size_t initrd_size = ALIGN4(i->iov_len);
|
||||
if (n > SIZE_MAX - initrd_size)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
n += initrd_size;
|
||||
}
|
||||
|
||||
_cleanup_pages_ Pages pages = xmalloc_initrd_pages(n);
|
||||
uint8_t *p = PHYSICAL_ADDRESS_TO_POINTER(pages.addr);
|
||||
|
||||
FOREACH_ARRAY(i, initrds, n_initrds) {
|
||||
size_t pad;
|
||||
|
||||
p = mempcpy(p, i->iov_base, i->iov_len);
|
||||
|
||||
pad = ALIGN4(i->iov_len) - i->iov_len;
|
||||
if (pad == 0)
|
||||
continue;
|
||||
|
||||
memzero(p, pad);
|
||||
p += pad;
|
||||
}
|
||||
|
||||
assert(PHYSICAL_ADDRESS_TO_POINTER(pages.addr + n) == p);
|
||||
|
||||
*ret_initrd_pages = TAKE_STRUCT(pages);
|
||||
*ret_initrd_size = n;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static void export_stub_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image, unsigned profile) {
|
||||
static const uint64_t stub_features =
|
||||
EFI_STUB_FEATURE_REPORT_BOOT_PARTITION | /* We set LoaderDevicePartUUID */
|
||||
@@ -550,6 +506,21 @@ static void extend_initrds(
|
||||
iovec_array_extend(all_initrds, n_all_initrds, *i);
|
||||
}
|
||||
|
||||
static void acquire_previous_initrd(struct iovec initrds[static _INITRD_MAX]) {
|
||||
EFI_STATUS err;
|
||||
|
||||
/* NB: the assumption here is that any previously installed initrd are measured by whatever
|
||||
* registered them, and we just pass them on here. */
|
||||
|
||||
err = initrd_read_previous(initrds + INITRD_PREVIOUS);
|
||||
if (err == EFI_NOT_FOUND)
|
||||
log_debug_status(err, "No previous initrd registered.");
|
||||
else if (err != EFI_SUCCESS)
|
||||
log_warning_status(err, "Failed to read previously registered initrd, ignoring.");
|
||||
else
|
||||
log_debug("Successfully loaded previously registered initrd (%zu bytes).", initrds[INITRD_PREVIOUS].iov_len);
|
||||
}
|
||||
|
||||
static EFI_STATUS load_addons(
|
||||
EFI_HANDLE stub_image,
|
||||
EFI_LOADED_IMAGE_PROTOCOL *loaded_image,
|
||||
@@ -821,10 +792,11 @@ static void cmdline_append_and_measure_smbios(char16_t **cmdline, int *parameter
|
||||
static void initrds_free(struct iovec (*initrds)[_INITRD_MAX]) {
|
||||
assert(initrds);
|
||||
|
||||
/* Free the dynamic initrds, but leave the non-dynamic ones around */
|
||||
/* Free the non-static initrds, but leave the static (i.e. PE embedded) ones around */
|
||||
|
||||
for (size_t i = _INITRD_DYNAMIC_FIRST; i < _INITRD_MAX; i++)
|
||||
iovec_done((*initrds) + i);
|
||||
for (size_t i = 0; i < _INITRD_MAX; i++)
|
||||
if (!INITRD_IS_STATIC(i))
|
||||
iovec_done((*initrds) + i);
|
||||
}
|
||||
|
||||
static void generate_sidecar_initrds(
|
||||
@@ -846,9 +818,7 @@ static void generate_sidecar_initrds(
|
||||
/* dropin_dir= */ NULL,
|
||||
u".cred",
|
||||
/* exclude_suffix= */ NULL,
|
||||
".extra/credentials",
|
||||
/* dir_mode= */ 0500,
|
||||
/* access_mode= */ 0400,
|
||||
&cpio_target_credentials,
|
||||
/* tpm_pcr= */ TPM2_PCR_KERNEL_CONFIG,
|
||||
u"Credentials initrd",
|
||||
initrds + INITRD_CREDENTIAL,
|
||||
@@ -859,9 +829,7 @@ static void generate_sidecar_initrds(
|
||||
u"\\loader\\credentials",
|
||||
u".cred",
|
||||
/* exclude_suffix= */ NULL,
|
||||
".extra/global_credentials",
|
||||
/* dir_mode= */ 0500,
|
||||
/* access_mode= */ 0400,
|
||||
&cpio_target_global_credentials,
|
||||
/* tpm_pcr= */ TPM2_PCR_KERNEL_CONFIG,
|
||||
u"Global credentials initrd",
|
||||
initrds + INITRD_GLOBAL_CREDENTIAL,
|
||||
@@ -872,9 +840,7 @@ static void generate_sidecar_initrds(
|
||||
/* dropin_dir= */ NULL,
|
||||
u".raw", /* ideally we'd pick up only *.sysext.raw here, but for compat we pick up *.raw instead … */
|
||||
u".confext.raw", /* … but then exclude *.confext.raw again */
|
||||
".extra/sysext",
|
||||
/* dir_mode= */ 0555,
|
||||
/* access_mode= */ 0444,
|
||||
&cpio_target_sysext,
|
||||
/* tpm_pcr= */ TPM2_PCR_SYSEXTS,
|
||||
u"System extension initrd",
|
||||
initrds + INITRD_SYSEXT,
|
||||
@@ -885,9 +851,7 @@ static void generate_sidecar_initrds(
|
||||
u"\\loader\\extensions",
|
||||
u".raw", /* as above */
|
||||
u".confext.raw",
|
||||
".extra/global_sysext",
|
||||
/* dir_mode= */ 0555,
|
||||
/* access_mode= */ 0444,
|
||||
&cpio_target_global_sysext,
|
||||
/* tpm_pcr= */ TPM2_PCR_SYSEXTS,
|
||||
u"Global system extension initrd",
|
||||
initrds + INITRD_GLOBAL_SYSEXT,
|
||||
@@ -898,9 +862,7 @@ static void generate_sidecar_initrds(
|
||||
/* dropin_dir= */ NULL,
|
||||
u".confext.raw",
|
||||
/* exclude_suffix= */ NULL,
|
||||
".extra/confext",
|
||||
/* dir_mode= */ 0555,
|
||||
/* access_mode= */ 0444,
|
||||
&cpio_target_confext,
|
||||
/* tpm_pcr= */ TPM2_PCR_KERNEL_CONFIG,
|
||||
u"Configuration extension initrd",
|
||||
initrds + INITRD_CONFEXT,
|
||||
@@ -911,9 +873,7 @@ static void generate_sidecar_initrds(
|
||||
u"\\loader\\extensions",
|
||||
u".confext.raw",
|
||||
/* exclude_suffix= */ NULL,
|
||||
".extra/global_confext",
|
||||
/* dir_mode= */ 0555,
|
||||
/* access_mode= */ 0444,
|
||||
&cpio_target_global_confext,
|
||||
/* tpm_pcr= */ TPM2_PCR_KERNEL_CONFIG,
|
||||
u"Global configuration extension initrd",
|
||||
initrds + INITRD_GLOBAL_CONFEXT,
|
||||
@@ -964,10 +924,8 @@ static void generate_embedded_initrds(
|
||||
(void) pack_cpio_literal(
|
||||
(const uint8_t*) loaded_image->ImageBase + sections[t->section].memory_offset,
|
||||
sections[t->section].memory_size,
|
||||
".extra",
|
||||
&cpio_target_meta,
|
||||
t->filename,
|
||||
/* dir_mode= */ 0555,
|
||||
/* access_mode= */ 0444,
|
||||
/* tpm_pcr= */ UINT32_MAX,
|
||||
/* tpm_description= */ NULL,
|
||||
initrds + t->initrd_index,
|
||||
@@ -988,10 +946,8 @@ static void generate_boot_secret_initrd(
|
||||
(void) pack_cpio_literal(
|
||||
boot_secret,
|
||||
BOOT_SECRET_SIZE,
|
||||
".extra",
|
||||
&cpio_target_meta_secret,
|
||||
u"boot-secret",
|
||||
/* dir_mode= */ 0555,
|
||||
/* access_mode= */ 0400,
|
||||
/* tpm_pcr= */ UINT32_MAX,
|
||||
/* tpm_description= */ NULL,
|
||||
initrds + INITRD_BOOT_SECRET,
|
||||
@@ -1309,6 +1265,7 @@ static EFI_STATUS run(EFI_HANDLE image) {
|
||||
install_addon_devicetrees(&dt_state, dt_addons, n_dt_addons, ¶meters_measured);
|
||||
|
||||
/* Generate & find all initrds */
|
||||
acquire_previous_initrd(initrds);
|
||||
generate_sidecar_initrds(loaded_image, initrds, ¶meters_measured, &sysext_measured, &confext_measured);
|
||||
generate_embedded_initrds(loaded_image, sections, initrds);
|
||||
generate_boot_secret_initrd(boot_secret, initrds);
|
||||
@@ -1319,9 +1276,10 @@ static EFI_STATUS run(EFI_HANDLE image) {
|
||||
* We want addons to take precedence over the base initrds, so the order is:
|
||||
* 1. Ucode addons
|
||||
* 2. UKI ucode
|
||||
* 3. UKI initrd
|
||||
* 4. Generated initrds
|
||||
* 5. initrd addons */
|
||||
* 3. Previous initrds
|
||||
* 4. UKI initrd
|
||||
* 5. Generated initrds
|
||||
* 6. initrd addons */
|
||||
measure_and_append_ucode_addons(&all_initrds, &n_all_initrds, ucode_addons, n_ucode_addons, ¶meters_measured);
|
||||
extend_initrds(initrds, &all_initrds, &n_all_initrds);
|
||||
measure_and_append_initrd_addons(&all_initrds, &n_all_initrds, initrd_addons, n_initrd_addons, ¶meters_measured);
|
||||
|
||||
+14
-4
@@ -15,6 +15,7 @@
|
||||
#include "bootctl-status.h"
|
||||
#include "bootctl-uki.h"
|
||||
#include "bootctl-unlink.h"
|
||||
#include "bootctl-util.h"
|
||||
#include "build.h"
|
||||
#include "devnum-util.h"
|
||||
#include "dissect-image.h"
|
||||
@@ -38,7 +39,6 @@
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "utf8.h"
|
||||
#include "varlink-io.systemd.BootControl.h"
|
||||
#include "varlink-util.h"
|
||||
#include "verbs.h"
|
||||
@@ -52,6 +52,7 @@ bool arg_print_esp_path = false;
|
||||
bool arg_print_dollar_boot_path = false;
|
||||
bool arg_print_loader_path = false;
|
||||
bool arg_print_stub_path = false;
|
||||
bool arg_print_efi_architecture = false;
|
||||
unsigned arg_print_root_device = 0;
|
||||
int arg_touch_variables = -1;
|
||||
bool arg_install_random_seed = true;
|
||||
@@ -450,6 +451,10 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
|
||||
arg_print_root_device++;
|
||||
break;
|
||||
|
||||
OPTION_LONG("print-efi-architecture", NULL, "Print the local EFI architecture string"):
|
||||
arg_print_efi_architecture = true;
|
||||
break;
|
||||
|
||||
OPTION_GROUP("Options"):
|
||||
break;
|
||||
|
||||
@@ -567,7 +572,7 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
|
||||
|
||||
OPTION_LONG("efi-boot-option-description", "DESCRIPTION",
|
||||
"Description of the entry in the boot option list"):
|
||||
if (isempty(arg) || !(string_is_safe(arg) && utf8_is_valid(arg))) {
|
||||
if (!string_is_safe(arg, STRING_ALLOW_BACKSLASHES|STRING_ALLOW_QUOTES|STRING_ALLOW_GLOBS)) {
|
||||
_cleanup_free_ char *escaped = cescape(arg);
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Invalid --efi-boot-option-description=: %s", strna(escaped));
|
||||
@@ -639,9 +644,9 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
|
||||
|
||||
char **args = option_parser_get_args(&state);
|
||||
|
||||
if (!!arg_print_esp_path + !!arg_print_dollar_boot_path + (arg_print_root_device > 0) + arg_print_loader_path + arg_print_stub_path > 1)
|
||||
if (!!arg_print_esp_path + !!arg_print_dollar_boot_path + (arg_print_root_device > 0) + arg_print_loader_path + arg_print_stub_path + arg_print_efi_architecture > 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"--print-esp-path/-p, --print-boot-path/-x, --print-root-device=/-R, --print-loader-path, --print-stub-path cannot be combined.");
|
||||
"--print-esp-path/-p, --print-boot-path/-x, --print-root-device=/-R, --print-loader-path, --print-stub-path, --print-efi-architecture cannot be combined.");
|
||||
|
||||
if ((arg_root || arg_image) && args[0] && !STR_IN_SET(args[0], "status", "list",
|
||||
"install", "update", "remove", "is-installed", "random-seed", "unlink", "cleanup"))
|
||||
@@ -761,6 +766,11 @@ static int run(int argc, char *argv[]) {
|
||||
if (arg_print_loader_path || arg_print_stub_path)
|
||||
return print_loader_or_stub_path();
|
||||
|
||||
if (arg_print_efi_architecture) {
|
||||
printf("%s\n", get_efi_arch());
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Open up and mount the image */
|
||||
if (arg_image) {
|
||||
assert(!arg_root);
|
||||
|
||||
@@ -24,6 +24,7 @@ extern bool arg_print_dollar_boot_path;
|
||||
extern bool arg_print_loader_path;
|
||||
extern bool arg_print_stub_path;
|
||||
extern unsigned arg_print_root_device;
|
||||
extern bool arg_print_efi_architecture;
|
||||
extern int arg_touch_variables;
|
||||
extern bool arg_install_random_seed;
|
||||
extern PagerFlags arg_pager_flags;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
---
|
||||
InheritParentConfig: true
|
||||
Checks: '-misc-use-internal-linkage'
|
||||
CheckOptions:
|
||||
misc-include-cleaner.IgnoreHeaders: 'errno\.h'
|
||||
...
|
||||
@@ -0,0 +1,5 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
Diagnostics:
|
||||
Includes:
|
||||
IgnoreHeader: [errno\.h]
|
||||
+3
-2
@@ -7,12 +7,13 @@
|
||||
* fine given that LGPL-2.1-or-later downgrades to GPL if needed.
|
||||
*/
|
||||
|
||||
#include "bpf-dlopen.h" /* IWYU pragma: keep */
|
||||
#include "bpf-dlopen.h" /* IWYU pragma: keep */
|
||||
|
||||
/* libbpf is used via dlopen(), so rename symbols */
|
||||
#define bpf_object__attach_skeleton sym_bpf_object__attach_skeleton
|
||||
#define bpf_object__destroy_skeleton sym_bpf_object__destroy_skeleton
|
||||
#define bpf_object__detach_skeleton sym_bpf_object__detach_skeleton
|
||||
#define bpf_object__load_skeleton sym_bpf_object__load_skeleton
|
||||
#define bpf_object__open_skeleton sym_bpf_object__open_skeleton
|
||||
|
||||
#include "bpf/userns-restrict/userns-restrict.skel.h" /* IWYU pragma: export */
|
||||
#include "@NAME@.bpf.skel.h" /* IWYU pragma: export */
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main() -> int:
|
||||
build_root = os.environ['MESON_BUILD_ROOT']
|
||||
|
||||
sep = sys.argv.index('--')
|
||||
sources = sys.argv[1:sep]
|
||||
command = sys.argv[sep + 1:]
|
||||
|
||||
db_path = os.path.join(build_root, 'compile_commands.json')
|
||||
try:
|
||||
with open(db_path) as f:
|
||||
db = json.load(f)
|
||||
except FileNotFoundError:
|
||||
db = []
|
||||
|
||||
sources_set = set(sources)
|
||||
db = [entry for entry in db if entry['file'] not in sources_set]
|
||||
|
||||
for source in sources:
|
||||
db.append({
|
||||
'directory': build_root,
|
||||
'file': source,
|
||||
'arguments': [source if a == '@INPUT@' else a for a in command],
|
||||
})
|
||||
|
||||
with open(db_path, 'w') as f:
|
||||
json.dump(db, f, indent=2)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,397 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
if not libbpf.found()
|
||||
conf.set10('BPF_FRAMEWORK', false)
|
||||
else
|
||||
clang_found = false
|
||||
clang_supports_bpf = false
|
||||
bpf_gcc_found = false
|
||||
bpftool_strip = false
|
||||
deps_found = false
|
||||
|
||||
if bpf_compiler == 'clang'
|
||||
# Support 'versioned' clang/llvm-strip binaries, as seen on Debian/Ubuntu
|
||||
# (like clang-10/llvm-strip-10)
|
||||
if meson.is_cross_build() or cc.get_id() != 'clang' or cc.cmd_array()[0].contains('afl-clang') or cc.cmd_array()[0].contains('hfuzz-clang')
|
||||
r = find_program('clang',
|
||||
required : bpf_framework,
|
||||
version : '>= 10.0.0')
|
||||
clang_found = r.found()
|
||||
if clang_found
|
||||
clang = r.full_path()
|
||||
endif
|
||||
else
|
||||
clang_found = true
|
||||
clang = cc.cmd_array()
|
||||
endif
|
||||
|
||||
if clang_found
|
||||
# Check if 'clang -target bpf' is supported.
|
||||
clang_supports_bpf = run_command(clang, '-target', 'bpf', '--print-supported-cpus', check : false).returncode() == 0
|
||||
endif
|
||||
if bpf_framework.enabled() and not clang_supports_bpf
|
||||
error('bpf-framework was enabled but clang does not support bpf')
|
||||
endif
|
||||
elif bpf_compiler == 'gcc'
|
||||
bpf_gcc = find_program('bpf-gcc',
|
||||
'bpf-none-gcc',
|
||||
'bpf-unknown-none-gcc',
|
||||
required : true,
|
||||
version : '>= 13.1.0')
|
||||
bpf_gcc_found = bpf_gcc.found()
|
||||
endif
|
||||
|
||||
if clang_supports_bpf or bpf_gcc_found
|
||||
# Debian installs this in /usr/sbin/ which is not in $PATH.
|
||||
# We check for 'bpftool' first, honouring $PATH, and in /usr/sbin/ for Debian.
|
||||
# We use 'bpftool gen object' subcommand for bpftool strip, it was added by d80b2fcbe0a023619e0fc73112f2a02c2662f6ab (v5.13).
|
||||
bpftool = find_program('bpftool',
|
||||
'/usr/sbin/bpftool',
|
||||
required : bpf_framework.enabled() and bpf_compiler == 'gcc',
|
||||
version : bpf_compiler == 'gcc' ? '>= 7.0.0' : '>= 5.13.0')
|
||||
|
||||
if bpftool.found()
|
||||
bpftool_strip = true
|
||||
deps_found = true
|
||||
elif bpf_compiler == 'clang'
|
||||
# We require the 'bpftool gen skeleton' subcommand, it was added by 985ead416df39d6fe8e89580cc1db6aa273e0175 (v5.6).
|
||||
bpftool = find_program('bpftool',
|
||||
'/usr/sbin/bpftool',
|
||||
required : bpf_framework,
|
||||
version : '>= 5.6.0')
|
||||
endif
|
||||
|
||||
# We use `llvm-strip` as a fallback if `bpftool gen object` strip support is not available.
|
||||
if not bpftool_strip and bpftool.found() and clang_supports_bpf
|
||||
if not meson.is_cross_build()
|
||||
llvm_strip_bin = run_command(clang, '--print-prog-name', 'llvm-strip',
|
||||
check : true).stdout().strip()
|
||||
else
|
||||
llvm_strip_bin = 'llvm-strip'
|
||||
endif
|
||||
llvm_strip = find_program(llvm_strip_bin,
|
||||
required : bpf_framework,
|
||||
version : '>= 10.0.0')
|
||||
deps_found = llvm_strip.found()
|
||||
endif
|
||||
endif
|
||||
|
||||
# Can build BPF program from source code in restricted C
|
||||
conf.set10('BPF_FRAMEWORK', deps_found)
|
||||
endif
|
||||
|
||||
if conf.get('BPF_FRAMEWORK') == 1
|
||||
bpf_clang_flags = [
|
||||
'-std=gnu17',
|
||||
'-Wno-compare-distinct-pointer-types',
|
||||
'-Wno-microsoft-anon-tag',
|
||||
'-fms-extensions',
|
||||
'-fno-stack-protector',
|
||||
'-O2',
|
||||
'-target',
|
||||
'bpf',
|
||||
'-g',
|
||||
'-c',
|
||||
]
|
||||
|
||||
bpf_gcc_flags = [
|
||||
'-std=gnu17',
|
||||
'-fms-extensions',
|
||||
'-fno-stack-protector',
|
||||
'-fno-ssa-phiopt',
|
||||
'-O2',
|
||||
'-mcpu=v3',
|
||||
'-mco-re',
|
||||
'-gbtf',
|
||||
'-c',
|
||||
]
|
||||
|
||||
# If c_args contains these flags copy them along with the values, in order to avoid breaking
|
||||
# reproducible builds and other functionality
|
||||
propagate_cflags = [
|
||||
'-ffile-prefix-map=',
|
||||
'-fdebug-prefix-map=',
|
||||
'-fmacro-prefix-map=',
|
||||
'--sysroot=',
|
||||
]
|
||||
|
||||
foreach opt : c_args
|
||||
foreach flag : propagate_cflags
|
||||
if opt.startswith(flag)
|
||||
bpf_clang_flags += [opt]
|
||||
bpf_gcc_flags += [opt]
|
||||
break
|
||||
endif
|
||||
endforeach
|
||||
endforeach
|
||||
|
||||
# Generate defines that are appropriate to tell the compiler what architecture
|
||||
# we're compiling for. By default we just map meson's cpu_family to __<cpu_family>__.
|
||||
# This dictionary contains the exceptions where this doesn't work.
|
||||
#
|
||||
# C.f. https://mesonbuild.com/Reference-tables.html#cpu-families
|
||||
# and src/basic/missing_syscall_def.h.
|
||||
|
||||
# Start with older ABI. When define is missing, we're likely targeting that.
|
||||
ppc64_elf_version = '1'
|
||||
|
||||
if host_machine.cpu_family() == 'ppc64'
|
||||
# cc doesn't have to be bpf_compiler, but they should be targeting the same ABI
|
||||
call_elf_value = cc.get_define('_CALL_ELF')
|
||||
if call_elf_value != ''
|
||||
ppc64_elf_version = call_elf_value
|
||||
endif
|
||||
endif
|
||||
|
||||
cpu_arch_defines = {
|
||||
'ppc' : ['-D__powerpc__', '-D__TARGET_ARCH_powerpc'],
|
||||
'ppc64' : ['-D__powerpc64__', '-D__TARGET_ARCH_powerpc', '-D_CALL_ELF=' + ppc64_elf_version],
|
||||
'riscv32' : ['-D__riscv', '-D__riscv_xlen=32', '-D__TARGET_ARCH_riscv'],
|
||||
'riscv64' : ['-D__riscv', '-D__riscv_xlen=64', '-D__TARGET_ARCH_riscv'],
|
||||
'x86' : ['-D__i386__', '-D__TARGET_ARCH_x86'],
|
||||
's390x' : ['-D__s390__', '-D__s390x__', '-D__TARGET_ARCH_s390'],
|
||||
|
||||
# For arm, assume hardware fp is available.
|
||||
'arm' : ['-D__arm__', '-D__ARM_PCS_VFP', '-D__TARGET_ARCH_arm'],
|
||||
'loongarch64' : ['-D__loongarch__', '-D__loongarch_grlen=64', '-D__TARGET_ARCH_loongarch']
|
||||
}
|
||||
|
||||
bpf_arch_flags = cpu_arch_defines.get(host_machine.cpu_family(),
|
||||
['-D__@0@__'.format(host_machine.cpu_family())])
|
||||
if bpf_compiler == 'gcc'
|
||||
bpf_arch_flags += ['-m' + host_machine.endian() + '-endian']
|
||||
endif
|
||||
|
||||
libbpf_include_dir = libbpf.get_variable(pkgconfig : 'includedir')
|
||||
|
||||
bpf_o_unstripped_cmd = []
|
||||
if bpf_compiler == 'clang'
|
||||
bpf_o_unstripped_cmd += [
|
||||
clang,
|
||||
bpf_clang_flags,
|
||||
bpf_arch_flags,
|
||||
]
|
||||
elif bpf_compiler == 'gcc'
|
||||
bpf_o_unstripped_cmd += [
|
||||
bpf_gcc,
|
||||
bpf_gcc_flags,
|
||||
bpf_arch_flags,
|
||||
]
|
||||
endif
|
||||
|
||||
bpf_o_unstripped_cmd += ['-I.', '-include', 'config.h']
|
||||
|
||||
if cc.get_id() == 'gcc' or meson.is_cross_build()
|
||||
if cc.get_id() != 'gcc'
|
||||
warning('Cross compiler is not gcc. Guessing the target triplet for bpf likely fails.')
|
||||
endif
|
||||
target_triplet_cmd = run_command(cc.cmd_array(), '-print-multiarch', check: false)
|
||||
else
|
||||
# clang does not support -print-multiarch (D133170) and its -dump-machine
|
||||
# does not match multiarch. Query gcc instead.
|
||||
target_triplet_cmd = run_command('gcc', '-print-multiarch', check: false)
|
||||
endif
|
||||
if target_triplet_cmd.returncode() == 0
|
||||
sysroot = meson.get_external_property('sys_root', '/')
|
||||
target_triplet = target_triplet_cmd.stdout().strip()
|
||||
target_include_dir = sysroot / 'usr' / 'include'
|
||||
target_triple_include_dir = target_include_dir / target_triplet
|
||||
isystem_dir = ''
|
||||
if fs.is_dir(target_triple_include_dir)
|
||||
isystem_dir = target_triple_include_dir
|
||||
elif fs.is_dir(target_include_dir)
|
||||
isystem_dir = target_include_dir
|
||||
endif
|
||||
if isystem_dir != ''
|
||||
bpf_o_unstripped_cmd += [
|
||||
'-isystem', isystem_dir
|
||||
]
|
||||
endif
|
||||
endif
|
||||
|
||||
bpf_o_unstripped_cmd += [
|
||||
'-idirafter',
|
||||
libbpf_include_dir,
|
||||
'@INPUT@',
|
||||
'-o',
|
||||
'@OUTPUT@'
|
||||
]
|
||||
|
||||
if bpftool_strip
|
||||
bpf_o_cmd = [
|
||||
bpftool,
|
||||
'gen',
|
||||
'object',
|
||||
'@OUTPUT@',
|
||||
'@INPUT@'
|
||||
]
|
||||
elif bpf_compiler == 'clang'
|
||||
bpf_o_cmd = [
|
||||
llvm_strip,
|
||||
'-g',
|
||||
'@INPUT@',
|
||||
'-o',
|
||||
'@OUTPUT@'
|
||||
]
|
||||
endif
|
||||
|
||||
skel_h_cmd = [
|
||||
bpftool,
|
||||
'gen',
|
||||
'skeleton',
|
||||
'@INPUT@'
|
||||
]
|
||||
endif
|
||||
|
||||
use_provided_vmlinux_h = false
|
||||
use_generated_vmlinux_h = false
|
||||
provided_vmlinux_h_path = get_option('vmlinux-h-path')
|
||||
|
||||
# For the more complex BPF programs we really want a vmlinux.h (which is arch
|
||||
# specific, but only somewhat bound to kernel version). Ideally the kernel
|
||||
# development headers would ship that, but right now they don't. Hence address
|
||||
# this in two ways:
|
||||
#
|
||||
# 1. Provide a vmlinux.h at build time
|
||||
# 2. Generate the file on the fly where possible (which requires /sys/ to be mounted)
|
||||
#
|
||||
# We generally prefer the former (to support reproducible builds), but will
|
||||
# fallback to the latter.
|
||||
|
||||
if conf.get('BPF_FRAMEWORK') == 1
|
||||
enable_vmlinux_h = get_option('vmlinux-h')
|
||||
|
||||
if enable_vmlinux_h == 'auto'
|
||||
if provided_vmlinux_h_path != ''
|
||||
use_provided_vmlinux_h = true
|
||||
elif fs.exists('/sys/kernel/btf/vmlinux') and \
|
||||
bpftool.found() and \
|
||||
(host_machine.cpu_family() == build_machine.cpu_family()) and \
|
||||
host_machine.cpu_family() in ['x86_64', 'aarch64']
|
||||
|
||||
# We will only generate a vmlinux.h from the running
|
||||
# kernel if the host and build machine are of the same
|
||||
# family. Also for now we focus on x86_64 and aarch64,
|
||||
# since other archs don't seem to be ready yet.
|
||||
|
||||
use_generated_vmlinux_h = true
|
||||
endif
|
||||
elif enable_vmlinux_h == 'provided'
|
||||
use_provided_vmlinux_h = true
|
||||
elif enable_vmlinux_h == 'generated'
|
||||
if not fs.exists('/sys/kernel/btf/vmlinux')
|
||||
error('BTF data from kernel not available (/sys/kernel/btf/vmlinux missing), cannot generate vmlinux.h, but was asked to.')
|
||||
endif
|
||||
if not bpftool.found()
|
||||
error('bpftool not available, cannot generate vmlinux.h, but was asked to.')
|
||||
endif
|
||||
use_generated_vmlinux_h = true
|
||||
endif
|
||||
endif
|
||||
|
||||
vmlinux_h_dependency = []
|
||||
if use_provided_vmlinux_h
|
||||
if not fs.exists(provided_vmlinux_h_path)
|
||||
error('Path to provided vmlinux.h does not exist.')
|
||||
endif
|
||||
bpf_o_unstripped_cmd += ['-I' + fs.parent(provided_vmlinux_h_path)]
|
||||
message(f'Using provided @provided_vmlinux_h_path@')
|
||||
elif use_generated_vmlinux_h
|
||||
vmlinux_h_dependency = custom_target(
|
||||
output: 'vmlinux.h',
|
||||
command : [ bpftool, 'btf', 'dump', 'file', '/sys/kernel/btf/vmlinux', 'format', 'c' ],
|
||||
capture : true)
|
||||
|
||||
bpf_o_unstripped_cmd += ['-I' + fs.parent(vmlinux_h_dependency.full_path())]
|
||||
generated_sources += vmlinux_h_dependency
|
||||
message('Using generated @0@'.format(vmlinux_h_dependency.full_path()))
|
||||
else
|
||||
message('Using neither provided nor generated vmlinux.h, some features will not be available.')
|
||||
endif
|
||||
|
||||
conf.set10('HAVE_VMLINUX_H', use_provided_vmlinux_h or use_generated_vmlinux_h)
|
||||
|
||||
conf.set10('ENABLE_SYSCTL_BPF', conf.get('HAVE_VMLINUX_H') == 1 and libbpf.version().version_compare('>= 0.7'))
|
||||
|
||||
bpf_programs = [
|
||||
{
|
||||
'source' : files('bind-iface.bpf.c'),
|
||||
'condition' : 'BPF_FRAMEWORK',
|
||||
},
|
||||
{
|
||||
'source' : files('restrict-fs.bpf.c'),
|
||||
'condition' : 'BPF_FRAMEWORK',
|
||||
},
|
||||
{
|
||||
'source' : files('restrict-ifaces.bpf.c'),
|
||||
'condition' : 'BPF_FRAMEWORK',
|
||||
},
|
||||
{
|
||||
'source' : files('socket-bind.bpf.c'),
|
||||
'condition' : 'BPF_FRAMEWORK',
|
||||
},
|
||||
{
|
||||
'source' : files('sysctl-monitor.bpf.c'),
|
||||
'condition' : 'ENABLE_SYSCTL_BPF',
|
||||
'depends' : vmlinux_h_dependency,
|
||||
},
|
||||
{
|
||||
'source' : files('userns-restrict.bpf.c'),
|
||||
'condition' : 'HAVE_VMLINUX_H',
|
||||
'depends' : vmlinux_h_dependency,
|
||||
},
|
||||
]
|
||||
|
||||
bpf_programs_by_name = {}
|
||||
bpf_sources = []
|
||||
|
||||
foreach program : bpf_programs
|
||||
if conf.get(program['condition']) != 1
|
||||
continue
|
||||
endif
|
||||
|
||||
source = program['source'][0]
|
||||
# Strip .bpf.c extension
|
||||
name = fs.stem(fs.stem(source))
|
||||
|
||||
bpf_o_unstripped = custom_target(
|
||||
input : source,
|
||||
output : name + '.bpf.unstripped.o',
|
||||
command : bpf_o_unstripped_cmd,
|
||||
depends : program.get('depends', []))
|
||||
|
||||
bpf_o = custom_target(
|
||||
input : bpf_o_unstripped,
|
||||
output : name + '.bpf.o',
|
||||
command : bpf_o_cmd)
|
||||
|
||||
skel_h = custom_target(
|
||||
input : bpf_o,
|
||||
output : name + '.bpf.skel.h',
|
||||
command : skel_h_cmd,
|
||||
capture : true)
|
||||
|
||||
# The wrapper is written at meson setup time and found via the
|
||||
# include path, so we don't need to list it as a build-time source.
|
||||
# Keeping it out of bpf_programs_by_name also keeps it out of the
|
||||
# clang-tidy per-source test loop, which would otherwise fall back
|
||||
# to a BPF compile_commands.json entry (no -Isrc/shared) and fail
|
||||
# to resolve bpf-dlopen.h.
|
||||
configure_file(
|
||||
input : 'bpf-skel-wrapper.h.in',
|
||||
output : name + '-skel.h',
|
||||
configuration : { 'NAME' : name })
|
||||
|
||||
bpf_programs_by_name += { name : skel_h }
|
||||
generated_sources += skel_h
|
||||
bpf_sources += source
|
||||
endforeach
|
||||
|
||||
if bpf_sources.length() > 0
|
||||
meson.add_postconf_script(
|
||||
python,
|
||||
files('merge-bpf-compdb.py'),
|
||||
bpf_sources,
|
||||
'--',
|
||||
bpf_o_unstripped_cmd)
|
||||
endif
|
||||
@@ -2,6 +2,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __bpf__
|
||||
#include "vmlinux.h"
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifndef TASK_COMM_LEN
|
||||
#define TASK_COMM_LEN 16
|
||||
#endif
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "vmlinux.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <errno.h> /* IWYU pragma: keep */
|
||||
#include <bpf/bpf_core_read.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_tracing.h>
|
||||
@@ -14,7 +14,7 @@
|
||||
/* libbpf, clang, llvm and bpftool compile time dependencies are satisfied */
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-link.h"
|
||||
#include "bpf/bind-iface/bind-iface-skel.h"
|
||||
#include "bind-iface-skel.h"
|
||||
|
||||
static struct bind_iface_bpf *bind_iface_bpf_free(struct bind_iface_bpf *obj) {
|
||||
bind_iface_bpf__destroy(obj);
|
||||
@@ -31,7 +31,7 @@ int bpf_bind_network_interface_supported(void) {
|
||||
if (supported >= 0)
|
||||
return supported;
|
||||
|
||||
if (dlopen_bpf_full(LOG_WARNING) < 0)
|
||||
if (dlopen_bpf(LOG_WARNING) < 0)
|
||||
return (supported = false);
|
||||
|
||||
obj = bind_iface_bpf__open();
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
/* libbpf, clang and llc compile time dependencies are satisfied */
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-link.h"
|
||||
#include "bpf/restrict-fs/restrict-fs-skel.h"
|
||||
#include "restrict-fs-skel.h"
|
||||
|
||||
#define CGROUP_HASH_SIZE_MAX 2048
|
||||
|
||||
@@ -91,7 +91,7 @@ bool bpf_restrict_fs_supported(bool initialize) {
|
||||
if (!initialize)
|
||||
return false;
|
||||
|
||||
if (dlopen_bpf_full(LOG_WARNING) < 0)
|
||||
if (dlopen_bpf(LOG_WARNING) < 0)
|
||||
return (supported = false);
|
||||
|
||||
r = lsm_supported("bpf");
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-link.h"
|
||||
#include "bpf/restrict-ifaces/restrict-ifaces-skel.h"
|
||||
#include "restrict-ifaces-skel.h"
|
||||
|
||||
static struct restrict_ifaces_bpf *restrict_ifaces_bpf_free(struct restrict_ifaces_bpf *obj) {
|
||||
restrict_ifaces_bpf__destroy(obj);
|
||||
@@ -86,7 +86,7 @@ int bpf_restrict_ifaces_supported(void) {
|
||||
if (supported >= 0)
|
||||
return supported;
|
||||
|
||||
if (dlopen_bpf_full(LOG_WARNING) < 0)
|
||||
if (dlopen_bpf(LOG_WARNING) < 0)
|
||||
return (supported = false);
|
||||
|
||||
r = prepare_restrict_ifaces_bpf(NULL, true, NULL, &obj);
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
/* libbpf, clang, llvm and bpftool compile time dependencies are satisfied */
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-link.h"
|
||||
#include "bpf/socket-bind/socket-bind-api.bpf.h"
|
||||
#include "bpf/socket-bind/socket-bind-skel.h"
|
||||
#include "socket-bind-api.bpf.h"
|
||||
#include "socket-bind-skel.h"
|
||||
|
||||
static struct socket_bind_bpf *socket_bind_bpf_free(struct socket_bind_bpf *obj) {
|
||||
/* socket_bind_bpf__destroy handles object == NULL case */
|
||||
@@ -125,7 +125,7 @@ int bpf_socket_bind_supported(void) {
|
||||
_cleanup_(socket_bind_bpf_freep) struct socket_bind_bpf *obj = NULL;
|
||||
int r;
|
||||
|
||||
if (dlopen_bpf_full(LOG_WARNING) < 0)
|
||||
if (dlopen_bpf(LOG_WARNING) < 0)
|
||||
return false;
|
||||
|
||||
r = prepare_socket_bind_bpf(/* unit= */ NULL, /* allow_rules= */ NULL, /* deny_rules= */ NULL, &obj);
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
/* The SPDX header above is actually correct in claiming this was
|
||||
* LGPL-2.1-or-later, because it is. Since the kernel doesn't consider that
|
||||
* compatible with GPL we will claim this to be GPL however, which should be
|
||||
* fine given that LGPL-2.1-or-later downgrades to GPL if needed.
|
||||
*/
|
||||
|
||||
#include "bpf-dlopen.h" /* IWYU pragma: keep */
|
||||
|
||||
/* libbpf is used via dlopen(), so rename symbols */
|
||||
#define bpf_object__open_skeleton sym_bpf_object__open_skeleton
|
||||
#define bpf_object__load_skeleton sym_bpf_object__load_skeleton
|
||||
#define bpf_object__destroy_skeleton sym_bpf_object__destroy_skeleton
|
||||
|
||||
#include "bpf/bind-iface/bind-iface.skel.h" /* IWYU pragma: export */
|
||||
@@ -1,23 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
if conf.get('BPF_FRAMEWORK') != 1
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
bind_network_interface_bpf_o_unstripped = custom_target(
|
||||
input : 'bind-iface.bpf.c',
|
||||
output : 'bind-iface.bpf.unstripped.o',
|
||||
command : bpf_o_unstripped_cmd)
|
||||
|
||||
bind_network_interface_bpf_o = custom_target(
|
||||
input : bind_network_interface_bpf_o_unstripped,
|
||||
output : 'bind-iface.bpf.o',
|
||||
command : bpf_o_cmd)
|
||||
|
||||
bind_network_interface_skel_h = custom_target(
|
||||
input : bind_network_interface_bpf_o,
|
||||
output : 'bind-iface.skel.h',
|
||||
command : skel_h_cmd,
|
||||
capture : true)
|
||||
|
||||
generated_sources += bind_network_interface_skel_h
|
||||
@@ -1,23 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
if conf.get('BPF_FRAMEWORK') != 1
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
restrict_fs_bpf_o_unstripped = custom_target(
|
||||
input : 'restrict-fs.bpf.c',
|
||||
output : 'restrict-fs.bpf.unstripped.o',
|
||||
command : bpf_o_unstripped_cmd)
|
||||
|
||||
restrict_fs_bpf_o = custom_target(
|
||||
input : restrict_fs_bpf_o_unstripped,
|
||||
output : 'restrict-fs.bpf.o',
|
||||
command : bpf_o_cmd)
|
||||
|
||||
restrict_fs_skel_h = custom_target(
|
||||
input : restrict_fs_bpf_o,
|
||||
output : 'restrict-fs.skel.h',
|
||||
command : skel_h_cmd,
|
||||
capture : true)
|
||||
|
||||
generated_sources += restrict_fs_skel_h
|
||||
@@ -1,17 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
/* The SPDX header above is actually correct in claiming this was
|
||||
* LGPL-2.1-or-later, because it is. Since the kernel doesn't consider that
|
||||
* compatible with GPL we will claim this to be GPL however, which should be
|
||||
* fine given that LGPL-2.1-or-later downgrades to GPL if needed.
|
||||
*/
|
||||
|
||||
#include "bpf-dlopen.h" /* IWYU pragma: keep */
|
||||
|
||||
/* libbpf is used via dlopen(), so rename symbols */
|
||||
#define bpf_object__open_skeleton sym_bpf_object__open_skeleton
|
||||
#define bpf_object__load_skeleton sym_bpf_object__load_skeleton
|
||||
#define bpf_object__destroy_skeleton sym_bpf_object__destroy_skeleton
|
||||
|
||||
#include "bpf/restrict-fs/restrict-fs.skel.h" /* IWYU pragma: export */
|
||||
@@ -1,23 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
if conf.get('BPF_FRAMEWORK') != 1
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
restrict_ifaces_bpf_o_unstripped = custom_target(
|
||||
input : 'restrict-ifaces.bpf.c',
|
||||
output : 'restrict-ifaces.bpf.unstripped.o',
|
||||
command : bpf_o_unstripped_cmd)
|
||||
|
||||
restrict_ifaces_bpf_o = custom_target(
|
||||
input : restrict_ifaces_bpf_o_unstripped,
|
||||
output : 'restrict-ifaces.bpf.o',
|
||||
command : bpf_o_cmd)
|
||||
|
||||
restrict_ifaces_skel_h = custom_target(
|
||||
input : restrict_ifaces_bpf_o,
|
||||
output : 'restrict-ifaces.skel.h',
|
||||
command : skel_h_cmd,
|
||||
capture : true)
|
||||
|
||||
generated_sources += restrict_ifaces_skel_h
|
||||
@@ -1,17 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
/* The SPDX header above is actually correct in claiming this was
|
||||
* LGPL-2.1-or-later, because it is. Since the kernel doesn't consider that
|
||||
* compatible with GPL we will claim this to be GPL however, which should be
|
||||
* fine given that LGPL-2.1-or-later downgrades to GPL if needed.
|
||||
*/
|
||||
|
||||
#include "bpf-dlopen.h" /* IWYU pragma: keep */
|
||||
|
||||
/* libbpf is used via dlopen(), so rename symbols */
|
||||
#define bpf_object__open_skeleton sym_bpf_object__open_skeleton
|
||||
#define bpf_object__load_skeleton sym_bpf_object__load_skeleton
|
||||
#define bpf_object__destroy_skeleton sym_bpf_object__destroy_skeleton
|
||||
|
||||
#include "bpf/restrict-ifaces/restrict-ifaces.skel.h" /* IWYU pragma: export */
|
||||
@@ -1,23 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
if conf.get('BPF_FRAMEWORK') != 1
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
socket_bind_bpf_o_unstripped = custom_target(
|
||||
input : 'socket-bind.bpf.c',
|
||||
output : 'socket-bind.bpf.unstripped.o',
|
||||
command : bpf_o_unstripped_cmd)
|
||||
|
||||
socket_bind_bpf_o = custom_target(
|
||||
input : socket_bind_bpf_o_unstripped,
|
||||
output : 'socket-bind.bpf.o',
|
||||
command : bpf_o_cmd)
|
||||
|
||||
socket_bind_skel_h = custom_target(
|
||||
input : socket_bind_bpf_o,
|
||||
output : 'socket-bind.skel.h',
|
||||
command : skel_h_cmd,
|
||||
capture : true)
|
||||
|
||||
generated_sources += socket_bind_skel_h
|
||||
@@ -1,17 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
/* The SPDX header above is actually correct in claiming this was
|
||||
* LGPL-2.1-or-later, because it is. Since the kernel doesn't consider that
|
||||
* compatible with GPL we will claim this to be GPL however, which should be
|
||||
* fine given that LGPL-2.1-or-later downgrades to GPL if needed.
|
||||
*/
|
||||
|
||||
#include "bpf-dlopen.h" /* IWYU pragma: keep */
|
||||
|
||||
/* libbpf is used via dlopen(), so rename symbols */
|
||||
#define bpf_object__open_skeleton sym_bpf_object__open_skeleton
|
||||
#define bpf_object__load_skeleton sym_bpf_object__load_skeleton
|
||||
#define bpf_object__destroy_skeleton sym_bpf_object__destroy_skeleton
|
||||
|
||||
#include "bpf/socket-bind/socket-bind.skel.h" /* IWYU pragma: export */
|
||||
@@ -387,13 +387,16 @@ static int property_set_pretimeout_watchdog_governor(
|
||||
sd_bus_error *reterr_error) {
|
||||
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
char *governor;
|
||||
const char *governor;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_read(value, "s", &governor);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (!string_is_safe(governor))
|
||||
|
||||
if (isempty(governor))
|
||||
governor = NULL;
|
||||
else if (!string_is_safe(governor, /* flags= */ 0))
|
||||
return -EINVAL;
|
||||
|
||||
return manager_override_watchdog_pretimeout_governor(m, governor);
|
||||
|
||||
@@ -1359,9 +1359,9 @@ static int setup_pam(
|
||||
* parent process will exec() the actual daemon. We do things this way to ensure that the main PID of
|
||||
* the daemon is the one we initially fork()ed. */
|
||||
|
||||
r = dlopen_libpam();
|
||||
r = dlopen_libpam(LOG_ERR);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "PAM support not available: %m");
|
||||
return r;
|
||||
|
||||
r = barrier_create(&barrier);
|
||||
if (r < 0)
|
||||
@@ -1625,7 +1625,7 @@ static bool seccomp_allows_drop_privileges(const ExecContext *c) {
|
||||
assert(c);
|
||||
|
||||
/* No libseccomp, all is fine */
|
||||
if (dlopen_libseccomp() < 0)
|
||||
if (dlopen_libseccomp(LOG_DEBUG) < 0)
|
||||
return true;
|
||||
|
||||
/* No syscall filter, we are allowed to drop privileges */
|
||||
@@ -1927,7 +1927,7 @@ static int apply_restrict_filesystems(const ExecContext *c, const ExecParameters
|
||||
}
|
||||
|
||||
/* We are in a new binary, so dl-open again */
|
||||
r = dlopen_bpf();
|
||||
r = dlopen_bpf(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -6026,10 +6026,10 @@ int exec_invoke(
|
||||
}
|
||||
|
||||
/* Load a bunch of libraries we'll possibly need later, before we turn off dlopen() */
|
||||
(void) dlopen_bpf();
|
||||
(void) dlopen_cryptsetup();
|
||||
(void) dlopen_libmount();
|
||||
(void) dlopen_libseccomp();
|
||||
(void) dlopen_bpf(LOG_DEBUG);
|
||||
(void) dlopen_cryptsetup(LOG_DEBUG);
|
||||
(void) dlopen_libmount(LOG_DEBUG);
|
||||
(void) dlopen_libseccomp(LOG_DEBUG);
|
||||
|
||||
/* Let's now disable further dlopen()ing of libraries, since we are about to do namespace
|
||||
* shenanigans, and do not want to mix resources from host and namespace */
|
||||
|
||||
+3
-3
@@ -1491,7 +1491,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
|
||||
fputc('~', f);
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
if (dlopen_libseccomp() >= 0) {
|
||||
if (dlopen_libseccomp(LOG_DEBUG) >= 0) {
|
||||
void *id, *val;
|
||||
bool first = true;
|
||||
HASHMAP_FOREACH_KEY(val, id, c->syscall_filter) {
|
||||
@@ -1910,7 +1910,7 @@ char** exec_context_get_syscall_filter(const ExecContext *c) {
|
||||
assert(c);
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
if (dlopen_libseccomp() < 0)
|
||||
if (dlopen_libseccomp(LOG_DEBUG) < 0)
|
||||
return strv_new(NULL);
|
||||
|
||||
void *id, *val;
|
||||
@@ -1979,7 +1979,7 @@ char** exec_context_get_syscall_log(const ExecContext *c) {
|
||||
assert(c);
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
if (dlopen_libseccomp() < 0)
|
||||
if (dlopen_libseccomp(LOG_DEBUG) < 0)
|
||||
return strv_new(NULL);
|
||||
|
||||
void *id, *val;
|
||||
|
||||
@@ -990,7 +990,7 @@ int config_parse_exec(
|
||||
ignore ? ", ignoring" : "", rvalue);
|
||||
return ignore ? 0 : -ENOEXEC;
|
||||
}
|
||||
if (!string_is_safe(path)) {
|
||||
if (!string_is_safe(path, /* flags= */ 0)) {
|
||||
log_syntax(unit, ignore ? LOG_WARNING : LOG_ERR, filename, line, 0,
|
||||
"Executable path contains special characters%s: %s",
|
||||
ignore ? ", ignoring" : "", path);
|
||||
|
||||
+2
-2
@@ -502,7 +502,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!string_is_safe(value)) {
|
||||
if (!string_is_safe(value, /* flags= */ 0)) {
|
||||
log_warning("Watchdog pretimeout governor '%s' is not valid, ignoring.", value);
|
||||
return 0;
|
||||
}
|
||||
@@ -3378,7 +3378,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
/* Building without libmount is allowed, but if it is compiled in, then we must be able to load it */
|
||||
r = dlopen_libmount();
|
||||
r = dlopen_libmount(LOG_DEBUG);
|
||||
if (r < 0 && !ERRNO_IS_NEG_NOT_SUPPORTED(r)) {
|
||||
error_message = "Failed to load libmount.so";
|
||||
goto finish;
|
||||
|
||||
+10
-6
@@ -3576,12 +3576,14 @@ int manager_set_watchdog_pretimeout_governor(Manager *m, const char *governor) {
|
||||
if (MANAGER_IS_USER(m))
|
||||
return 0;
|
||||
|
||||
governor = empty_to_null(governor);
|
||||
|
||||
if (streq_ptr(m->watchdog_pretimeout_governor, governor))
|
||||
return 0;
|
||||
|
||||
p = strdup(governor);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
r = strdup_to(&p, governor);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = watchdog_setup_pretimeout_governor(governor);
|
||||
if (r < 0)
|
||||
@@ -3599,12 +3601,14 @@ int manager_override_watchdog_pretimeout_governor(Manager *m, const char *govern
|
||||
if (MANAGER_IS_USER(m))
|
||||
return 0;
|
||||
|
||||
governor = empty_to_null(governor);
|
||||
|
||||
if (streq_ptr(m->watchdog_pretimeout_governor_overridden, governor))
|
||||
return 0;
|
||||
|
||||
p = strdup(governor);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
r = strdup_to(&p, governor);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = watchdog_setup_pretimeout_governor(governor);
|
||||
if (r < 0)
|
||||
|
||||
+6
-10
@@ -64,26 +64,22 @@ libcore_sources = files(
|
||||
'unit-serialize.c',
|
||||
'unit.c',
|
||||
'varlink.c',
|
||||
'varlink-automount.c',
|
||||
'varlink-cgroup.c',
|
||||
'varlink-common.c',
|
||||
'varlink-dynamic-user.c',
|
||||
'varlink-execute.c',
|
||||
'varlink-kill.c',
|
||||
'varlink-manager.c',
|
||||
'varlink-metrics.c',
|
||||
'varlink-mount.c',
|
||||
'varlink-unit.c',
|
||||
)
|
||||
|
||||
subdir('bpf/socket-bind')
|
||||
subdir('bpf/restrict-fs')
|
||||
subdir('bpf/restrict-ifaces')
|
||||
subdir('bpf/bind-iface')
|
||||
|
||||
if conf.get('BPF_FRAMEWORK') == 1
|
||||
libcore_sources += [
|
||||
socket_bind_skel_h,
|
||||
restrict_fs_skel_h,
|
||||
restrict_ifaces_skel_h,
|
||||
bind_network_interface_skel_h]
|
||||
foreach name : ['socket-bind', 'restrict-fs', 'restrict-ifaces', 'bind-iface']
|
||||
libcore_sources += bpf_programs_by_name[name]
|
||||
endforeach
|
||||
endif
|
||||
|
||||
sources += libcore_sources
|
||||
|
||||
+1
-1
@@ -2408,7 +2408,7 @@ static int mount_test_startable(Unit *u) {
|
||||
}
|
||||
|
||||
static bool mount_supported(void) {
|
||||
return dlopen_libmount() >= 0;
|
||||
return dlopen_libmount(LOG_DEBUG) >= 0;
|
||||
}
|
||||
|
||||
static int mount_subsystem_ratelimited(Manager *m) {
|
||||
|
||||
@@ -1049,7 +1049,7 @@ static bool verity_has_later_duplicates(MountList *ml, const MountEntry *needle)
|
||||
for (const MountEntry *m = needle + 1; m < ml->mounts + ml->n_mounts; m++) {
|
||||
if (m->mode != MOUNT_EXTENSION_IMAGE)
|
||||
continue;
|
||||
if (iovec_memcmp(&m->verity.root_hash, &needle->verity.root_hash) == 0)
|
||||
if (iovec_equal(&m->verity.root_hash, &needle->verity.root_hash))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3984,7 +3984,7 @@ int refresh_extensions_in_namespace(
|
||||
if (r > 0)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Target namespace is not separate, cannot reload extensions");
|
||||
|
||||
(void) dlopen_cryptsetup();
|
||||
(void) dlopen_cryptsetup(LOG_DEBUG);
|
||||
|
||||
extension_dir = path_join(p->private_namespace_dir, "unit-extensions");
|
||||
if (!extension_dir)
|
||||
|
||||
@@ -17,11 +17,9 @@ int mac_selinux_setup(bool *loaded_policy) {
|
||||
|
||||
assert(loaded_policy);
|
||||
|
||||
r = dlopen_libselinux();
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "No SELinux library available, skipping setup.");
|
||||
r = dlopen_libselinux(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
mac_selinux_disable_logging();
|
||||
|
||||
|
||||
+1
-1
@@ -5210,7 +5210,7 @@ static void service_notify_message(
|
||||
|
||||
e = empty_to_null(e);
|
||||
|
||||
if (e && !string_is_safe_ascii(e)) {
|
||||
if (e && !string_is_safe(e, STRING_ASCII)) {
|
||||
_cleanup_free_ char *escaped = cescape(e);
|
||||
log_unit_warning(u, "Got invalid %s string, ignoring: %s", i->tag, strna(escaped));
|
||||
} else if (free_and_strdup_warn(status_error, e) > 0)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "sd-json.h"
|
||||
|
||||
#include "automount.h"
|
||||
#include "json-util.h"
|
||||
#include "varlink-automount.h"
|
||||
|
||||
int automount_context_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
Automount *a = ASSERT_PTR(AUTOMOUNT(userdata));
|
||||
return sd_json_buildo(
|
||||
ASSERT_PTR(ret),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("Where", a->where),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("ExtraOptions", a->extra_options),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("DirectoryMode", a->directory_mode),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("TimeoutIdleUSec", a->timeout_idle_usec));
|
||||
}
|
||||
|
||||
int automount_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
Automount *a = ASSERT_PTR(AUTOMOUNT(userdata));
|
||||
return sd_json_buildo(ASSERT_PTR(ret), JSON_BUILD_PAIR_ENUM("Result", automount_result_to_string(a->result)));
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "core-forward.h"
|
||||
|
||||
int automount_context_build_json(sd_json_variant **ret, const char *name, void *userdata);
|
||||
int automount_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata);
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "bus-common-errors.h"
|
||||
#include "cpu-set-util.h"
|
||||
#include "execute.h"
|
||||
#include "json-util.h"
|
||||
#include "rlimit-util.h"
|
||||
#include "varlink-common.h"
|
||||
@@ -104,3 +105,24 @@ empty:
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exec_command_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
ExecCommand *cmd = ASSERT_PTR(userdata);
|
||||
|
||||
assert(ret);
|
||||
|
||||
if (isempty(cmd->path)) {
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sd_json_buildo(
|
||||
ret,
|
||||
SD_JSON_BUILD_PAIR_STRING("path", cmd->path),
|
||||
JSON_BUILD_PAIR_STRV_NON_EMPTY("arguments", cmd->argv),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("ignoreFailure", FLAGS_SET(cmd->flags, EXEC_COMMAND_IGNORE_FAILURE)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("privileged", FLAGS_SET(cmd->flags, EXEC_COMMAND_FULLY_PRIVILEGED)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("noSetuid", FLAGS_SET(cmd->flags, EXEC_COMMAND_NO_SETUID)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("noEnvExpand", FLAGS_SET(cmd->flags, EXEC_COMMAND_NO_ENV_EXPAND)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("viaShell", FLAGS_SET(cmd->flags, EXEC_COMMAND_VIA_SHELL)));
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
int rlimit_build_json(sd_json_variant **ret, const char *name, void *userdata);
|
||||
int rlimit_table_build_json(sd_json_variant **ret, const char *name, void *userdata);
|
||||
int cpuset_build_json(sd_json_variant **ret, const char *name, void *userdata);
|
||||
|
||||
const char* varlink_error_id_from_bus_error(const sd_bus_error *e);
|
||||
int exec_command_build_json(sd_json_variant **ret, const char *name, void *userdata);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "sd-json.h"
|
||||
|
||||
#include "json-util.h"
|
||||
#include "kill.h"
|
||||
#include "signal-util.h"
|
||||
#include "varlink-kill.h"
|
||||
|
||||
int unit_kill_context_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
KillContext *c = userdata;
|
||||
|
||||
assert(ret);
|
||||
|
||||
if (!c) {
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sd_json_buildo(
|
||||
ret,
|
||||
JSON_BUILD_PAIR_ENUM("KillMode", kill_mode_to_string(c->kill_mode)),
|
||||
SD_JSON_BUILD_PAIR_STRING("KillSignal", signal_to_string(c->kill_signal)),
|
||||
SD_JSON_BUILD_PAIR_STRING("RestartKillSignal", signal_to_string(restart_kill_signal(c))),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("SendSIGHUP", c->send_sighup),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("SendSIGKILL", c->send_sigkill),
|
||||
SD_JSON_BUILD_PAIR_STRING("FinalKillSignal", signal_to_string(c->final_kill_signal)),
|
||||
SD_JSON_BUILD_PAIR_STRING("WatchdogSignal", signal_to_string(c->watchdog_signal)));
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "core-forward.h"
|
||||
|
||||
int unit_kill_context_build_json(sd_json_variant **ret, const char *name, void *userdata);
|
||||
@@ -0,0 +1,55 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "sd-json.h"
|
||||
|
||||
#include "json-util.h"
|
||||
#include "mount.h"
|
||||
#include "user-util.h"
|
||||
#include "varlink-common.h"
|
||||
#include "varlink-mount.h"
|
||||
|
||||
int mount_context_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
Mount *m = ASSERT_PTR(MOUNT(userdata));
|
||||
_cleanup_free_ char *what = NULL, *where = NULL, *options = NULL;
|
||||
|
||||
what = mount_get_what_escaped(m);
|
||||
if (!what)
|
||||
return -ENOMEM;
|
||||
|
||||
where = mount_get_where_escaped(m);
|
||||
if (!where)
|
||||
return -ENOMEM;
|
||||
|
||||
options = mount_get_options_escaped(m);
|
||||
if (!options)
|
||||
return -ENOMEM;
|
||||
|
||||
return sd_json_buildo(
|
||||
ASSERT_PTR(ret),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("What", what),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("Where", where),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("Type", mount_get_fstype(m)),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("Options", options),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("SloppyOptions", m->sloppy_options),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("LazyUnmount", m->lazy_unmount),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("ReadWriteOnly", m->read_write_only),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("ForceUnmount", m->force_unmount),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("DirectoryMode", m->directory_mode),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("TimeoutUSec", m->timeout_usec),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecMount", exec_command_build_json, &m->exec_command[MOUNT_EXEC_MOUNT]),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecUnmount", exec_command_build_json, &m->exec_command[MOUNT_EXEC_UNMOUNT]),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExecRemount", exec_command_build_json, &m->exec_command[MOUNT_EXEC_REMOUNT]));
|
||||
}
|
||||
|
||||
int mount_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
Mount *m = ASSERT_PTR(MOUNT(u));
|
||||
return sd_json_buildo(
|
||||
ASSERT_PTR(ret),
|
||||
SD_JSON_BUILD_PAIR_CONDITION(pidref_is_set(&m->control_pid), "ControlPID", JSON_BUILD_PIDREF(&m->control_pid)),
|
||||
JSON_BUILD_PAIR_ENUM("Result", mount_result_to_string(m->result)),
|
||||
JSON_BUILD_PAIR_ENUM("ReloadResult", mount_result_to_string(m->reload_result)),
|
||||
JSON_BUILD_PAIR_ENUM("CleanResult", mount_result_to_string(m->clean_result)),
|
||||
SD_JSON_BUILD_PAIR_CONDITION(uid_is_valid(u->ref_uid), "UID", SD_JSON_BUILD_UNSIGNED(u->ref_uid)),
|
||||
SD_JSON_BUILD_PAIR_CONDITION(gid_is_valid(u->ref_gid), "GID", SD_JSON_BUILD_UNSIGNED(u->ref_gid)));
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "core-forward.h"
|
||||
|
||||
int mount_context_build_json(sd_json_variant **ret, const char *name, void *userdata);
|
||||
int mount_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata);
|
||||
+20
-13
@@ -18,8 +18,11 @@
|
||||
#include "set.h"
|
||||
#include "strv.h"
|
||||
#include "unit.h"
|
||||
#include "varlink-automount.h"
|
||||
#include "varlink-cgroup.h"
|
||||
#include "varlink-execute.h"
|
||||
#include "varlink-kill.h"
|
||||
#include "varlink-mount.h"
|
||||
#include "varlink-unit.h"
|
||||
#include "varlink-util.h"
|
||||
|
||||
@@ -112,6 +115,12 @@ static int unit_context_build_json(sd_json_variant **ret, const char *name, void
|
||||
* If it make sense to place a property into a config/unit file it belongs to Context.
|
||||
* Otherwise it's a 'Runtime'. */
|
||||
|
||||
/* TODO missing callbacks */
|
||||
static const sd_json_build_callback_t unit_type_callbacks[_UNIT_TYPE_MAX] = {
|
||||
[UNIT_AUTOMOUNT] = automount_context_build_json,
|
||||
[UNIT_MOUNT] = mount_context_build_json,
|
||||
};
|
||||
|
||||
return sd_json_buildo(
|
||||
ASSERT_PTR(ret),
|
||||
SD_JSON_BUILD_PAIR_STRING("Type", unit_type_to_string(u->type)),
|
||||
@@ -189,18 +198,9 @@ static int unit_context_build_json(sd_json_variant **ret, const char *name, void
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("DebugInvocation", u->debug_invocation),
|
||||
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("CGroup", unit_cgroup_context_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Exec", unit_exec_context_build_json, u));
|
||||
|
||||
// TODO follow up PRs:
|
||||
// JSON_BUILD_PAIR_CALLBACK_NON_NULL("Exec", exec_context_build_json, u)
|
||||
// JSON_BUILD_PAIR_CALLBACK_NON_NULL("Kill", kill_context_build_json, u)
|
||||
// Mount/Automount context
|
||||
// Path context
|
||||
// Scope context
|
||||
// Swap context
|
||||
// Timer context
|
||||
// Service context
|
||||
// Socket context
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Exec", unit_exec_context_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Kill", unit_kill_context_build_json, unit_get_kill_context(u)),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL(unit_type_to_capitalized_string(u->type), unit_type_callbacks[u->type], u));
|
||||
}
|
||||
|
||||
static int can_clean_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
@@ -280,6 +280,12 @@ static int unit_runtime_build_json(sd_json_variant **ret, const char *name, void
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
Unit *f = unit_following(u);
|
||||
|
||||
/* TODO missing callbacks */
|
||||
static const sd_json_build_callback_t unit_type_callbacks[_UNIT_TYPE_MAX] = {
|
||||
[UNIT_AUTOMOUNT] = automount_runtime_build_json,
|
||||
[UNIT_MOUNT] = mount_runtime_build_json,
|
||||
};
|
||||
|
||||
return sd_json_buildo(
|
||||
ASSERT_PTR(ret),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("Following", f ? f->id : NULL),
|
||||
@@ -309,7 +315,8 @@ static int unit_runtime_build_json(sd_json_variant **ret, const char *name, void
|
||||
SD_JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(u->invocation_id), "InvocationID", SD_JSON_BUILD_UUID(u->invocation_id)),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Markers", markers_build_json, &u->markers),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("ActivationDetails", activation_details_build_json, u->activation_details),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("CGroup", unit_cgroup_runtime_build_json, u));
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("CGroup", unit_cgroup_runtime_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL(unit_type_to_capitalized_string(u->type), unit_type_callbacks[u->type], u));
|
||||
}
|
||||
|
||||
static int list_unit_one(sd_varlink *link, Unit *unit) {
|
||||
|
||||
+1
-1
@@ -188,7 +188,7 @@ static int is_tmpfs_with_noswap(dev_t devno) {
|
||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
||||
int r;
|
||||
|
||||
r = dlopen_libmount();
|
||||
r = dlopen_libmount(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ int load_volume_key_fido2(
|
||||
if (passphrase_size < 0)
|
||||
return log_oom();
|
||||
|
||||
r = crypt_volume_key_get(
|
||||
r = sym_crypt_volume_key_get(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
ret_vk,
|
||||
@@ -95,9 +95,9 @@ int enroll_fido2(
|
||||
assert_se(iovec_is_set(volume_key));
|
||||
assert_se(device);
|
||||
|
||||
assert_se(node = crypt_get_device_name(cd));
|
||||
assert_se(node = sym_crypt_get_device_name(cd));
|
||||
|
||||
un = strempty(crypt_get_uuid(cd));
|
||||
un = strempty(sym_crypt_get_uuid(cd));
|
||||
|
||||
if (salt_file)
|
||||
r = fido2_read_salt_file(
|
||||
@@ -140,7 +140,7 @@ int enroll_fido2(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set minimal PBKDF: %m");
|
||||
|
||||
keyslot = crypt_keyslot_add_by_volume_key(
|
||||
keyslot = sym_crypt_keyslot_add_by_volume_key(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
volume_key->iov_base,
|
||||
|
||||
@@ -26,11 +26,11 @@ int list_enrolled(struct crypt_device *cd) {
|
||||
assert(cd);
|
||||
|
||||
/* First step, find out all currently used slots */
|
||||
assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
assert_se((slot_max = sym_crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
for (int slot = 0; slot < slot_max; slot++) {
|
||||
crypt_keyslot_info status;
|
||||
|
||||
status = crypt_keyslot_status(cd, slot);
|
||||
status = sym_crypt_keyslot_status(cd, slot);
|
||||
if (!IN_SET(status, CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ int load_volume_key_password(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to acquire password from environment: %m");
|
||||
if (r > 0) {
|
||||
r = crypt_volume_key_get(
|
||||
r = sym_crypt_volume_key_get(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
ret_vk,
|
||||
@@ -81,7 +81,7 @@ int load_volume_key_password(
|
||||
|
||||
r = -EPERM;
|
||||
STRV_FOREACH(p, passwords) {
|
||||
r = crypt_volume_key_get(
|
||||
r = sym_crypt_volume_key_get(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
ret_vk,
|
||||
@@ -114,7 +114,7 @@ int enroll_password(
|
||||
assert(cd);
|
||||
assert(iovec_is_set(volume_key));
|
||||
|
||||
assert_se(node = crypt_get_device_name(cd));
|
||||
assert_se(node = sym_crypt_get_device_name(cd));
|
||||
|
||||
r = getenv_steal_erase("NEWPASSWORD", &new_password);
|
||||
if (r < 0)
|
||||
@@ -123,7 +123,7 @@ int enroll_password(
|
||||
_cleanup_free_ char *disk_path = NULL, *id = NULL;
|
||||
unsigned i = 5;
|
||||
|
||||
assert_se(node = crypt_get_device_name(cd));
|
||||
assert_se(node = sym_crypt_get_device_name(cd));
|
||||
|
||||
(void) suggest_passwords();
|
||||
|
||||
@@ -196,7 +196,7 @@ int enroll_password(
|
||||
else if (r == 0)
|
||||
log_warning("Specified password does not pass quality checks (%s), proceeding anyway.", error);
|
||||
|
||||
keyslot = crypt_keyslot_add_by_volume_key(
|
||||
keyslot = sym_crypt_keyslot_add_by_volume_key(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
volume_key->iov_base,
|
||||
|
||||
@@ -53,7 +53,7 @@ int enroll_pkcs11(struct crypt_device *cd, const struct iovec *volume_key,const
|
||||
assert_se(iovec_is_set(volume_key));
|
||||
assert_se(uri);
|
||||
|
||||
assert_se(node = crypt_get_device_name(cd));
|
||||
assert_se(node = sym_crypt_get_device_name(cd));
|
||||
|
||||
r = pkcs11_acquire_public_key(
|
||||
uri,
|
||||
@@ -80,7 +80,7 @@ int enroll_pkcs11(struct crypt_device *cd, const struct iovec *volume_key,const
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set minimal PBKDF: %m");
|
||||
|
||||
int keyslot = crypt_keyslot_add_by_volume_key(
|
||||
int keyslot = sym_crypt_keyslot_add_by_volume_key(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
volume_key->iov_base,
|
||||
|
||||
@@ -24,7 +24,7 @@ int enroll_recovery(
|
||||
assert_se(cd);
|
||||
assert_se(iovec_is_set(volume_key));
|
||||
|
||||
assert_se(node = crypt_get_device_name(cd));
|
||||
assert_se(node = sym_crypt_get_device_name(cd));
|
||||
|
||||
r = make_recovery_key(&password);
|
||||
if (r < 0)
|
||||
@@ -34,7 +34,7 @@ int enroll_recovery(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set minimal PBKDF: %m");
|
||||
|
||||
keyslot = crypt_keyslot_add_by_volume_key(
|
||||
keyslot = sym_crypt_keyslot_add_by_volume_key(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
volume_key->iov_base,
|
||||
@@ -93,7 +93,7 @@ int enroll_recovery(
|
||||
return keyslot;
|
||||
|
||||
rollback:
|
||||
q = crypt_keyslot_destroy(cd, keyslot);
|
||||
q = sym_crypt_keyslot_destroy(cd, keyslot);
|
||||
if (q < 0)
|
||||
log_debug_errno(q, "Unable to remove key slot we just added again, can't rollback, sorry: %m");
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ static int search_policy_hash(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Invalid hex data in 'tpm2-policy-hash' field item : %m");
|
||||
|
||||
if (iovec_memcmp(policy_hash + j, &thash) != 0) {
|
||||
if (!iovec_equal(policy_hash + j, &thash)) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
@@ -91,7 +91,7 @@ static int search_policy_hash(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Invalid hex data in 'tpm2-policy-hash' field: %m");
|
||||
|
||||
if (iovec_memcmp(policy_hash + 0, &thash) == 0)
|
||||
if (iovec_equal(policy_hash + 0, &thash))
|
||||
return keyslot; /* Found entry with same hash. */
|
||||
}
|
||||
}
|
||||
@@ -272,7 +272,7 @@ int load_volume_key_tpm2(
|
||||
if (passphrase_size < 0)
|
||||
return log_oom();
|
||||
|
||||
r = crypt_volume_key_get(
|
||||
r = sym_crypt_volume_key_get(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
ret_vk,
|
||||
@@ -329,7 +329,7 @@ int enroll_tpm2(struct crypt_device *cd,
|
||||
assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask));
|
||||
assert(ret_slot_to_wipe);
|
||||
|
||||
assert_se(node = crypt_get_device_name(cd));
|
||||
assert_se(node = sym_crypt_get_device_name(cd));
|
||||
|
||||
if (use_pin) {
|
||||
r = get_pin(&pin_str, &flags);
|
||||
@@ -566,7 +566,7 @@ int enroll_tpm2(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to unseal secret using TPM2: %m");
|
||||
|
||||
if (iovec_memcmp(&secret, &secret2) != 0)
|
||||
if (!iovec_equal(&secret, &secret2))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 seal/unseal verification failed.");
|
||||
}
|
||||
|
||||
@@ -579,7 +579,7 @@ int enroll_tpm2(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set minimal PBKDF: %m");
|
||||
|
||||
keyslot = crypt_keyslot_add_by_volume_key(
|
||||
keyslot = sym_crypt_keyslot_add_by_volume_key(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
volume_key->iov_base,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user