1
0
mirror of https://github.com/systemd/systemd synced 2026-03-23 23:34:52 +01:00

Compare commits

..

No commits in common. "ceaa36c21e89aac1d9370b804ee74223bd96f943" and "875b568f56e3a8a23edd9f20463c9019ec098900" have entirely different histories.

25 changed files with 32 additions and 451 deletions

23
TODO
View File

@ -143,9 +143,6 @@ Features:
integrity tags are stored by the device (inline), interleaved with data (data),
and on a separate device (meta).
* homed/pam_systemd: allow authentication by ssh-agent, so that run0/polkit can
be allowed if caller comes with the right ssh-agent keys.
* networkd/machined: implement reverse name lookups in the resolved hook
* networkd's resolved hook: optionally map all lease IP addresses handed out to
@ -216,6 +213,10 @@ Features:
* similar: add a plugin for factory reset logic that erases certain parts of
the ESP, but leaves others in place.
* systemd-repart: add --defer-partitions-factory-reset or so, as a flavour of
--defer-partitions= that picks all partitions that are marked for factory
reset. for an installer this is usually the partitions not to copy, too.
* flush_fd() should probably try to be smart and stop reading once we know that
all further queued data was enqueued after flush_fd() was originally
called. For that, try SIOCINQ if fd refers to stream socket, and look at
@ -846,6 +847,8 @@ Features:
early on, but provide opt-out via kernel cmdline.
* systemd-pcrextend:
- support measuring to nvindex with PCR update semantics ("fake PCRs")
- add api for "allocating" such an nvindex
- once we have that start measuring every sysext we apply, every confext,
every RootImage= we apply, every nspawn and so on. All in separate fake
PCRs.
@ -860,6 +863,8 @@ Features:
- translate SIGTERM to clean ACPI shutdown event
- implement hotkeys ^]^]r and ^]^]p like nspawn
* systemd-pcrmachine should probably also measure the SMBIOS system UUID.
* storagetm:
- add USB mass storage device logic, so that all local disks are also exposed
as mass storage devices on systems that have a USB controller that can
@ -1264,6 +1269,10 @@ Features:
parametrization, if needed. This matches our usual rule that admin config
should win over vendor defaults.
* write a "search path" spec, that documents the prefixes to search in
(i.e. the usual /etc/, /run/, /usr/lib/ dance, potentially /usr/etc/), how to
sort found entries, how masking works and overriding.
* automatic boot assessment: add one more default success check that just waits
for a bit after boot, and blesses the boot if the system stayed up that long.
@ -1680,6 +1689,10 @@ Features:
(i.e. sysext, root verity) from those inherently local (i.e. encryption key),
which is useful if they shall be signed separately.
* in uefi stub: query firmware regarding which PCR banks are being used, store
that in EFI var. then use this when enrolling TPM2 in cryptsetup to verify
that the selected PCRs actually are used by firmware.
* rework recursive read-only remount to use new mount API
* when mounting disk images: if IMAGE_ID/IMAGE_VERSION is set in os-release
@ -1774,6 +1787,9 @@ Features:
* Figure out naming of verbs in systemd-analyze: we have (singular) capability,
exit-status, but (plural) filesystems, architectures.
* Add service setting to run a service within the specified VRF. i.e. do the
equivalent of "ip vrf exec".
* special case some calls of chase() to use openat2() internally, so
that the kernel does what we otherwise do.
@ -2264,6 +2280,7 @@ Features:
- allow Type=simple with PIDFile=
https://bugzilla.redhat.com/show_bug.cgi?id=723942
- allow writing multiple conditions in unit files on one line
- introduce Type=pid-file
- add a concept of RemainAfterExit= to scope units
- Allow multiple ExecStart= for all Type= settings, so that we can cover rescue.service nicely
- add verification of [Install] section to systemd-analyze verify

View File

