mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
Merge pull request #20902 from tasleson/integritysetup-generator
Add stand-alone dm integrity support
This commit is contained in:
commit
eaaa02bffe
@ -50,6 +50,10 @@ All tools:
|
|||||||
useful for debugging. Currently only supported by
|
useful for debugging. Currently only supported by
|
||||||
`systemd-cryptsetup-generator`.
|
`systemd-cryptsetup-generator`.
|
||||||
|
|
||||||
|
* `$SYSTEMD_INTEGRITYTAB` — if set, use this path instead of
|
||||||
|
`/etc/integritytab`. Only useful for debugging. Currently only supported by
|
||||||
|
`systemd-integritysetup-generator`.
|
||||||
|
|
||||||
* `$SYSTEMD_VERITYTAB` — if set, use this path instead of
|
* `$SYSTEMD_VERITYTAB` — if set, use this path instead of
|
||||||
`/etc/veritytab`. Only useful for debugging. Currently only supported by
|
`/etc/veritytab`. Only useful for debugging. Currently only supported by
|
||||||
`systemd-veritysetup-generator`.
|
`systemd-veritysetup-generator`.
|
||||||
|
161
man/integritytab.xml
Normal file
161
man/integritytab.xml
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--*-nxml-*-->
|
||||||
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||||
|
<!--
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
|
-->
|
||||||
|
<refentry id="integritytab" conditional='HAVE_LIBCRYPTSETUP' xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
|
||||||
|
<refentryinfo>
|
||||||
|
<title>integritytab</title>
|
||||||
|
<productname>systemd</productname>
|
||||||
|
</refentryinfo>
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>integritytab</refentrytitle>
|
||||||
|
<manvolnum>5</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>integritytab</refname>
|
||||||
|
<refpurpose>Configuration for integrity block devices</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<para><filename>/etc/integritytab</filename></para>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para>The <filename>/etc/integritytab</filename> file describes
|
||||||
|
integrity protected block devices that are set up during
|
||||||
|
system boot.</para>
|
||||||
|
|
||||||
|
<para>Empty lines and lines starting with the <literal>#</literal>
|
||||||
|
character are ignored. Each of the remaining lines describes one
|
||||||
|
verity integrity protected block device. Fields are delimited by
|
||||||
|
white space.</para>
|
||||||
|
|
||||||
|
<para>Each line is in the form<programlisting><replaceable>volume-name</replaceable> <replaceable>block-device</replaceable>
|
||||||
|
<replaceable>[keyfile|-]</replaceable> <replaceable>[options|-]</replaceable></programlisting>
|
||||||
|
The first two fields are mandatory, the remaining two are optional and only required if user specified non-default options during integrity format.</para>
|
||||||
|
|
||||||
|
<para>The first field contains the name of the resulting integrity volume; its block device is set up
|
||||||
|
below <filename>/dev/mapper/</filename>.</para>
|
||||||
|
|
||||||
|
<para>The second field contains a path to the underlying block device, or a specification of a block device via
|
||||||
|
<literal>UUID=</literal> followed by the UUID,
|
||||||
|
<literal>PARTUUID=</literal> followed by the partition UUID,
|
||||||
|
<literal>LABEL=</literal> followed by the label,
|
||||||
|
<literal>PARTLABEL=</literal> followed by the partition label,
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>The third field if present contains an absolute filename path to a key file or a <literal>-</literal>
|
||||||
|
to specify none. When the filename is present, the "integrity-algorithm" defaults to <literal>hmac-sha256</literal>
|
||||||
|
with the key length derived from the number of bytes in the key file. At this time the only supported integrity algorithm
|
||||||
|
when using key file is hmac-sha256. The maximum size of the key file is 4096 bytes.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>The fourth field, if present, is a comma-delimited list of options or a <literal>-</literal> to specify none. The following options are
|
||||||
|
recognized:</para>
|
||||||
|
<variablelist>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>allow-discards</option></term>
|
||||||
|
|
||||||
|
<listitem><para>
|
||||||
|
Allow the use of discard (TRIM) requests for the device.
|
||||||
|
This option is available since the Linux kernel version 5.7.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>journal-watermark=[0..100]%</option></term>
|
||||||
|
|
||||||
|
<listitem><para>
|
||||||
|
Journal watermark in percent. When the journal percentage exceeds this watermark, the journal flush will be started. Setting a value of
|
||||||
|
"0%" uses default value.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>journal-commit-time=[0..N]</option></term>
|
||||||
|
|
||||||
|
<listitem><para>
|
||||||
|
Commit time in milliseconds. When this time passes (and no explicit flush operation was issued), the journal is written. Setting a value of
|
||||||
|
zero uses default value.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>data-device=/dev/disk/by-...</option></term>
|
||||||
|
|
||||||
|
<listitem><para>
|
||||||
|
Specify a separate block device that contains existing data. The second field specified in the
|
||||||
|
integritytab for block device then will contain calculated integrity tags and journal for data-device,
|
||||||
|
but not the end user data.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>integrity-algorithm=[crc32c|crc32|sha1|sha256|hmac-sha256]</option></term>
|
||||||
|
|
||||||
|
<listitem><para>
|
||||||
|
The algorithm used for integrity checking. The default is crc32c. Must match option used during format.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
<para>At early boot and when the system manager configuration is
|
||||||
|
reloaded, this file is translated into native systemd units by
|
||||||
|
<citerefentry><refentrytitle>systemd-integritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Examples</title>
|
||||||
|
<example>
|
||||||
|
<title>/etc/integritytab</title>
|
||||||
|
<para>Set up two integrity protected block devices. </para>
|
||||||
|
|
||||||
|
<programlisting>home PARTUUID=4973d0b8-1b15-c449-96ec-94bab7f6a7b8 - journal-commit-time=10,allow-discards,journal-watermark=55%
|
||||||
|
data PARTUUID=5d4b1808-be76-774d-88af-03c4c3a41761 - allow-discards
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<title>/etc/integritytab</title>
|
||||||
|
<para>Set up 1 integrity protected block device using defaults </para>
|
||||||
|
|
||||||
|
<programlisting>home PARTUUID=4973d0b8-1b15-c449-96ec-94bab7f6a7b8</programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<title>/etc/integritytab</title>
|
||||||
|
<para>Set up 1 integrity device using existing data block device which contains user data </para>
|
||||||
|
|
||||||
|
<programlisting>home PARTUUID=4973d0b8-1b15-c449-96ec-94bab7f6a7b8 - data-device=/dev/disk/by-uuid/9276d9c0-d4e3-4297-b4ff-3307cd0d092f</programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<title>/etc/integritytab</title>
|
||||||
|
<para>Set up 1 integrity device using a HMAC key file using defaults </para>
|
||||||
|
|
||||||
|
<programlisting>home PARTUUID=4973d0b8-1b15-c449-96ec-94bab7f6a7b8 /etc/hmac.key</programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
<para>
|
||||||
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>systemd-integritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>systemd-integritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||||
|
<citerefentry project='die-net'><refentrytitle>integritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
</refentry>
|
@ -24,6 +24,7 @@ manpages = [
|
|||||||
['hostname', '5', [], ''],
|
['hostname', '5', [], ''],
|
||||||
['hostnamectl', '1', [], 'ENABLE_HOSTNAMED'],
|
['hostnamectl', '1', [], 'ENABLE_HOSTNAMED'],
|
||||||
['hwdb', '7', [], 'ENABLE_HWDB'],
|
['hwdb', '7', [], 'ENABLE_HWDB'],
|
||||||
|
['integritytab', '5', [], 'HAVE_LIBCRYPTSETUP'],
|
||||||
['journal-remote.conf', '5', ['journal-remote.conf.d'], 'HAVE_MICROHTTPD'],
|
['journal-remote.conf', '5', ['journal-remote.conf.d'], 'HAVE_MICROHTTPD'],
|
||||||
['journal-upload.conf', '5', ['journal-upload.conf.d'], 'HAVE_MICROHTTPD'],
|
['journal-upload.conf', '5', ['journal-upload.conf.d'], 'HAVE_MICROHTTPD'],
|
||||||
['journalctl', '1', [], ''],
|
['journalctl', '1', [], ''],
|
||||||
@ -882,6 +883,11 @@ manpages = [
|
|||||||
'8',
|
'8',
|
||||||
['systemd-initctl', 'systemd-initctl.socket'],
|
['systemd-initctl', 'systemd-initctl.socket'],
|
||||||
'HAVE_SYSV_COMPAT'],
|
'HAVE_SYSV_COMPAT'],
|
||||||
|
['systemd-integritysetup-generator', '8', [], 'HAVE_LIBCRYPTSETUP'],
|
||||||
|
['systemd-integritysetup@.service',
|
||||||
|
'8',
|
||||||
|
['systemd-integritysetup'],
|
||||||
|
'HAVE_LIBCRYPTSETUP'],
|
||||||
['systemd-journal-gatewayd.service',
|
['systemd-journal-gatewayd.service',
|
||||||
'8',
|
'8',
|
||||||
['systemd-journal-gatewayd', 'systemd-journal-gatewayd.socket'],
|
['systemd-journal-gatewayd', 'systemd-journal-gatewayd.socket'],
|
||||||
|
48
man/systemd-integritysetup-generator.xml
Normal file
48
man/systemd-integritysetup-generator.xml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--*-nxml-*-->
|
||||||
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||||
|
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
|
||||||
|
<refentry id="systemd-integritysetup-generator" conditional='HAVE_LIBCRYPTSETUP'>
|
||||||
|
|
||||||
|
<refentryinfo>
|
||||||
|
<title>systemd-integritysetup-generator</title>
|
||||||
|
<productname>systemd</productname>
|
||||||
|
</refentryinfo>
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>systemd-integritysetup-generator</refentrytitle>
|
||||||
|
<manvolnum>8</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>systemd-integritysetup-generator</refname>
|
||||||
|
<refpurpose>Unit generator for integrity protected block devices</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<para><filename>/usr/lib/systemd/system-generators/systemd-integritysetup-generator</filename></para>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para><filename>systemd-integritysetup-generator</filename> is a generator that translates <filename>/etc/integritytab</filename> entries into
|
||||||
|
native systemd units early at boot. This will create
|
||||||
|
<citerefentry><refentrytitle>systemd-integritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||||
|
units as necessary.</para>
|
||||||
|
|
||||||
|
<para><command>systemd-integritysetup-generator</command> implements
|
||||||
|
<citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
<para>
|
||||||
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>systemd-integritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||||
|
<citerefentry project='die-net'><refentrytitle>integritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
</refentry>
|
95
man/systemd-integritysetup@.service.xml
Normal file
95
man/systemd-integritysetup@.service.xml
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--*-nxml-*-->
|
||||||
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||||
|
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
|
||||||
|
<refentry id="systemd-integritysetup@.service" conditional='HAVE_LIBCRYPTSETUP'>
|
||||||
|
|
||||||
|
<refentryinfo>
|
||||||
|
<title>systemd-integritysetup@.service</title>
|
||||||
|
<productname>systemd</productname>
|
||||||
|
</refentryinfo>
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>systemd-integritysetup@.service</refentrytitle>
|
||||||
|
<manvolnum>8</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>systemd-integritysetup@.service</refname>
|
||||||
|
<refname>systemd-integritysetup</refname>
|
||||||
|
<refpurpose>Disk integrity protection logic</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<para><filename>systemd-integritysetup@.service</filename></para>
|
||||||
|
<para><filename>/usr/lib/systemd/systemd-integritysetup</filename></para>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para><filename>systemd-integritysetup@.service</filename> is a service responsible for setting up integrity
|
||||||
|
protected block devices. It should be instantiated for each device that requires integrity
|
||||||
|
protection.</para>
|
||||||
|
|
||||||
|
<para>At early boot and when the system manager configuration is reloaded, entries from /etc/integritytab are converted into
|
||||||
|
<filename>systemd-integritysetup@.service</filename> units by
|
||||||
|
<citerefentry><refentrytitle>systemd-integritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
|
||||||
|
|
||||||
|
<para><filename>systemd-integritysetup@.service</filename> calls <command>systemd-integritysetup</command>.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Commands</title>
|
||||||
|
|
||||||
|
<para>The following commands are understood by <command>systemd-integritysetup</command>:</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>attach</option>
|
||||||
|
<replaceable>volume</replaceable>
|
||||||
|
<replaceable>device</replaceable>
|
||||||
|
[<replaceable>key-file|-</replaceable>]
|
||||||
|
[<replaceable>option(s)|-</replaceable>]
|
||||||
|
</term>
|
||||||
|
|
||||||
|
<listitem><para>Create a block device <replaceable>volume</replaceable> using
|
||||||
|
<replaceable>device</replaceable>. See integritytab man page and
|
||||||
|
<ulink url="https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-integrity.html">
|
||||||
|
Kernel dm-integrity</ulink> documentation for details.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>detach</option>
|
||||||
|
<replaceable>volume</replaceable>
|
||||||
|
</term>
|
||||||
|
|
||||||
|
<listitem><para>Detach (destroy) the block device
|
||||||
|
<replaceable>volume</replaceable>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>help</option>
|
||||||
|
</term>
|
||||||
|
|
||||||
|
<listitem><para>Print short information about command syntax.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
<para>
|
||||||
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>integritytab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>systemd-integritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||||
|
<citerefentry project='die-net'><refentrytitle>integritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
</refentry>
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>systemd-veritysetup-generator</refname>
|
<refname>systemd-veritysetup-generator</refname>
|
||||||
<refpurpose>Unit generator for integrity protected block devices</refpurpose>
|
<refpurpose>Unit generator for verity protected block devices</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
@ -28,7 +28,7 @@
|
|||||||
<title>Description</title>
|
<title>Description</title>
|
||||||
|
|
||||||
<para><filename>systemd-veritysetup-generator</filename> is a generator that translates kernel command line options
|
<para><filename>systemd-veritysetup-generator</filename> is a generator that translates kernel command line options
|
||||||
configuring integrity-protected block devices (verity) into native systemd units early at boot and when
|
configuring verity protected block devices into native systemd units early at boot and when
|
||||||
configuration of the system manager is reloaded. This will create
|
configuration of the system manager is reloaded. This will create
|
||||||
<citerefentry><refentrytitle>systemd-veritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>systemd-veritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||||
units as necessary.</para>
|
units as necessary.</para>
|
||||||
@ -66,7 +66,7 @@
|
|||||||
data devices to use are automatically derived from the specified hash value. Specifically, the data partition
|
data devices to use are automatically derived from the specified hash value. Specifically, the data partition
|
||||||
device is looked for under a GPT partition UUID derived from the first 128bit of the root hash, the hash
|
device is looked for under a GPT partition UUID derived from the first 128bit of the root hash, the hash
|
||||||
partition device is looked for under a GPT partition UUID derived from the last 128bit of the root hash. Hence
|
partition device is looked for under a GPT partition UUID derived from the last 128bit of the root hash. Hence
|
||||||
it is usually sufficient to specify the root hash to boot from an integrity protected root file system, as
|
it is usually sufficient to specify the root hash to boot from a verity protected root file system, as
|
||||||
device paths are automatically determined from it — as long as the partition table is properly set up.</para>
|
device paths are automatically determined from it — as long as the partition table is properly set up.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -76,7 +76,7 @@
|
|||||||
<term><varname>systemd.verity_root_hash=</varname></term>
|
<term><varname>systemd.verity_root_hash=</varname></term>
|
||||||
|
|
||||||
<listitem><para>These two settings take block device paths as arguments and may be used to explicitly
|
<listitem><para>These two settings take block device paths as arguments and may be used to explicitly
|
||||||
configure the data partition and hash partition to use for setting up the integrity protection for the root file
|
configure the data partition and hash partition to use for setting up the verity protection for the root file
|
||||||
system. If not specified, these paths are automatically derived from the <varname>roothash=</varname> argument
|
system. If not specified, these paths are automatically derived from the <varname>roothash=</varname> argument
|
||||||
(see above).</para></listitem>
|
(see above).</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>systemd-veritysetup@.service</refname>
|
<refname>systemd-veritysetup@.service</refname>
|
||||||
<refname>systemd-veritysetup</refname>
|
<refname>systemd-veritysetup</refname>
|
||||||
<refpurpose>Disk integrity protection logic</refpurpose>
|
<refpurpose>Disk verity protection logic</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
@ -29,12 +29,12 @@
|
|||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Description</title>
|
<title>Description</title>
|
||||||
|
|
||||||
<para><filename>systemd-veritysetup@.service</filename> is a service responsible for setting up integrity
|
<para><filename>systemd-veritysetup@.service</filename> is a service responsible for setting up verity
|
||||||
protection (verity) block devices. It should be instantiated for each device that requires integrity
|
protection block devices. It should be instantiated for each device that requires verity
|
||||||
protection.</para>
|
protection.</para>
|
||||||
|
|
||||||
<para>At early boot and when the system manager configuration is reloaded kernel command line configuration for
|
<para>At early boot and when the system manager configuration is reloaded kernel command line configuration for
|
||||||
integrity protected block devices is translated into <filename>systemd-veritysetup@.service</filename> units by
|
verity protected block devices is translated into <filename>systemd-veritysetup@.service</filename> units by
|
||||||
<citerefentry><refentrytitle>systemd-veritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
|
<citerefentry><refentrytitle>systemd-veritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
|
||||||
|
|
||||||
<para><filename>systemd-veritysetup@.service</filename> calls <command>systemd-veritysetup</command>.</para>
|
<para><filename>systemd-veritysetup@.service</filename> calls <command>systemd-veritysetup</command>.</para>
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
<filename>initrd-root-device.target</filename>,
|
<filename>initrd-root-device.target</filename>,
|
||||||
<filename>initrd-root-fs.target</filename>,
|
<filename>initrd-root-fs.target</filename>,
|
||||||
<filename>initrd-usr-fs.target</filename>,
|
<filename>initrd-usr-fs.target</filename>,
|
||||||
|
<filename>integritysetup-pre.target</filename>,
|
||||||
|
<filename>integritysetup.target</filename>,
|
||||||
<filename>kbrequest.target</filename>,
|
<filename>kbrequest.target</filename>,
|
||||||
<filename>kexec.target</filename>,
|
<filename>kexec.target</filename>,
|
||||||
<filename>local-fs-pre.target</filename>,
|
<filename>local-fs-pre.target</filename>,
|
||||||
|
@ -33,12 +33,12 @@ This is based on crypttab(5).
|
|||||||
<title>Description</title>
|
<title>Description</title>
|
||||||
|
|
||||||
<para>The <filename>/etc/veritytab</filename> file describes
|
<para>The <filename>/etc/veritytab</filename> file describes
|
||||||
verity integrity protected block devices that are set up during
|
verity protected block devices that are set up during
|
||||||
system boot.</para>
|
system boot.</para>
|
||||||
|
|
||||||
<para>Empty lines and lines starting with the <literal>#</literal>
|
<para>Empty lines and lines starting with the <literal>#</literal>
|
||||||
character are ignored. Each of the remaining lines describes one
|
character are ignored. Each of the remaining lines describes one
|
||||||
verity integrity protected block device. Fields are delimited by
|
verity protected block device. Fields are delimited by
|
||||||
white space.</para>
|
white space.</para>
|
||||||
|
|
||||||
<para>Each line is in the form<programlisting><replaceable>volume-name</replaceable> <replaceable>data-device</replaceable> <replaceable>hash-device</replaceable> <replaceable>roothash</replaceable> <replaceable>options</replaceable></programlisting>
|
<para>Each line is in the form<programlisting><replaceable>volume-name</replaceable> <replaceable>data-device</replaceable> <replaceable>hash-device</replaceable> <replaceable>roothash</replaceable> <replaceable>options</replaceable></programlisting>
|
||||||
@ -65,7 +65,7 @@ This is based on crypttab(5).
|
|||||||
<term><option>restart-on-corruption</option></term>
|
<term><option>restart-on-corruption</option></term>
|
||||||
<term><option>panic-on-corruption</option></term>
|
<term><option>panic-on-corruption</option></term>
|
||||||
|
|
||||||
<listitem><para>Defines what to do if data integrity problem is detected (data corruption). Without these
|
<listitem><para>Defines what to do if a data verity problem is detected (data corruption). Without these
|
||||||
options kernel fails the IO operation with I/O error. With <literal>--ignore-corruption</literal> option the
|
options kernel fails the IO operation with I/O error. With <literal>--ignore-corruption</literal> option the
|
||||||
corruption is only logged. With <literal>--restart-on-corruption</literal> or
|
corruption is only logged. With <literal>--restart-on-corruption</literal> or
|
||||||
<literal>--panic-on-corruption</literal> the kernel is restarted (panicked) immediately.
|
<literal>--panic-on-corruption</literal> the kernel is restarted (panicked) immediately.
|
||||||
@ -149,18 +149,18 @@ This is based on crypttab(5).
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>x-initrd.attach</option></term>
|
<term><option>x-initrd.attach</option></term>
|
||||||
|
|
||||||
<listitem><para>Setup this verity integrity protected block device in the initramfs, similarly to
|
<listitem><para>Setup this verity protected block device in the initramfs, similarly to
|
||||||
<citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||||
units marked with <option>x-initrd.mount</option>.</para>
|
units marked with <option>x-initrd.mount</option>.</para>
|
||||||
|
|
||||||
<para>Although it's not necessary to mark the mount entry for the root file system with
|
<para>Although it's not necessary to mark the mount entry for the root file system with
|
||||||
<option>x-initrd.mount</option>, <option>x-initrd.attach</option> is still recommended with
|
<option>x-initrd.mount</option>, <option>x-initrd.attach</option> is still recommended with
|
||||||
the verity integrity protected block device containing the root file system as otherwise systemd
|
the verity protected block device containing the root file system as otherwise systemd
|
||||||
will attempt to detach the device during the regular system shutdown while it's still in
|
will attempt to detach the device during the regular system shutdown while it's still in
|
||||||
use. With this option the device will still be detached but later after the root file
|
use. With this option the device will still be detached but later after the root file
|
||||||
system is unmounted.</para>
|
system is unmounted.</para>
|
||||||
|
|
||||||
<para>All other verity integrity protected block devices that contain file systems mounted in the
|
<para>All other verity protected block devices that contain file systems mounted in the
|
||||||
initramfs should use this option.</para>
|
initramfs should use this option.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -176,7 +176,7 @@ This is based on crypttab(5).
|
|||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
<example>
|
<example>
|
||||||
<title>/etc/veritytab example</title>
|
<title>/etc/veritytab example</title>
|
||||||
<para>Set up two verity integrity protected block devices. One using device blocks, another using files.</para>
|
<para>Set up two verity protected block devices. One using device blocks, another using files.</para>
|
||||||
|
|
||||||
<programlisting>usr PARTUUID=783e45ae-7aa3-484a-beef-a80ff9c19cbb PARTUUID=21dc1dfe-4c33-8b48-98a9-918a22eb3e37 36e3f740ad502e2c25e2a23d9c7c17bf0fdad2300b7580842d4b7ec1fb0fa263 auto
|
<programlisting>usr PARTUUID=783e45ae-7aa3-484a-beef-a80ff9c19cbb PARTUUID=21dc1dfe-4c33-8b48-98a9-918a22eb3e37 36e3f740ad502e2c25e2a23d9c7c17bf0fdad2300b7580842d4b7ec1fb0fa263 auto
|
||||||
data /etc/data /etc/hash a5ee4b42f70ae1f46a08a7c92c2e0a20672ad2f514792730f5d49d7606ab8fdf auto
|
data /etc/data /etc/hash a5ee4b42f70ae1f46a08a7c92c2e0a20672ad2f514792730f5d49d7606ab8fdf auto
|
||||||
|
20
meson.build
20
meson.build
@ -252,6 +252,7 @@ conf.set_quoted('SYSTEMD_GROWFS_PATH', rootlibexecdir / '
|
|||||||
conf.set_quoted('SYSTEMD_HOMEWORK_PATH', rootlibexecdir / 'systemd-homework')
|
conf.set_quoted('SYSTEMD_HOMEWORK_PATH', rootlibexecdir / 'systemd-homework')
|
||||||
conf.set_quoted('SYSTEMD_IMPORT_FS_PATH', rootlibexecdir / 'systemd-import-fs')
|
conf.set_quoted('SYSTEMD_IMPORT_FS_PATH', rootlibexecdir / 'systemd-import-fs')
|
||||||
conf.set_quoted('SYSTEMD_IMPORT_PATH', rootlibexecdir / 'systemd-import')
|
conf.set_quoted('SYSTEMD_IMPORT_PATH', rootlibexecdir / 'systemd-import')
|
||||||
|
conf.set_quoted('SYSTEMD_INTEGRITYSETUP_PATH', rootlibexecdir / 'systemd-integritysetup')
|
||||||
conf.set_quoted('SYSTEMD_KBD_MODEL_MAP', pkgdatadir / 'kbd-model-map')
|
conf.set_quoted('SYSTEMD_KBD_MODEL_MAP', pkgdatadir / 'kbd-model-map')
|
||||||
conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP', pkgdatadir / 'language-fallback-map')
|
conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP', pkgdatadir / 'language-fallback-map')
|
||||||
conf.set_quoted('SYSTEMD_MAKEFS_PATH', rootlibexecdir / 'systemd-makefs')
|
conf.set_quoted('SYSTEMD_MAKEFS_PATH', rootlibexecdir / 'systemd-makefs')
|
||||||
@ -2535,6 +2536,25 @@ if conf.get('HAVE_LIBCRYPTSETUP') == 1
|
|||||||
libp11kit],
|
libp11kit],
|
||||||
install_rpath : rootlibexecdir,
|
install_rpath : rootlibexecdir,
|
||||||
install : true)
|
install : true)
|
||||||
|
|
||||||
|
executable(
|
||||||
|
'systemd-integritysetup',
|
||||||
|
['src/integritysetup/integritysetup.c', 'src/integritysetup/integrity-util.c'],
|
||||||
|
include_directories : includes,
|
||||||
|
link_with : [libshared],
|
||||||
|
dependencies : [libcryptsetup],
|
||||||
|
install_rpath : rootlibexecdir,
|
||||||
|
install : true,
|
||||||
|
install_dir : rootlibexecdir)
|
||||||
|
|
||||||
|
executable(
|
||||||
|
'systemd-integritysetup-generator',
|
||||||
|
['src/integritysetup/integritysetup-generator.c', 'src/integritysetup/integrity-util.c'],
|
||||||
|
include_directories : includes,
|
||||||
|
link_with : [libshared],
|
||||||
|
install_rpath : rootlibexecdir,
|
||||||
|
install : true,
|
||||||
|
install_dir : systemgeneratordir)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if conf.get('HAVE_SYSV_COMPAT') == 1
|
if conf.get('HAVE_SYSV_COMPAT') == 1
|
||||||
|
66
src/integritysetup/integrity-util.c
Normal file
66
src/integritysetup/integrity-util.c
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
#include "integrity-util.h"
|
||||||
|
|
||||||
|
#include "extract-word.h"
|
||||||
|
#include "fileio.h"
|
||||||
|
#include "path-util.h"
|
||||||
|
#include "percent-util.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int supported_integrity_algorithm(char *user_supplied) {
|
||||||
|
if (!STR_IN_SET(user_supplied, "crc32", "crc32c", "sha1", "sha256", "hmac-sha256"))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unsupported integrity algorithm (%s)", user_supplied);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_integrity_options(
|
||||||
|
const char *options,
|
||||||
|
uint32_t *ret_activate_flags,
|
||||||
|
int *ret_percent,
|
||||||
|
usec_t *ret_commit_time,
|
||||||
|
char **ret_data_device,
|
||||||
|
char **ret_integrity_alg) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
_cleanup_free_ char *word = NULL;
|
||||||
|
char *val;
|
||||||
|
|
||||||
|
r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse options: %m");
|
||||||
|
if (r == 0)
|
||||||
|
break;
|
||||||
|
else if (streq(word, "allow-discards")) {
|
||||||
|
if (ret_activate_flags)
|
||||||
|
*ret_activate_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
|
||||||
|
} else if ((val = startswith(word, "journal-watermark="))) {
|
||||||
|
r = parse_percent(val);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse journal-watermark value or value out of range (%s)", val);
|
||||||
|
if (ret_percent)
|
||||||
|
*ret_percent = r;
|
||||||
|
} else if ((val = startswith(word, "journal-commit-time="))) {
|
||||||
|
usec_t tmp_commit_time;
|
||||||
|
r = parse_sec(val, &tmp_commit_time);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse journal-commit-time value (%s)", val);
|
||||||
|
if (ret_commit_time)
|
||||||
|
*ret_commit_time = tmp_commit_time;
|
||||||
|
} else if ((val = startswith(word, "data-device="))) {
|
||||||
|
r = free_and_strdup(ret_data_device, val);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
} else if ((val = startswith(word, "integrity-algorithm="))) {
|
||||||
|
r = free_and_strdup(ret_integrity_alg, val);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
r = supported_integrity_algorithm(*ret_integrity_alg);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
} else
|
||||||
|
log_warning("Encountered unknown option '%s', ignoring.", word);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
19
src/integritysetup/integrity-util.h
Normal file
19
src/integritysetup/integrity-util.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "cryptsetup-util.h"
|
||||||
|
#include "time-util.h"
|
||||||
|
|
||||||
|
|
||||||
|
int parse_integrity_options(
|
||||||
|
const char *options,
|
||||||
|
uint32_t *ret_activate_flags,
|
||||||
|
int *ret_percent,
|
||||||
|
usec_t *ret_commit_time,
|
||||||
|
char **ret_data_device,
|
||||||
|
char **ret_integrity_alg);
|
||||||
|
|
||||||
|
#define DM_HMAC_256 "hmac(sha256)"
|
||||||
|
#define DM_MAX_KEY_SIZE 4096 /* Maximum size of key allowed for dm-integrity */
|
181
src/integritysetup/integritysetup-generator.c
Normal file
181
src/integritysetup/integritysetup-generator.c
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
|
#include "fd-util.h"
|
||||||
|
#include "fileio.h"
|
||||||
|
#include "fstab-util.h"
|
||||||
|
#include "generator.h"
|
||||||
|
#include "hexdecoct.h"
|
||||||
|
#include "id128-util.h"
|
||||||
|
#include "integrity-util.h"
|
||||||
|
#include "main-func.h"
|
||||||
|
#include "mkdir.h"
|
||||||
|
#include "parse-util.h"
|
||||||
|
#include "path-util.h"
|
||||||
|
#include "proc-cmdline.h"
|
||||||
|
#include "specifier.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
#include "unit-name.h"
|
||||||
|
|
||||||
|
static const char *arg_dest = NULL;
|
||||||
|
static const char *arg_integritytab = NULL;
|
||||||
|
static char *arg_options = NULL;
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_options, freep);
|
||||||
|
|
||||||
|
static int create_disk(
|
||||||
|
const char *name,
|
||||||
|
const char *device,
|
||||||
|
const char *key_file,
|
||||||
|
const char *options) {
|
||||||
|
|
||||||
|
_cleanup_free_ char *n = NULL, *dd = NULL, *e = NULL, *name_escaped = NULL, *key_file_escaped = NULL;
|
||||||
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
|
int r;
|
||||||
|
char *dmname = NULL;
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
assert(device);
|
||||||
|
|
||||||
|
name_escaped = specifier_escape(name);
|
||||||
|
if (!name_escaped)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
e = unit_name_escape(name);
|
||||||
|
if (!e)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
r = unit_name_build("systemd-integritysetup", e, ".service", &n);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to generate unit name: %m");
|
||||||
|
|
||||||
|
r = unit_name_from_path(device, ".device", &dd);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to generate unit name: %m");
|
||||||
|
|
||||||
|
r = generator_open_unit_file(arg_dest, NULL, n, &f);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (key_file) {
|
||||||
|
if (!path_is_absolute(key_file))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "key file not absolute file path %s", key_file);
|
||||||
|
|
||||||
|
key_file_escaped = specifier_escape(key_file);
|
||||||
|
if (!key_file_escaped)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options) {
|
||||||
|
r = parse_integrity_options(options, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(f,
|
||||||
|
"[Unit]\n"
|
||||||
|
"Description=Integrity Setup for %%I\n"
|
||||||
|
"Documentation=man:integritytab(5) man:systemd-integritysetup-generator(8) man:systemd-integritysetup@.service(8)\n"
|
||||||
|
"SourcePath=%s\n"
|
||||||
|
"DefaultDependencies=no\n"
|
||||||
|
"IgnoreOnIsolate=true\n"
|
||||||
|
"After=integritysetup-pre.target systemd-udevd-kernel.socket\n"
|
||||||
|
"Before=blockdev@dev-mapper-%%i.target\n"
|
||||||
|
"Wants=blockdev@dev-mapper-%%i.target\n"
|
||||||
|
"Conflicts=umount.target\n"
|
||||||
|
"Before=integritysetup.target\n"
|
||||||
|
"BindsTo=%s\n"
|
||||||
|
"After=%s\n"
|
||||||
|
"Before=umount.target\n",
|
||||||
|
arg_integritytab,
|
||||||
|
dd, dd);
|
||||||
|
|
||||||
|
fprintf(f,
|
||||||
|
"\n"
|
||||||
|
"[Service]\n"
|
||||||
|
"Type=oneshot\n"
|
||||||
|
"RemainAfterExit=yes\n"
|
||||||
|
"TimeoutSec=0\n"
|
||||||
|
"ExecStart=" ROOTLIBEXECDIR "/systemd-integritysetup attach '%s' '%s' '%s' '%s'\n"
|
||||||
|
"ExecStop=" ROOTLIBEXECDIR "/systemd-integritysetup detach '%s'\n",
|
||||||
|
name_escaped, device, empty_to_dash(key_file_escaped), empty_to_dash(options),
|
||||||
|
name_escaped);
|
||||||
|
|
||||||
|
r = fflush_and_check(f);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to write unit file %s: %m", n);
|
||||||
|
|
||||||
|
r = generator_add_symlink(arg_dest, "integritysetup.target", "requires", n);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
dmname = strjoina("dev-mapper-", e, ".device");
|
||||||
|
return generator_add_symlink(arg_dest, dmname, "requires", n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int add_integritytab_devices(void) {
|
||||||
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
|
unsigned integritytab_line = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = fopen_unlocked(arg_integritytab, "re", &f);
|
||||||
|
if (r < 0) {
|
||||||
|
if (errno != ENOENT)
|
||||||
|
log_error_errno(errno, "Failed to open %s: %m", arg_integritytab);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
_cleanup_free_ char *line = NULL, *name = NULL, *device_id = NULL, *device_path = NULL, *key_file = NULL, *options = NULL;
|
||||||
|
char *l;
|
||||||
|
|
||||||
|
r = read_line(f, LONG_LINE_MAX, &line);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to read %s: %m", arg_integritytab);
|
||||||
|
if (r == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
integritytab_line++;
|
||||||
|
|
||||||
|
l = strstrip(line);
|
||||||
|
if (!l)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (IN_SET(l[0], 0, '#'))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* The key file and the options are optional */
|
||||||
|
r = sscanf(l, "%ms %ms %ms %ms", &name, &device_id, &key_file, &options);
|
||||||
|
if (!IN_SET(r, 2, 3, 4)) {
|
||||||
|
log_error("Failed to parse %s:%u, ignoring.", l, integritytab_line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
device_path = fstab_node_to_udev_node(device_id);
|
||||||
|
if (!device_path) {
|
||||||
|
log_error("Failed to find device %s:%u, ignoring.", device_id, integritytab_line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = create_disk(name, device_path, empty_or_dash_to_null(key_file), empty_or_dash_to_null(options));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int run(const char *dest, const char *dest_early, const char *dest_late) {
|
||||||
|
assert_se(arg_dest = dest);
|
||||||
|
|
||||||
|
arg_integritytab = getenv("SYSTEMD_INTEGRITYTAB") ?: "/etc/integritytab";
|
||||||
|
|
||||||
|
return add_integritytab_devices();
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_MAIN_GENERATOR_FUNCTION(run);
|
197
src/integritysetup/integritysetup.c
Normal file
197
src/integritysetup/integritysetup.c
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
|
#include "cryptsetup-util.h"
|
||||||
|
#include "fileio.h"
|
||||||
|
#include "hexdecoct.h"
|
||||||
|
#include "integrity-util.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "main-func.h"
|
||||||
|
#include "memory-util.h"
|
||||||
|
#include "path-util.h"
|
||||||
|
#include "parse-util.h"
|
||||||
|
#include "pretty-print.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
#include "terminal-util.h"
|
||||||
|
|
||||||
|
static uint32_t arg_activate_flags;
|
||||||
|
static int arg_percent;
|
||||||
|
static usec_t arg_commit_time;
|
||||||
|
static char *arg_existing_data_device;
|
||||||
|
static char *arg_integrity_algorithm;
|
||||||
|
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_existing_data_device, freep);
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_integrity_algorithm, freep);
|
||||||
|
|
||||||
|
static int help(void) {
|
||||||
|
_cleanup_free_ char *link = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = terminal_urlify_man("systemd-integritysetup@.service", "8", &link);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
printf("%s attach VOLUME DEVICE [HMAC_KEY_FILE|-] [OPTIONS]\n"
|
||||||
|
"%s detach VOLUME\n\n"
|
||||||
|
"Attach or detach an integrity protected block device.\n"
|
||||||
|
"\nSee the %s for details.\n",
|
||||||
|
program_invocation_short_name,
|
||||||
|
program_invocation_short_name,
|
||||||
|
link);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int load_key_file(
|
||||||
|
const char *key_file,
|
||||||
|
void **ret_key_file_contents,
|
||||||
|
size_t *ret_key_file_size) {
|
||||||
|
int r;
|
||||||
|
_cleanup_(erase_and_freep) char *tmp_key_file_contents = NULL;
|
||||||
|
size_t tmp_key_file_size;
|
||||||
|
|
||||||
|
if (!path_is_absolute(key_file))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "key file not absolute path: %s", key_file);
|
||||||
|
|
||||||
|
r = read_full_file_full(
|
||||||
|
AT_FDCWD, key_file, UINT64_MAX, DM_MAX_KEY_SIZE,
|
||||||
|
READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET|READ_FULL_FILE_FAIL_WHEN_LARGER,
|
||||||
|
NULL,
|
||||||
|
&tmp_key_file_contents, &tmp_key_file_size);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to process key file: %m");
|
||||||
|
|
||||||
|
if (ret_key_file_contents && ret_key_file_size) {
|
||||||
|
*ret_key_file_contents = TAKE_PTR(tmp_key_file_contents);
|
||||||
|
*ret_key_file_size = tmp_key_file_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *integrity_algorithm_select(const void *key_file_buf) {
|
||||||
|
/* To keep a bit of sanity for end users, the subset of integrity
|
||||||
|
algorithms we support will match what is used in integritysetup */
|
||||||
|
if (arg_integrity_algorithm) {
|
||||||
|
if (streq("hmac-sha256", arg_integrity_algorithm))
|
||||||
|
return DM_HMAC_256;
|
||||||
|
return arg_integrity_algorithm;
|
||||||
|
} else if (key_file_buf)
|
||||||
|
return DM_HMAC_256;
|
||||||
|
return "crc32c";
|
||||||
|
}
|
||||||
|
|
||||||
|
static int run(int argc, char *argv[]) {
|
||||||
|
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
|
||||||
|
int r;
|
||||||
|
char *action, *volume;
|
||||||
|
|
||||||
|
if (argc <= 1 ||
|
||||||
|
strv_contains(strv_skip(argv, 1), "--help") ||
|
||||||
|
strv_contains(strv_skip(argv, 1), "-h") ||
|
||||||
|
streq(argv[1], "help"))
|
||||||
|
return help();
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program requires at least two arguments.");
|
||||||
|
|
||||||
|
action = argv[1];
|
||||||
|
volume = argv[2];
|
||||||
|
|
||||||
|
log_setup();
|
||||||
|
|
||||||
|
cryptsetup_enable_logging(NULL);
|
||||||
|
|
||||||
|
umask(0022);
|
||||||
|
|
||||||
|
if (streq(action, "attach")) {
|
||||||
|
/* attach name device optional_key_file optional_options */
|
||||||
|
|
||||||
|
crypt_status_info status;
|
||||||
|
_cleanup_(erase_and_freep) void *key_buf = NULL;
|
||||||
|
const char *device, *key_file, *options;
|
||||||
|
size_t key_buf_size = 0;
|
||||||
|
|
||||||
|
if (argc < 4)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach requires at least three arguments.");
|
||||||
|
|
||||||
|
if (argc > 6)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach has a maximum of five arguments.");
|
||||||
|
|
||||||
|
device = argv[3];
|
||||||
|
key_file = (argc > 4) ? empty_or_dash_to_null(argv[4]) : NULL;
|
||||||
|
options = (argc > 5) ? empty_or_dash_to_null(argv[5]) : NULL;
|
||||||
|
|
||||||
|
if (key_file) {
|
||||||
|
r = load_key_file(key_file, &key_buf, &key_buf_size);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options) {
|
||||||
|
r = parse_integrity_options(options, &arg_activate_flags, &arg_percent,
|
||||||
|
&arg_commit_time, &arg_existing_data_device, &arg_integrity_algorithm);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = crypt_init(&cd, device);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to open integrity device %s: %m", device);
|
||||||
|
|
||||||
|
cryptsetup_enable_logging(cd);
|
||||||
|
|
||||||
|
status = crypt_status(cd, volume);
|
||||||
|
if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
|
||||||
|
log_info("Volume %s already active.", volume);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isempty(arg_existing_data_device)) {
|
||||||
|
r = crypt_init_data_device(&cd, device, arg_existing_data_device);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to add separate data device: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
r = crypt_load(cd,
|
||||||
|
CRYPT_INTEGRITY,
|
||||||
|
&(struct crypt_params_integrity) {
|
||||||
|
.journal_watermark = arg_percent,
|
||||||
|
.journal_commit_time = DIV_ROUND_UP(arg_commit_time, USEC_PER_SEC),
|
||||||
|
.integrity = integrity_algorithm_select(key_buf),
|
||||||
|
});
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to load integrity superblock: %m");
|
||||||
|
|
||||||
|
r = crypt_activate_by_volume_key(cd, volume, key_buf, key_buf_size, arg_activate_flags);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to set up integrity device: %m");
|
||||||
|
|
||||||
|
} else if (streq(action, "detach")) {
|
||||||
|
|
||||||
|
if (argc > 3)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "detach has a maximum of two arguments.");
|
||||||
|
|
||||||
|
r = crypt_init_by_name(&cd, volume);
|
||||||
|
if (r == -ENODEV)
|
||||||
|
return 0;
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "crypt_init_by_name() failed: %m");
|
||||||
|
|
||||||
|
cryptsetup_enable_logging(cd);
|
||||||
|
|
||||||
|
r = crypt_deactivate(cd, volume);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to deactivate: %m");
|
||||||
|
|
||||||
|
} else
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb %s.", action);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_MAIN_FUNCTION(run);
|
@ -100,7 +100,7 @@ static int create_device(void) {
|
|||||||
|
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
"[Unit]\n"
|
"[Unit]\n"
|
||||||
"Description=Integrity Protection Setup for %%I\n"
|
"Description=Verity Protection Setup for %%I\n"
|
||||||
"Documentation=man:systemd-veritysetup-generator(8) man:systemd-veritysetup@.service(8)\n"
|
"Documentation=man:systemd-veritysetup-generator(8) man:systemd-veritysetup@.service(8)\n"
|
||||||
"SourcePath=/proc/cmdline\n"
|
"SourcePath=/proc/cmdline\n"
|
||||||
"DefaultDependencies=no\n"
|
"DefaultDependencies=no\n"
|
||||||
|
@ -30,7 +30,7 @@ static int help(void) {
|
|||||||
|
|
||||||
printf("%s attach VOLUME DATADEVICE HASHDEVICE ROOTHASH [OPTIONS]\n"
|
printf("%s attach VOLUME DATADEVICE HASHDEVICE ROOTHASH [OPTIONS]\n"
|
||||||
"%s detach VOLUME\n\n"
|
"%s detach VOLUME\n\n"
|
||||||
"Attach or detach an integrity protected block device.\n"
|
"Attach or detach a verity protected block device.\n"
|
||||||
"\nSee the %s for details.\n",
|
"\nSee the %s for details.\n",
|
||||||
program_invocation_short_name,
|
program_invocation_short_name,
|
||||||
program_invocation_short_name,
|
program_invocation_short_name,
|
||||||
|
14
units/integritysetup-pre.target
Normal file
14
units/integritysetup-pre.target
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
#
|
||||||
|
# This file is part of systemd.
|
||||||
|
#
|
||||||
|
# systemd is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Local Integrity Protected Volumes (Pre)
|
||||||
|
Documentation=man:systemd.special(7)
|
||||||
|
RefuseManualStart=yes
|
||||||
|
Before=integritysetup.target
|
12
units/integritysetup.target
Normal file
12
units/integritysetup.target
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
#
|
||||||
|
# This file is part of systemd.
|
||||||
|
#
|
||||||
|
# systemd is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Local Integrity Protected Volumes
|
||||||
|
Documentation=man:systemd.special(7)
|
@ -13,6 +13,9 @@ units = [
|
|||||||
['veritysetup-pre.target', 'HAVE_LIBCRYPTSETUP'],
|
['veritysetup-pre.target', 'HAVE_LIBCRYPTSETUP'],
|
||||||
['veritysetup.target', 'HAVE_LIBCRYPTSETUP',
|
['veritysetup.target', 'HAVE_LIBCRYPTSETUP',
|
||||||
'sysinit.target.wants/'],
|
'sysinit.target.wants/'],
|
||||||
|
['integritysetup-pre.target', 'HAVE_LIBCRYPTSETUP'],
|
||||||
|
['integritysetup.target', 'HAVE_LIBCRYPTSETUP',
|
||||||
|
'sysinit.target.wants/'],
|
||||||
['dev-hugepages.mount', '',
|
['dev-hugepages.mount', '',
|
||||||
'sysinit.target.wants/'],
|
'sysinit.target.wants/'],
|
||||||
['dev-mqueue.mount', '',
|
['dev-mqueue.mount', '',
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
|
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Remote Verity Integrity Protected Volumes
|
Description=Remote Verity Protected Volumes
|
||||||
Documentation=man:systemd.special(7)
|
Documentation=man:systemd.special(7)
|
||||||
After=remote-fs-pre.target veritysetup-pre.target
|
After=remote-fs-pre.target veritysetup-pre.target
|
||||||
DefaultDependencies=no
|
DefaultDependencies=no
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
|
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Local Verity Integrity Protected Volumes (Pre)
|
Description=Local Verity Protected Volumes (Pre)
|
||||||
Documentation=man:systemd.special(7)
|
Documentation=man:systemd.special(7)
|
||||||
RefuseManualStart=yes
|
RefuseManualStart=yes
|
||||||
Before=veritysetup.target
|
Before=veritysetup.target
|
||||||
|
@ -8,5 +8,5 @@
|
|||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
|
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Local Verity Integrity Protected Volumes
|
Description=Local Verity Protected Volumes
|
||||||
Documentation=man:systemd.special(7)
|
Documentation=man:systemd.special(7)
|
||||||
|
Loading…
Reference in New Issue
Block a user