@ -3037,8 +3037,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly (bas) RestrictNetworkInterfaces = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s BindNetworkInterface = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s MemoryPressureWatch = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryPressureThresholdUSec = ...;
@ -3706,8 +3704,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<!--property RestrictNetworkInterfaces is not documented!-->
<!--property BindNetworkInterface is not documented!-->
<!--property MemoryPressureWatch is not documented!-->
<!--property MemoryPressureThresholdUSec is not documented!-->
@ -4400,8 +4396,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<variablelist class="dbus-property" generated="True" extra-ref="RestrictNetworkInterfaces"/>
<variablelist class="dbus-property" generated="True" extra-ref="BindNetworkInterface"/>
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureWatch"/>
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureThresholdUSec"/>
@ -5300,8 +5294,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly (bas) RestrictNetworkInterfaces = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s BindNetworkInterface = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s MemoryPressureWatch = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryPressureThresholdUSec = ...;
@ -5987,8 +5979,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
<!--property RestrictNetworkInterfaces is not documented!-->
<!--property BindNetworkInterface is not documented!-->
<!--property MemoryPressureWatch is not documented!-->
<!--property MemoryPressureThresholdUSec is not documented!-->
@ -6657,8 +6647,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
<variablelist class="dbus-property" generated="True" extra-ref="RestrictNetworkInterfaces"/>
<variablelist class="dbus-property" generated="True" extra-ref="BindNetworkInterface"/>
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureWatch"/>
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureThresholdUSec"/>
@ -7381,8 +7369,6 @@ node /org/freedesktop/systemd1/unit/home_2emount {
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly (bas) RestrictNetworkInterfaces = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s BindNetworkInterface = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s MemoryPressureWatch = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryPressureThresholdUSec = ...;
@ -7992,8 +7978,6 @@ node /org/freedesktop/systemd1/unit/home_2emount {
<!--property RestrictNetworkInterfaces is not documented!-->
<!--property BindNetworkInterface is not documented!-->
<!--property MemoryPressureWatch is not documented!-->
<!--property MemoryPressureThresholdUSec is not documented!-->
@ -8570,8 +8554,6 @@ node /org/freedesktop/systemd1/unit/home_2emount {
<variablelist class="dbus-property" generated="True" extra-ref="RestrictNetworkInterfaces"/>
<variablelist class="dbus-property" generated="True" extra-ref="BindNetworkInterface"/>
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureWatch"/>
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureThresholdUSec"/>
@ -9427,8 +9409,6 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly (bas) RestrictNetworkInterfaces = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s BindNetworkInterface = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s MemoryPressureWatch = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryPressureThresholdUSec = ...;
@ -10020,8 +10000,6 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
<!--property RestrictNetworkInterfaces is not documented!-->
<!--property BindNetworkInterface is not documented!-->
<!--property MemoryPressureWatch is not documented!-->
<!--property MemoryPressureThresholdUSec is not documented!-->
@ -10580,8 +10558,6 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
<variablelist class="dbus-property" generated="True" extra-ref="RestrictNetworkInterfaces"/>
<variablelist class="dbus-property" generated="True" extra-ref="BindNetworkInterface"/>
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureWatch"/>
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureThresholdUSec"/>
@ -11290,8 +11266,6 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly (bas) RestrictNetworkInterfaces = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s BindNetworkInterface = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s MemoryPressureWatch = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryPressureThresholdUSec = ...;
@ -11469,8 +11443,6 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
<!--property RestrictNetworkInterfaces is not documented!-->
<!--property BindNetworkInterface is not documented!-->
<!--property MemoryPressureWatch is not documented!-->
<!--property MemoryPressureThresholdUSec is not documented!-->
@ -11663,8 +11635,6 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
<variablelist class="dbus-property" generated="True" extra-ref="RestrictNetworkInterfaces"/>
<variablelist class="dbus-property" generated="True" extra-ref="BindNetworkInterface"/>
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureWatch"/>
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureThresholdUSec"/>
@ -11880,8 +11850,6 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly (bas) RestrictNetworkInterfaces = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s BindNetworkInterface = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s MemoryPressureWatch = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t MemoryPressureThresholdUSec = ...;
@ -12073,8 +12041,6 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
<!--property RestrictNetworkInterfaces is not documented!-->
<!--property BindNetworkInterface is not documented!-->
<!--property MemoryPressureWatch is not documented!-->
<!--property MemoryPressureThresholdUSec is not documented!-->
@ -12291,8 +12257,6 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
<variablelist class="dbus-property" generated="True" extra-ref="RestrictNetworkInterfaces"/>
<variablelist class="dbus-property" generated="True" extra-ref="BindNetworkInterface"/>
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureWatch"/>
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureThresholdUSec"/>

View File

@ -11,7 +11,6 @@
<para id="controllers-text">The following controller names may be specified: <option>cpu</option>,
<option>cpuset</option>, <option>io</option>, <option>memory</option>, <option>pids</option>,
<option>bpf-firewall</option>, <option>bpf-devices</option>, <option>bpf-foreign</option>,
<option>bpf-socket-bind</option>, <option>bpf-restrict-network-interfaces</option>, and
<option>bpf-bind-network-interface</option>.</para>
<option>bpf-socket-bind</option>, and <option>bpf-restrict-network-interfaces</option>.</para>
</refsect1>

View File

@ -1023,33 +1023,6 @@ RestrictNetworkInterfaces=~eth1</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>BindNetworkInterface=</varname></term>
<listitem>
<para>Takes the name of a network interface. This option causes every socket created by processes of this
unit to be bound to the specified network interface.
</para>
<para>It is specially useful to confine a process to a VRF, when the program does not offer native support
for it. It is equivalent to running the program using <constant>ip vrf exec</constant>.
</para>
<para>In systems using <filename>nss-resolve</filename>, the interface used for DNS resolution can be chosen
by using the <varname>SYSTEMD_NSS_RESOLVE_IFINDEX</varname> environment variable.</para>
<para>The feature is implemented with <constant>cgroup/sock_create</constant> cgroup-bpf hooks.</para>
<para>Example:<programlisting>[Service]
BindNetworkInterface=vrf-mgmt
</programlisting></para>
<xi:include href="cgroup-sandboxing.xml" xpointer="singular"/>
<xi:include href="version-info.xml" xpointer="v260"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>NFTSet=</varname><replaceable>family</replaceable>:<replaceable>table</replaceable>:<replaceable>set</replaceable></term>
<listitem>

View File

@ -1771,7 +1771,6 @@ static const char *const cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = {
[CGROUP_CONTROLLER_BPF_FOREIGN] = "bpf-foreign",
[CGROUP_CONTROLLER_BPF_SOCKET_BIND] = "bpf-socket-bind",
[CGROUP_CONTROLLER_BPF_RESTRICT_NETWORK_INTERFACES] = "bpf-restrict-network-interfaces",
[CGROUP_CONTROLLER_BPF_BIND_NETWORK_INTERFACE] = "bpf-bind-network-interface",
};
DEFINE_STRING_TABLE_LOOKUP(cgroup_controller, CGroupController);

View File

@ -23,7 +23,6 @@ typedef enum CGroupController {
CGROUP_CONTROLLER_BPF_FOREIGN,
CGROUP_CONTROLLER_BPF_SOCKET_BIND,
CGROUP_CONTROLLER_BPF_RESTRICT_NETWORK_INTERFACES,
CGROUP_CONTROLLER_BPF_BIND_NETWORK_INTERFACE,
/* The BPF hook implementing RestrictFileSystems= is not defined here.
* It's applied as late as possible in exec_invoke() so we don't block
* our own unit setup code. */
@ -49,7 +48,6 @@ typedef enum CGroupMask {
CGROUP_MASK_BPF_FOREIGN = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_FOREIGN),
CGROUP_MASK_BPF_SOCKET_BIND = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_SOCKET_BIND),
CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_RESTRICT_NETWORK_INTERFACES),
CGROUP_MASK_BPF_BIND_NETWORK_INTERFACE = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_BIND_NETWORK_INTERFACE),
/* All real cgroup v1 controllers */
CGROUP_MASK_V1 = CGROUP_MASK_CPU|CGROUP_MASK_CPUACCT|CGROUP_MASK_BLKIO|CGROUP_MASK_MEMORY|CGROUP_MASK_DEVICES|CGROUP_MASK_PIDS,
@ -61,7 +59,7 @@ typedef enum CGroupMask {
CGROUP_MASK_DELEGATE = CGROUP_MASK_V2,
/* All cgroup v2 BPF pseudo-controllers */
CGROUP_MASK_BPF = CGROUP_MASK_BPF_FIREWALL|CGROUP_MASK_BPF_DEVICES|CGROUP_MASK_BPF_FOREIGN|CGROUP_MASK_BPF_SOCKET_BIND|CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES|CGROUP_MASK_BPF_BIND_NETWORK_INTERFACE,
CGROUP_MASK_BPF = CGROUP_MASK_BPF_FIREWALL|CGROUP_MASK_BPF_DEVICES|CGROUP_MASK_BPF_FOREIGN|CGROUP_MASK_BPF_SOCKET_BIND|CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES,
_CGROUP_MASK_ALL = CGROUP_CONTROLLER_TO_MASK(_CGROUP_CONTROLLER_MAX) - 1,
} CGroupMask;

View File

@ -969,8 +969,7 @@ int terminal_reset_ansi_seq(int fd) {
k = loop_write_full(fd,
"\033[!p" /* soft terminal reset */
ANSI_OSC "104" ANSI_ST /* reset color palette via OSC 104 */
ANSI_NORMAL /* reset colors */
"\033]104\007" /* reset colors */
"\033[?7h" /* enable line-wrapping */
"\033[1G" /* place cursor at beginning of current line */
"\033[0J", /* erase till end of screen */

View File

@ -1,146 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "sd-netlink.h"
#include "alloc-util.h"
#include "bpf-bind-iface.h"
#include "cgroup.h"
#include "fd-util.h"
#include "netlink-util.h"
#include "string-util.h"
#include "unit.h"
#if BPF_FRAMEWORK
/* 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"
static struct bind_iface_bpf *bind_iface_bpf_free(struct bind_iface_bpf *obj) {
bind_iface_bpf__destroy(obj);
return NULL;
}
DEFINE_TRIVIAL_CLEANUP_FUNC(struct bind_iface_bpf *, bind_iface_bpf_free);
int bpf_bind_network_interface_supported(void) {
_cleanup_(bind_iface_bpf_freep) struct bind_iface_bpf *obj = NULL;
static int supported = -1;
int r;
if (supported >= 0)
return supported;
if (dlopen_bpf_full(LOG_WARNING) < 0)
return (supported = false);
obj = bind_iface_bpf__open();
if (!obj) {
log_debug_errno(errno, "bind-interface: Failed to open BPF object: %m");
return (supported = false);
}
r = bind_iface_bpf__load(obj);
if (r != 0) {
log_debug_errno(r, "bind-interface: Failed to load BPF object: %m");
return (supported = false);
}
return (supported = bpf_can_link_program(obj->progs.sd_bind_interface));
}
int bpf_bind_network_interface_install(Unit *u) {
_cleanup_(bpf_link_freep) struct bpf_link *link = NULL;
_cleanup_(bind_iface_bpf_freep) struct bind_iface_bpf *obj = NULL;
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
_cleanup_free_ char *cgroup_path = NULL;
_cleanup_close_ int cgroup_fd = -EBADF;
CGroupContext *cc;
CGroupRuntime *crt;
int r, ifindex;
assert(u);
cc = unit_get_cgroup_context(u);
if (!cc)
return 0;
crt = unit_get_cgroup_runtime(u);
if (!crt)
return 0;
if (isempty(cc->bind_network_interface))
return 0;
r = cg_get_path(crt->cgroup_path, /* suffix = */ NULL, &cgroup_path);
if (r < 0)
return log_unit_error_errno(u, r, "bind-interface: Failed to get cgroup path: %m");
ifindex = rtnl_resolve_interface(&rtnl, cc->bind_network_interface);
if (ifindex < 0) {
log_unit_warning_errno(u, ifindex,
"bind-interface: Couldn't find index of network interface '%s', ignoring: %m",
cc->bind_network_interface);
return 0;
}
log_unit_debug(u, "bind-interface: Found index %d for network interface '%s'", ifindex, cc->bind_network_interface);
/* Open the BPF skeleton */
obj = bind_iface_bpf__open();
if (!obj)
return log_unit_error_errno(u, errno, "bind-interface: Failed to open BPF object: %m");
/* Set the VRF interface index in rodata before loading */
obj->rodata->ifindex = ifindex;
/* Load the BPF program */
r = bind_iface_bpf__load(obj);
if (r != 0)
return log_unit_error_errno(u, r, "bind-interface: Failed to load BPF object: %m");
/* Open the cgroup directory */
cgroup_fd = open(cgroup_path, O_PATH | O_CLOEXEC | O_DIRECTORY, 0);
if (cgroup_fd < 0)
return log_unit_error_errno(u, errno, "bind-interface: Failed to open cgroup directory '%s': %m", cgroup_path);
/* Attach the BPF program to the cgroup */
link = sym_bpf_program__attach_cgroup(obj->progs.sd_bind_interface, cgroup_fd);
r = bpf_get_error_translated(link);
if (r != 0)
return log_unit_error_errno(u, r, "bind-interface: Failed to create cgroup link: %m");
/* Store the link in CGroupRuntime */
crt->bpf_bind_network_interface_link = TAKE_PTR(link);
log_unit_debug(u, "bind-interface: Successfully installed VRF binding for interface '%s' (ifindex=%d)",
cc->bind_network_interface, ifindex);
return 0;
}
int bpf_bind_network_interface_serialize(Unit *u, FILE *f, FDSet *fds) {
CGroupRuntime *crt;
assert(u);
crt = unit_get_cgroup_runtime(u);
if (!crt)
return 0;
return bpf_serialize_link(f, fds, "bind-interface-fd", crt->bpf_bind_network_interface_link);
}
#else /* ! BPF_FRAMEWORK */
int bpf_bind_network_interface_supported(void) {
return 0;
}
int bpf_bind_network_interface_install(Unit *u) {
return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP),
"bind-interface: Failed to install; BPF framework is not supported");
}
int bpf_bind_network_interface_serialize(Unit *u, FILE *f, FDSet *fds) {
return 0;
}
#endif

View File

@ -1,9 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "core-forward.h"
int bpf_bind_network_interface_supported(void);
int bpf_bind_network_interface_install(Unit *u);
int bpf_bind_network_interface_serialize(Unit *u, FILE *f, FDSet *fds);

View File

@ -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 */

View File

@ -1,19 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/* <linux/bpf.h> must precede <bpf/bpf_helpers.h> due to integer types
* in bpf helpers signatures.
*/
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
/* VRF interface index to bind sockets to, set from userspace */
const volatile __u32 ifindex = 0;
SEC("cgroup/sock_create")
int sd_bind_interface(struct bpf_sock *ctx) {
/* Bind the socket to the VRF interface */
ctx->bound_dev_if = ifindex;
return 1;
}
static const char _license[] SEC("license") = "LGPL-2.1-or-later";

View File

@ -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

View File

@ -10,7 +10,6 @@
#include "af-list.h"
#include "alloc-util.h"
#include "blockdev-util.h"
#include "bpf-bind-iface.h"
#include "bpf-devices.h"
#include "bpf-firewall.h"
#include "bpf-foreign.h"
@ -269,8 +268,6 @@ void cgroup_context_done(CGroupContext *c) {
c->restrict_network_interfaces = set_free(c->restrict_network_interfaces);
c->bind_network_interface = mfree(c->bind_network_interface);
cpu_set_done(&c->cpuset_cpus);
cpu_set_done(&c->startup_cpuset_cpus);
cpu_set_done(&c->cpuset_mems);
@ -571,10 +568,6 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
fprintf(f, "%sDelegateSubgroup: %s\n",
prefix, c->delegate_subgroup);
if (!isempty(c->bind_network_interface))
fprintf(f, "%sBindNetworkInterface: %s\n",
prefix, c->bind_network_interface);
if (c->memory_pressure_threshold_usec != USEC_INFINITY)
fprintf(f, "%sMemoryPressureThresholdSec: %s\n",
prefix, FORMAT_TIMESPAN(c->memory_pressure_threshold_usec, 1));
@ -1376,12 +1369,6 @@ static void cgroup_apply_restrict_network_interfaces(Unit *u) {
(void) bpf_restrict_ifaces_install(u);
}
static void cgroup_apply_bind_network_interface(Unit *u) {
assert(u);
(void) bpf_bind_network_interface_install(u);
}
static int cgroup_apply_devices(Unit *u) {
_cleanup_(bpf_program_freep) BPFProgram *prog = NULL;
CGroupContext *c;
@ -1622,9 +1609,6 @@ static void cgroup_context_apply(
if (apply_mask & CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES)
cgroup_apply_restrict_network_interfaces(u);
if (apply_mask & CGROUP_MASK_BPF_BIND_NETWORK_INTERFACE)
cgroup_apply_bind_network_interface(u);
unit_modify_nft_set(u, /* add= */ true);
}
@ -1690,17 +1674,6 @@ static bool unit_get_needs_restrict_network_interfaces(Unit *u) {
return !set_isempty(c->restrict_network_interfaces);
}
static bool unit_get_needs_bind_network_interface(Unit *u) {
CGroupContext *c;
assert(u);
c = unit_get_cgroup_context(u);
if (!c)
return false;
return !isempty(c->bind_network_interface);
}
static CGroupMask unit_get_cgroup_mask(Unit *u) {
CGroupMask mask = 0;
CGroupContext *c;
@ -1753,9 +1726,6 @@ static CGroupMask unit_get_bpf_mask(Unit *u) {
if (unit_get_needs_restrict_network_interfaces(u))
mask |= CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES;
if (unit_get_needs_bind_network_interface(u))
mask |= CGROUP_MASK_BPF_BIND_NETWORK_INTERFACE;
return mask;
}
@ -3274,13 +3244,6 @@ static int cg_bpf_mask_supported(CGroupMask *ret) {
if (r > 0)
mask |= CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES;
/* BPF-based cgroup/sock_create hooks */
r = bpf_bind_network_interface_supported();
if (r < 0)
return r;
if (r > 0)
mask |= CGROUP_MASK_BPF_BIND_NETWORK_INTERFACE;
*ret = mask;
return 0;
}
@ -4230,10 +4193,7 @@ CGroupRuntime* cgroup_runtime_free(CGroupRuntime *crt) {
#if BPF_FRAMEWORK
bpf_link_free(crt->restrict_ifaces_ingress_bpf_link);
bpf_link_free(crt->restrict_ifaces_egress_bpf_link);
bpf_link_free(crt->bpf_bind_network_interface_link);
#endif
fdset_free(crt->initial_restrict_ifaces_link_fds);
bpf_firewall_close(crt);
@ -4357,8 +4317,6 @@ int cgroup_runtime_serialize(Unit *u, FILE *f, FDSet *fds) {
(void) bpf_restrict_ifaces_serialize(u, f, fds);
(void) bpf_bind_network_interface_serialize(u, f, fds);
return 0;
}

View File

@ -185,8 +185,6 @@ typedef struct CGroupContext {
LIST_HEAD(CGroupSocketBindItem, socket_bind_allow);
LIST_HEAD(CGroupSocketBindItem, socket_bind_deny);
char *bind_network_interface;
/* Common */
CGroupTasksMax tasks_max;
@ -334,12 +332,6 @@ typedef struct CGroupRuntime {
bool warned_clamping_cpu_quota_period:1;
int deserialized_cgroup_realized; /* tristate, for backwards compat */
#if BPF_FRAMEWORK
/* BPF link to BPF programs attached to cgroup/sock_create hooks and
* responsible for binding created sockets to a given VRF interface. */
struct bpf_link *bpf_bind_network_interface_link;
#endif
} CGroupRuntime;
uint64_t cgroup_context_cpu_weight(CGroupContext *c, ManagerState state);

View File

@ -429,7 +429,6 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
SD_BUS_PROPERTY("SocketBindAllow", "a(iiqq)", property_get_socket_bind, offsetof(CGroupContext, socket_bind_allow), 0),
SD_BUS_PROPERTY("SocketBindDeny", "a(iiqq)", property_get_socket_bind, offsetof(CGroupContext, socket_bind_deny), 0),
SD_BUS_PROPERTY("RestrictNetworkInterfaces", "(bas)", property_get_restrict_network_interfaces, 0, 0),
SD_BUS_PROPERTY("BindNetworkInterface", "s", NULL, offsetof(CGroupContext, bind_network_interface), 0),
SD_BUS_PROPERTY("MemoryPressureWatch", "s", bus_property_get_cgroup_pressure_watch, offsetof(CGroupContext, memory_pressure_watch), 0),
SD_BUS_PROPERTY("MemoryPressureThresholdUSec", "t", bus_property_get_usec, offsetof(CGroupContext, memory_pressure_threshold_usec), 0),
SD_BUS_PROPERTY("NFTSet", "a(iiss)", property_get_cgroup_nft_set, 0, 0),
@ -1951,31 +1950,6 @@ int bus_cgroup_set_property(
return 1;
}
if (streq(name, "BindNetworkInterface")) {
const char *s;
r = sd_bus_message_read(message, "s", &s);
if (r < 0)
return r;
if (!ifname_valid_full(s, IFNAME_VALID_ALTERNATIVE))
return sd_bus_error_setf(reterr_error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface name: %s", s);
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
if (isempty(s))
c->bind_network_interface = mfree(c->bind_network_interface);
else {
r = free_and_strdup_warn(&c->bind_network_interface, s);
if (r < 0)
return r;
}
unit_write_settingf(u, flags, name, "BindNetworkInterface=%s", strempty(s));
}
return 1;
}
if (streq(name, "NFTSet")) {
int source, nfproto;
const char *table, *set;

View File

@ -428,10 +428,6 @@ static int exec_cgroup_context_serialize(const CGroupContext *c, FILE *f) {
if (r < 0)
return r;
r = serialize_item(f, "exec-cgroup-context-bind-iface", c->bind_network_interface);
if (r < 0)
return r;
fputc('\n', f); /* End marker */
return 0;
@ -911,10 +907,6 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) {
if (r < 0)
return r;
c->restrict_network_interfaces_is_allow_list = r;
} else if ((val = startswith(l, "exec-cgroup-context-bind-iface="))) {
r = free_and_strdup(&c->bind_network_interface, val);
if (r < 0)
return r;
} else
log_warning("Failed to parse serialized line, ignoring: %s", l);
}

View File

@ -278,7 +278,6 @@
{{type}}.MemoryPressureWatch, config_parse_memory_pressure_watch, 0, offsetof({{type}}, cgroup_context.memory_pressure_watch)
{{type}}.NFTSet, config_parse_cgroup_nft_set, NFT_SET_PARSE_CGROUP, offsetof({{type}}, cgroup_context)
{{type}}.CoredumpReceive, config_parse_bool, 0, offsetof({{type}}, cgroup_context.coredump_receive)
{{type}}.BindNetworkInterface, config_parse_bind_network_interface, 0, offsetof({{type}}, cgroup_context)
{%- endmacro -%}
%{

View File

@ -5999,47 +5999,6 @@ int config_parse_concurrency_max(
return config_parse_unsigned(unit, filename, line, section, section_line, lvalue, ltype, rvalue, data, userdata);
}
int config_parse_bind_network_interface(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
CGroupContext *c = ASSERT_PTR(data);
_cleanup_free_ char *k = NULL;
const Unit *u = ASSERT_PTR(userdata);
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
c->bind_network_interface = mfree(c->bind_network_interface);
return 0;
}
r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
return 0;
}
if (!ifname_valid_full(k, IFNAME_VALID_ALTERNATIVE)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid interface name, ignoring: %s", k);
return 0;
}
return free_and_strdup_warn(&c->bind_network_interface, k);
}
static int merge_by_names(Unit *u, Set *names, const char *id) {
char *k;
int r;

View File

@ -167,7 +167,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_memory_pressure_watch);
CONFIG_PARSER_PROTOTYPE(config_parse_cgroup_nft_set);
CONFIG_PARSER_PROTOTYPE(config_parse_mount_node);
CONFIG_PARSER_PROTOTYPE(config_parse_concurrency_max);
CONFIG_PARSER_PROTOTYPE(config_parse_bind_network_interface);
/* gperf prototypes */
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, GPERF_LEN_TYPE length);

View File

@ -9,7 +9,6 @@ libcore_sources = files(
'bpf-restrict-fs.c',
'bpf-restrict-ifaces.c',
'bpf-socket-bind.c',
'bpf-bind-iface.c',
'cgroup.c',
'dbus-automount.c',
'dbus-cgroup.c',
@ -75,14 +74,12 @@ libcore_sources = files(
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]
restrict_ifaces_skel_h]
endif
sources += libcore_sources

View File

@ -2551,7 +2551,6 @@ static const BusProperty execute_properties[] = {
{ "StateDirectoryAccounting", bus_append_parse_boolean },
{ "CacheDirectoryAccounting", bus_append_parse_boolean },
{ "LogsDirectoryAccounting", bus_append_parse_boolean },
{ "BindNetworkInterface", bus_append_string },
{ NULL, bus_try_append_resource_limit, dump_resource_limits },
{}

View File

@ -131,6 +131,9 @@ static void pty_forward_disconnect(PTYForward *f) {
if (f->saved_stdout)
(void) tcsetattr(f->output_fd, TCSANOW, &f->saved_stdout_attr);
/* STDIN/STDOUT should not be non-blocking normally, so let's reset it */
(void) fd_nonblock(f->output_fd, false);
if (f->last_char_set && f->last_char != '\n') {
const char *s;
@ -151,9 +154,6 @@ static void pty_forward_disconnect(PTYForward *f) {
terminal_reset_ansi_seq(f->output_fd);
}
/* STDIN/STDOUT should not be non-blocking normally, so let's reset it */
(void) fd_nonblock(f->output_fd, false);
if (f->close_output_fd)
f->output_fd = safe_close(f->output_fd);
}

View File

@ -130,7 +130,7 @@ static void test_cg_mask_to_string_one(CGroupMask mask, const char *t) {
TEST(cg_mask_to_string) {
test_cg_mask_to_string_one(0, NULL);
test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct cpuset io blkio memory devices pids bpf-firewall bpf-devices bpf-foreign bpf-socket-bind bpf-restrict-network-interfaces bpf-bind-network-interface");
test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct cpuset io blkio memory devices pids bpf-firewall bpf-devices bpf-foreign bpf-socket-bind bpf-restrict-network-interfaces");
test_cg_mask_to_string_one(CGROUP_MASK_CPU, "cpu");
test_cg_mask_to_string_one(CGROUP_MASK_CPUACCT, "cpuacct");
test_cg_mask_to_string_one(CGROUP_MASK_CPUSET, "cpuset");

View File

@ -216,23 +216,6 @@ if ! systemd-detect-virt -cq; then
bash -xec 'timeout 1s ncat -6 -l ::1 1234; exit 1'
systemd-run --wait --pipe -p SuccessExitStatus=124 "${ARGUMENTS[@]}" \
bash -xec 'timeout 1s ncat -6 -l ::1 6666; exit 1'
# BindNetworkInterface*=
# Create a VRF interface to later bind to and check if the binding is working
ip link add vrf-test type vrf table 100
ip link set vrf-test up
ip address add 127.0.0.1/8 dev vrf-test
# Verify that a socket with BindNetworkInterface set is correctly bound to the interface
systemd-run --wait --pipe -p BindNetworkInterface=vrf-test \
bash -xec 'ncat -l 127.0.0.1 9999 & sleep 0.5; ss -tlnp | grep "127.0.0.1%vrf-test:9999" > /dev/null'
# Verify that a socket without BindNetworkInterface is not bound to any interface
systemd-run --wait --pipe \
bash -xec 'ncat -l 127.0.0.1 9998 & sleep 0.5; ss -tlnp | grep "127.0.0.1:9998" > /dev/null'
ip link del vrf-test
fi
losetup -d "$LODEV"

View File

@ -751,7 +751,6 @@ org.freedesktop.systemd1.Mount.AmbientCapabilities
org.freedesktop.systemd1.Mount.AppArmorProfile
org.freedesktop.systemd1.Mount.AttachProcesses()
org.freedesktop.systemd1.Mount.BPFProgram
org.freedesktop.systemd1.Mount.BindNetworkInterface
org.freedesktop.systemd1.Mount.BindPaths
org.freedesktop.systemd1.Mount.BindReadOnlyPaths
org.freedesktop.systemd1.Mount.BlockIOAccounting
@ -1019,7 +1018,6 @@ org.freedesktop.systemd1.Scope.AllowedCPUs
org.freedesktop.systemd1.Scope.AllowedMemoryNodes
org.freedesktop.systemd1.Scope.AttachProcesses()
org.freedesktop.systemd1.Scope.BPFProgram
org.freedesktop.systemd1.Scope.BindNetworkInterface
org.freedesktop.systemd1.Scope.BlockIOAccounting
org.freedesktop.systemd1.Scope.BlockIODeviceWeight
org.freedesktop.systemd1.Scope.BlockIOReadBandwidth
@ -1109,7 +1107,6 @@ org.freedesktop.systemd1.Service.AppArmorProfile
org.freedesktop.systemd1.Service.AttachProcesses()
org.freedesktop.systemd1.Service.BPFProgram
org.freedesktop.systemd1.Service.BindMount()
org.freedesktop.systemd1.Service.BindNetworkInterface
org.freedesktop.systemd1.Service.BindPaths
org.freedesktop.systemd1.Service.BindReadOnlyPaths
org.freedesktop.systemd1.Service.BlockIOAccounting
@ -1412,7 +1409,6 @@ org.freedesktop.systemd1.Slice.AllowedCPUs
org.freedesktop.systemd1.Slice.AllowedMemoryNodes
org.freedesktop.systemd1.Slice.AttachProcesses()
org.freedesktop.systemd1.Slice.BPFProgram
org.freedesktop.systemd1.Slice.BindNetworkInterface
org.freedesktop.systemd1.Slice.BlockIOAccounting
org.freedesktop.systemd1.Slice.BlockIODeviceWeight
org.freedesktop.systemd1.Slice.BlockIOReadBandwidth
@ -1491,7 +1487,6 @@ org.freedesktop.systemd1.Socket.AttachProcesses()
org.freedesktop.systemd1.Socket.BPFProgram
org.freedesktop.systemd1.Socket.Backlog
org.freedesktop.systemd1.Socket.BindIPv6Only
org.freedesktop.systemd1.Socket.BindNetworkInterface
org.freedesktop.systemd1.Socket.BindPaths
org.freedesktop.systemd1.Socket.BindReadOnlyPaths
org.freedesktop.systemd1.Socket.BindToDevice
@ -1791,7 +1786,6 @@ org.freedesktop.systemd1.Swap.AmbientCapabilities
org.freedesktop.systemd1.Swap.AppArmorProfile
org.freedesktop.systemd1.Swap.AttachProcesses()
org.freedesktop.systemd1.Swap.BPFProgram
org.freedesktop.systemd1.Swap.BindNetworkInterface
org.freedesktop.systemd1.Swap.BindPaths
org.freedesktop.systemd1.Swap.BindReadOnlyPaths
org.freedesktop.systemd1.Swap.BlockIOAccounting