1
0
mirror of https://github.com/systemd/systemd synced 2025-09-24 22:34:45 +02:00

Compare commits

..

No commits in common. "7b11770bae0653eb7c9c81f90ebc7324c25bf697" and "cf3317f63a24c17ca06a5c277171550c28ed7ef2" have entirely different histories.

27 changed files with 192 additions and 172 deletions

8
NEWS
View File

@ -698,10 +698,10 @@ CHANGES WITH 243:
the IO accounting data is included in the resource log message the IO accounting data is included in the resource log message
generated whenever a unit stops. generated whenever a unit stops.
* Units may now configure an explicit timeout to wait for when killed * Units may now configure an explicit time-out to wait for when killed
with SIGABRT, for example when a service watchdog is hit. Previously, with SIGABRT, for example when a service watchdog is hit. Previously,
the regular TimeoutStopSec= timeout was applied in this case too — the regular TimeoutStopSec= time-out was applied in this case too —
now a separate timeout may be set using TimeoutAbortSec=. now a separate time-out may be set using TimeoutAbortSec=.
* Services may now send a special WATCHDOG=trigger message with * Services may now send a special WATCHDOG=trigger message with
sd_notify() to trigger an immediate "watchdog missed" event, and thus sd_notify() to trigger an immediate "watchdog missed" event, and thus
@ -731,7 +731,7 @@ CHANGES WITH 243:
* If processes terminated during the last phase of shutdown do not exit * If processes terminated during the last phase of shutdown do not exit
quickly systemd will now show their names after a short time, to make quickly systemd will now show their names after a short time, to make
debugging easier. After a longer timeout they are forcibly killed, debugging easier. After a longer time-out they are forcibly killed,
as before. as before.
* journalctl (and the other tools that display logs) will now highlight * journalctl (and the other tools that display logs) will now highlight

2
TODO
View File

@ -37,8 +37,6 @@ Features:
* nspawn: support time namespaces * nspawn: support time namespaces
* add ConditionSecurity=tpm2
* pid1: Move to tracking of main pid/control pid of units per pidfd * pid1: Move to tracking of main pid/control pid of units per pidfd
* pid1: support new clone3() fork-into-cgroup feature * pid1: support new clone3() fork-into-cgroup feature

View File

@ -101,9 +101,9 @@ Here's an example walkthrough of how this all fits together.
6. If this boot also fails, on the next boot the boot loader will see the 6. If this boot also fails, on the next boot the boot loader will see the
tag `+0-3`, i.e. the counter reached zero. At this point the entry will be tag `+0-3`, i.e. the counter reached zero. At this point the entry will be
considered "bad", and ordered to the beginning of the list of entries. The considered "bad", and ordered to the end of the list of entries. The next
next newest boot entry is now tried, i.e. the system automatically reverted newest boot entry is now tried, i.e. the system automatically reverted back
back to an earlier version. to an earlier version.
The above describes the walkthrough when the selected boot entry continuously The above describes the walkthrough when the selected boot entry continuously
fails. Let's have a look at an alternative ending to this walkthrough. In this fails. Let's have a look at an alternative ending to this walkthrough. In this

View File

@ -145,7 +145,7 @@ systemd-udevd:
boot loader menu through EFI a file `/run/systemd/reboot-to-boot-loader-menu` boot loader menu through EFI a file `/run/systemd/reboot-to-boot-loader-menu`
is created whenever this is requested. The file contains the requested boot is created whenever this is requested. The file contains the requested boot
loader menu timeout in µs, formatted in ASCII decimals, or zero in case no loader menu timeout in µs, formatted in ASCII decimals, or zero in case no
timeout is requested. This file may be checked for by services run during time-out is requested. This file may be checked for by services run during
system shutdown in order to request the appropriate operation from the boot system shutdown in order to request the appropriate operation from the boot
loader in an alternative fashion. loader in an alternative fashion.

View File

@ -200,7 +200,7 @@ node /org/freedesktop/home1 {
the returned error code, in case more credentials are necessary. This function is synchronous and the returned error code, in case more credentials are necessary. This function is synchronous and
returns only after the home directory was fully activated (or the operation failed), which might take returns only after the home directory was fully activated (or the operation failed), which might take
some time. Clients must be prepared for that, and typically should extend the D-Bus method call some time. Clients must be prepared for that, and typically should extend the D-Bus method call
timeout accordingly. This method is equivalent to the <function>Activate()</function> method on the time-out accordingly. This method is equivalent to the <function>Activate()</function> method on the
<classname>org.freedesktop.home1.Home</classname> interface documented below, but may be called on the <classname>org.freedesktop.home1.Home</classname> interface documented below, but may be called on the
manager object and takes a user name as additional argument, instead.</para> manager object and takes a user name as additional argument, instead.</para>

View File

@ -3745,7 +3745,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<varname>ActiveState</varname> above). The following values are currently known: <varname>ActiveState</varname> above). The following values are currently known:
<literal>success</literal> is set if the unit didn't fail. <literal>resources</literal> indicates that <literal>success</literal> is set if the unit didn't fail. <literal>resources</literal> indicates that
not enough resources were available to fork off and execute the service not enough resources were available to fork off and execute the service
processes. <literal>timeout</literal> indicates that a timeout occurred while executing a service processes. <literal>timeout</literal> indicates that a time-out occurred while executing a service
operation. <literal>exit-code</literal> indicates that a service process exited with an unclean exit operation. <literal>exit-code</literal> indicates that a service process exited with an unclean exit
code. <literal>signal</literal> indicates that a service process exited with an uncaught code. <literal>signal</literal> indicates that a service process exited with an uncaught
signal. <literal>core-dump</literal> indicates that a service process exited uncleanly and dumped signal. <literal>core-dump</literal> indicates that a service process exited uncleanly and dumped

View File

@ -26,7 +26,7 @@
<refname>sd_bus_get_events</refname> <refname>sd_bus_get_events</refname>
<refname>sd_bus_get_timeout</refname> <refname>sd_bus_get_timeout</refname>
<refpurpose>Get the file descriptor, I/O events and timeout to wait for from a message bus <refpurpose>Get the file descriptor, I/O events and time-out to wait for from a message bus
object</refpurpose> object</refpurpose>
</refnamediv> </refnamediv>
@ -79,13 +79,13 @@
<constant>POLLIN</constant>, <constant>POLLOUT</constant>, … events, or negative on error. <constant>POLLIN</constant>, <constant>POLLOUT</constant>, … events, or negative on error.
</para> </para>
<para><function>sd_bus_get_timeout()</function> returns the timeout in µs to pass to to <para><function>sd_bus_get_timeout()</function> returns the time-out in µs to pass to to
<function>poll()</function> or a similar call when waiting for events on the specified bus <function>poll()</function> or a similar call when waiting for events on the specified bus
connection. The returned timeout may be zero, in which case a subsequent I/O polling call connection. The returned time-out may be zero, in which case a subsequent I/O polling call
should be invoked in non-blocking mode. The returned timeout may be should be invoked in non-blocking mode. The returned timeout may be
<constant>UINT64_MAX</constant> in which case the I/O polling call may block indefinitely, <constant>UINT64_MAX</constant> in which case the I/O polling call may block indefinitely,
without any applied timeout. Note that the returned timeout should be considered only a without any applied time-out. Note that the returned time-out should be considered only a
maximum sleeping time. It is permissible (and even expected) that shorter timeouts are used by maximum sleeping time. It is permissible (and even expected) that shorter time-outs are used by
the calling program, in case other event sources are polled in the same event loop. Note that the calling program, in case other event sources are polled in the same event loop. Note that
the returned time-value is relative and specified in microseconds. When converting this value in the returned time-value is relative and specified in microseconds. When converting this value in
order to pass it as third argument to <function>poll()</function> (which expects milliseconds), order to pass it as third argument to <function>poll()</function> (which expects milliseconds),
@ -93,7 +93,7 @@
doesn't sleep for shorter than necessary, which might result in unintended busy looping doesn't sleep for shorter than necessary, which might result in unintended busy looping
(alternatively, use (alternatively, use
<citerefentry project='man-pages'><refentrytitle>ppoll</refentrytitle><manvolnum>3</manvolnum></citerefentry> <citerefentry project='man-pages'><refentrytitle>ppoll</refentrytitle><manvolnum>3</manvolnum></citerefentry>
instead of plain <function>poll()</function>, which understands timeouts with nano-second instead of plain <function>poll()</function>, which understands time-outs with nano-second
granularity).</para> granularity).</para>
<para>These three functions are useful to hook up a bus connection object with an external or <para>These three functions are useful to hook up a bus connection object with an external or
@ -101,7 +101,7 @@
each invocation of the I/O polling call, all three functions should be invoked: the file each invocation of the I/O polling call, all three functions should be invoked: the file
descriptor returned by <function>sd_bus_get_fd()</function> should be polled for the events descriptor returned by <function>sd_bus_get_fd()</function> should be polled for the events
indicated by <function>sd_bus_get_events()</function>, and the I/O call should block for that up indicated by <function>sd_bus_get_events()</function>, and the I/O call should block for that up
to the timeout returned by <function>sd_bus_get_timeout()</function>. After each I/O polling to the time-out returned by <function>sd_bus_get_timeout()</function>. After each I/O polling
call the bus connection needs to process incoming or outgoing data, by invoking call the bus connection needs to process incoming or outgoing data, by invoking
<citerefentry><refentrytitle>sd_bus_process</refentrytitle><manvolnum>3</manvolnum></citerefentry>. <citerefentry><refentrytitle>sd_bus_process</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
</para> </para>

View File

@ -2100,8 +2100,8 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<listitem> <listitem>
<para>When used with the <command>reboot</command> command, indicate to the system's boot loader to show the <para>When used with the <command>reboot</command> command, indicate to the system's boot loader to show the
boot loader menu on the following boot. Takes a time value as parameter — indicating the menu timeout. Pass boot loader menu on the following boot. Takes a time value as parameter — indicating the menu time-out. Pass
zero in order to disable the menu timeout. Note that not all boot loaders support this zero in order to disable the menu time-out. Note that not all boot loaders support this
functionality.</para> functionality.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -476,10 +476,10 @@
considered 'good' from then on.</para> considered 'good' from then on.</para>
<para>The boot menu takes the 'tries left' counter into account when sorting the menu entries: entries in 'bad' <para>The boot menu takes the 'tries left' counter into account when sorting the menu entries: entries in 'bad'
state are ordered at the beginning of the list, and entries in 'good' or 'indeterminate' at the end. The user can state are ordered at the end of the list, and entries in 'good' or 'indeterminate' at the beginning. The user can
freely choose to boot any entry of the menu, including those already marked 'bad'. If the menu entry to boot is freely choose to boot any entry of the menu, including those already marked 'bad'. If the menu entry to boot is
automatically determined, this means that 'good' or 'indeterminate' entries are generally preferred (as the bottom automatically determined, this means that 'good' or 'indeterminate' entries are generally preferred (as the top item of
item of the menu is the one booted by default), and 'bad' entries will only be considered if there are no 'good' or the menu is the one booted by default), and 'bad' entries will only be considered if there are no 'good' or
'indeterminate' entries left.</para> 'indeterminate' entries left.</para>
<para>The <citerefentry><refentrytitle>kernel-install</refentrytitle><manvolnum>8</manvolnum></citerefentry> kernel <para>The <citerefentry><refentrytitle>kernel-install</refentrytitle><manvolnum>8</manvolnum></citerefentry> kernel

View File

@ -1098,8 +1098,8 @@ StateDirectory=aaa/bbb ccc</programlisting>
clean …</command>, see clean …</command>, see
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> for <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
details. Takes the usual time values and defaults to <constant>infinity</constant>, i.e. by default details. Takes the usual time values and defaults to <constant>infinity</constant>, i.e. by default
no timeout is applied. If a timeout is configured the clean operation will be aborted forcibly when no time-out is applied. If a time-out is configured the clean operation will be aborted forcibly when
the timeout is reached, potentially leaving resources on disk.</para></listitem> the time-out is reached, potentially leaving resources on disk.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>

View File

@ -571,29 +571,29 @@
<term><varname>IPAddressDeny=<replaceable>ADDRESS[/PREFIXLENGTH]…</replaceable></varname></term> <term><varname>IPAddressDeny=<replaceable>ADDRESS[/PREFIXLENGTH]…</replaceable></varname></term>
<listitem> <listitem>
<para>Turn on network traffic filtering for IP packets sent and received over <para>Turn on address range network traffic filtering for IP packets sent and received over
<constant>AF_INET</constant> and <constant>AF_INET6</constant> sockets. Both directives take a <constant>AF_INET</constant> and <constant>AF_INET6</constant> sockets. Both directives take a
space separated list of IPv4 or IPv6 addresses, each optionally suffixed with an address prefix space separated list of IPv4 or IPv6 addresses, each optionally suffixed with an address prefix
length in bits after a <literal>/</literal> character. If the suffix is omitted, the address is length in bits (separated by a <literal>/</literal> character). If the latter is omitted, the
considered a host address, i.e. the filter covers the whole address (32 bits for IPv4, 128 bits for address is considered a host address, i.e. the prefix covers the whole address (32 for IPv4, 128
IPv6).</para> for IPv6).</para>
<para>The access lists configured with this option are applied to all sockets created by processes <para>The access lists configured with this option are applied to all sockets created by processes
of this unit (or in the case of socket units, associated with it). The lists are implicitly of this unit (or in the case of socket units, associated with it). The lists are implicitly
combined with any lists configured for any of the parent slice units this unit might be a member combined with any lists configured for any of the parent slice units this unit might be a member
of. By default both access lists are empty. Both ingress and egress traffic is filtered by these of. By default all access lists are empty. Both ingress and egress traffic is filtered by these
settings. In case of ingress traffic the source IP address is checked against these access lists, settings. In case of ingress traffic the source IP address is checked against these access lists,
in case of egress traffic the destination IP address is checked. The following rules are applied in in case of egress traffic the destination IP address is checked. When configured the lists are
turn:</para> enforced as follows:</para>
<itemizedlist> <itemizedlist>
<listitem><para>Access is granted when the checked IP address matches an entry in the <listitem><para>Access will be granted in case an IP packet's destination/source address matches
<varname>IPAddressAllow=</varname> list.</para></listitem> any entry in the <varname>IPAddressAllow=</varname> setting.</para></listitem>
<listitem><para>Otherwise, access is denied when the checked IP address matches an entry in the <listitem><para>Otherwise, access will be denied in case its destination/source address matches
<varname>IPAddressDeny=</varname> list.</para></listitem> any entry in the <varname>IPAddressDeny=</varname> setting.</para></listitem>
<listitem><para>Otherwise, access is granted.</para></listitem> <listitem><para>Otherwise, access will be granted.</para></listitem>
</itemizedlist> </itemizedlist>
<para>In order to implement a whitelisting IP firewall, it is recommended to use a <para>In order to implement a whitelisting IP firewall, it is recommended to use a
@ -604,13 +604,12 @@
details on these slice units), plus individual per-service <varname>IPAddressAllow=</varname> lines details on these slice units), plus individual per-service <varname>IPAddressAllow=</varname> lines
permitting network access to relevant services, and only them.</para> permitting network access to relevant services, and only them.</para>
<para>Note that for socket-activated services, the IP access list configured on the socket unit <para>Note that for socket-activated services, the IP access list configured on the socket unit applies to
applies to all sockets associated with it directly, but not to any sockets created by the all sockets associated with it directly, but not to any sockets created by the ultimately activated services
ultimately activated services for it. Conversely, the IP access list configured for the service is for it. Conversely, the IP access list configured for the service is not applied to any sockets passed into
not applied to any sockets passed into the service via socket activation. Thus, it is usually a the service via socket activation. Thus, it is usually a good idea, to replicate the IP access lists on both
good idea to replicate the IP access lists on both the socket and the service unit. Nevertheless, the socket and the service unit, however it often makes sense to maintain one list more open and the other
it may make sense to maintain one list more open and the other one more restricted, depending on one more restricted, depending on the usecase.</para>
the usecase.</para>
<para>If these settings are used multiple times in the same unit the specified lists are combined. If an <para>If these settings are used multiple times in the same unit the specified lists are combined. If an
empty string is assigned to these settings the specific access list is reset and all previous settings undone.</para> empty string is assigned to these settings the specific access list is reset and all previous settings undone.</para>

View File

@ -464,7 +464,7 @@
of the daemon, and may be used for command lines like the of the daemon, and may be used for command lines like the
following:</para> following:</para>
<programlisting>ExecReload=kill -HUP $MAINPID</programlisting> <programlisting>/bin/kill -HUP $MAINPID</programlisting>
<para>Note however that reloading a daemon by sending a signal <para>Note however that reloading a daemon by sending a signal
(as with the example line above) is usually not a good choice, (as with the example line above) is usually not a good choice,
@ -473,14 +473,7 @@
other. It is strongly recommended to set other. It is strongly recommended to set
<varname>ExecReload=</varname> to a command that not only <varname>ExecReload=</varname> to a command that not only
triggers a configuration reload of the daemon, but also triggers a configuration reload of the daemon, but also
synchronously waits for it to complete. For example, synchronously waits for it to complete.</para>
<citerefentry project='mankier'><refentrytitle>dbus-broker</refentrytitle><manvolnum>1</manvolnum></citerefentry>
uses the following:</para>
<programlisting>ExecReload=busctl call org.freedesktop.DBus \
/org/freedesktop/DBus org.freedesktop.DBus \
ReloadConfig
</programlisting>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -43,3 +43,18 @@ disable syslog.socket
disable systemd-journal-gatewayd.* disable systemd-journal-gatewayd.*
disable systemd-journal-remote.* disable systemd-journal-remote.*
disable systemd-journal-upload.* disable systemd-journal-upload.*
# Passive targets: always off by default, since they should only be pulled in
# by dependent units.
disable cryptsetup-pre.target
disable getty-pre.target
disable local-fs-pre.target
disable network.target
disable network-pre.target
disable nss-lookup.target
disable nss-user-lookup.target
disable remote-fs-pre.target
disable rpcbind.target
disable time-set.target
disable time-sync.target

View File

@ -13,3 +13,9 @@
enable systemd-tmpfiles-setup.service enable systemd-tmpfiles-setup.service
enable systemd-tmpfiles-clean.timer enable systemd-tmpfiles-clean.timer
# Passive targets: always off by default, since they should only be pulled in
# by dependent units.
disable graphical-session-pre.target
disable graphical-session.target

View File

@ -927,12 +927,9 @@ static int qgroup_create_or_destroy(int fd, bool b, uint64_t qgroupid) {
for (c = 0;; c++) { for (c = 0;; c++) {
if (ioctl(fd, BTRFS_IOC_QGROUP_CREATE, &args) < 0) { if (ioctl(fd, BTRFS_IOC_QGROUP_CREATE, &args) < 0) {
/* On old kernels if quota is not enabled, we get EINVAL. On newer kernels we get /* If quota is not enabled, we get EINVAL. Turn this into a recognizable error */
* ENOTCONN. Let's always convert this to ENOTCONN to make this recognizable if (errno == EINVAL)
* everywhere the same way. */ return -ENOPROTOOPT;
if (IN_SET(errno, EINVAL, ENOTCONN))
return -ENOTCONN;
if (errno == EBUSY && c < 10) { if (errno == EBUSY && c < 10) {
(void) btrfs_quota_scan_wait(fd); (void) btrfs_quota_scan_wait(fd);

View File

@ -206,87 +206,11 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
return 0; return 0;
} }
static int update_argv(const char name[], size_t l) { int rename_process(const char name[]) {
static int can_do = -1;
if (can_do == 0)
return 0;
can_do = false; /* We'll set it to true only if the whole process works */
/* Let's not bother with this if we don't have euid == 0. Strictly speaking we should check for the
* CAP_SYS_RESOURCE capability which is independent of the euid. In our own code the capability generally is
* present only for euid == 0, hence let's use this as quick bypass check, to avoid calling mmap() if
* PR_SET_MM_ARG_{START,END} fails with EPERM later on anyway. After all geteuid() is dead cheap to call, but
* mmap() is not. */
if (geteuid() != 0)
return log_debug_errno(SYNTHETIC_ERRNO(EPERM),
"Skipping PR_SET_MM, as we don't have privileges.");
static size_t mm_size = 0; static size_t mm_size = 0;
static char *mm = NULL; static char *mm = NULL;
int r;
if (mm_size < l+1) {
size_t nn_size;
char *nn;
nn_size = PAGE_ALIGN(l+1);
nn = mmap(NULL, nn_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (nn == MAP_FAILED)
return log_debug_errno(errno, "mmap() failed: %m");
strncpy(nn, name, nn_size);
/* Now, let's tell the kernel about this new memory */
if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0) {
if (ERRNO_IS_PRIVILEGE(errno))
return log_debug_errno(errno, "PR_SET_MM_ARG_START failed: %m");
/* HACK: prctl() API is kind of dumb on this point. The existing end address may already be
* below the desired start address, in which case the kernel may have kicked this back due
* to a range-check failure (see linux/kernel/sys.c:validate_prctl_map() to see this in
* action). The proper solution would be to have a prctl() API that could set both start+end
* simultaneously, or at least let us query the existing address to anticipate this condition
* and respond accordingly. For now, we can only guess at the cause of this failure and try
* a workaround--which will briefly expand the arg space to something potentially huge before
* resizing it to what we want. */
log_debug_errno(errno, "PR_SET_MM_ARG_START failed, attempting PR_SET_MM_ARG_END hack: %m");
if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0) < 0) {
r = log_debug_errno(errno, "PR_SET_MM_ARG_END hack failed, proceeding without: %m");
(void) munmap(nn, nn_size);
return r;
}
if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0)
return log_debug_errno(errno, "PR_SET_MM_ARG_START still failed, proceeding without: %m");
} else {
/* And update the end pointer to the new end, too. If this fails, we don't really know what
* to do, it's pretty unlikely that we can rollback, hence we'll just accept the failure,
* and continue. */
if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0) < 0)
log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m");
}
if (mm)
(void) munmap(mm, mm_size);
mm = nn;
mm_size = nn_size;
} else {
strncpy(mm, name, mm_size);
/* Update the end pointer, continuing regardless of any failure. */
if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) mm + l + 1, 0, 0) < 0)
log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m");
}
can_do = true;
return 0;
}
int rename_process(const char name[]) {
bool truncated = false; bool truncated = false;
size_t l;
/* This is a like a poor man's setproctitle(). It changes the comm field, argv[0], and also the glibc's /* This is a like a poor man's setproctitle(). It changes the comm field, argv[0], and also the glibc's
* internally used name of the process. For the first one a limit of 16 chars applies; to the second one in * internally used name of the process. For the first one a limit of 16 chars applies; to the second one in
@ -304,7 +228,7 @@ int rename_process(const char name[]) {
* cache things without locking, and we make assumptions that PR_SET_NAME sets the * cache things without locking, and we make assumptions that PR_SET_NAME sets the
* process name that isn't correct on any other threads */ * process name that isn't correct on any other threads */
size_t l = strlen(name); l = strlen(name);
/* First step, change the comm field. The main thread's comm is identical to the process comm. This means we /* First step, change the comm field. The main thread's comm is identical to the process comm. This means we
* can use PR_SET_NAME, which sets the thread name for the calling thread. */ * can use PR_SET_NAME, which sets the thread name for the calling thread. */
@ -326,11 +250,77 @@ int rename_process(const char name[]) {
/* Third step, completely replace the argv[] array the kernel maintains for us. This requires privileges, but /* Third step, completely replace the argv[] array the kernel maintains for us. This requires privileges, but
* has the advantage that the argv[] array is exactly what we want it to be, and not filled up with zeros at * has the advantage that the argv[] array is exactly what we want it to be, and not filled up with zeros at
* the end. This is the best option for changing /proc/self/cmdline. */ * the end. This is the best option for changing /proc/self/cmdline. */
(void) update_argv(name, l);
/* Let's not bother with this if we don't have euid == 0. Strictly speaking we should check for the
* CAP_SYS_RESOURCE capability which is independent of the euid. In our own code the capability generally is
* present only for euid == 0, hence let's use this as quick bypass check, to avoid calling mmap() if
* PR_SET_MM_ARG_{START,END} fails with EPERM later on anyway. After all geteuid() is dead cheap to call, but
* mmap() is not. */
if (geteuid() != 0)
log_debug("Skipping PR_SET_MM, as we don't have privileges.");
else if (mm_size < l+1) {
size_t nn_size;
char *nn;
nn_size = PAGE_ALIGN(l+1);
nn = mmap(NULL, nn_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (nn == MAP_FAILED) {
log_debug_errno(errno, "mmap() failed: %m");
goto use_saved_argv;
}
strncpy(nn, name, nn_size);
/* Now, let's tell the kernel about this new memory */
if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0) {
/* HACK: prctl() API is kind of dumb on this point. The existing end address may already be
* below the desired start address, in which case the kernel may have kicked this back due
* to a range-check failure (see linux/kernel/sys.c:validate_prctl_map() to see this in
* action). The proper solution would be to have a prctl() API that could set both start+end
* simultaneously, or at least let us query the existing address to anticipate this condition
* and respond accordingly. For now, we can only guess at the cause of this failure and try
* a workaround--which will briefly expand the arg space to something potentially huge before
* resizing it to what we want. */
log_debug_errno(errno, "PR_SET_MM_ARG_START failed, attempting PR_SET_MM_ARG_END hack: %m");
if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0) < 0) {
log_debug_errno(errno, "PR_SET_MM_ARG_END hack failed, proceeding without: %m");
(void) munmap(nn, nn_size);
goto use_saved_argv;
}
if (prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long) nn, 0, 0) < 0) {
log_debug_errno(errno, "PR_SET_MM_ARG_START still failed, proceeding without: %m");
goto use_saved_argv;
}
} else {
/* And update the end pointer to the new end, too. If this fails, we don't really know what
* to do, it's pretty unlikely that we can rollback, hence we'll just accept the failure,
* and continue. */
if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) nn + l + 1, 0, 0) < 0)
log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m");
}
if (mm)
(void) munmap(mm, mm_size);
mm = nn;
mm_size = nn_size;
} else {
strncpy(mm, name, mm_size);
/* Update the end pointer, continuing regardless of any failure. */
if (prctl(PR_SET_MM, PR_SET_MM_ARG_END, (unsigned long) mm + l + 1, 0, 0) < 0)
log_debug_errno(errno, "PR_SET_MM_ARG_END failed, proceeding without: %m");
}
use_saved_argv:
/* Fourth step: in all cases we'll also update the original argv[], so that our own code gets it right too if /* Fourth step: in all cases we'll also update the original argv[], so that our own code gets it right too if
* it still looks here */ * it still looks here */
if (saved_argc > 0) { if (saved_argc > 0) {
int i;
if (saved_argv[0]) { if (saved_argv[0]) {
size_t k; size_t k;
@ -340,7 +330,7 @@ int rename_process(const char name[]) {
truncated = true; truncated = true;
} }
for (int i = 1; i < saved_argc; i++) { for (i = 1; i < saved_argc; i++) {
if (!saved_argv[i]) if (!saved_argv[i])
break; break;

View File

@ -1519,11 +1519,11 @@ static VOID config_load_entries(
static INTN config_entry_compare(ConfigEntry *a, ConfigEntry *b) { static INTN config_entry_compare(ConfigEntry *a, ConfigEntry *b) {
INTN r; INTN r;
/* Order entries that have no tries left to the beginning of the list */ /* Order entries that have no tries left to the end of the list */
if (a->tries_left != 0 && b->tries_left == 0) if (a->tries_left != 0 && b->tries_left == 0)
return 1;
if (a->tries_left == 0 && b->tries_left != 0)
return -1; return -1;
if (a->tries_left == 0 && b->tries_left != 0)
return 1;
r = str_verscmp(a->id, b->id); r = str_verscmp(a->id, b->id);
if (r != 0) if (r != 0)
@ -1533,17 +1533,17 @@ static INTN config_entry_compare(ConfigEntry *a, ConfigEntry *b) {
b->tries_left == (UINTN) -1) b->tries_left == (UINTN) -1)
return 0; return 0;
/* If both items have boot counting, and otherwise are identical, put the entry with more tries left last */ /* If both items have boot counting, and otherwise are identical, put the entry with more tries left first */
if (a->tries_left > b->tries_left) if (a->tries_left > b->tries_left)
return 1;
if (a->tries_left < b->tries_left)
return -1; return -1;
if (a->tries_left < b->tries_left)
return 1;
/* If they have the same number of tries left, then let the one win which was tried fewer times so far */ /* If they have the same number of tries left, then let the one win which was tried fewer times so far */
if (a->tries_done < b->tries_done) if (a->tries_done < b->tries_done)
return 1;
if (a->tries_done > b->tries_done)
return -1; return -1;
if (a->tries_done > b->tries_done)
return 1;
return 0; return 0;
} }

View File

@ -19,7 +19,7 @@ int split_user_name_realm(const char *t, char **ret_user_name, char **ret_realm)
int bus_message_append_secret(sd_bus_message *m, UserRecord *secret); int bus_message_append_secret(sd_bus_message *m, UserRecord *secret);
/* Many of our operations might be slow due to crypto, fsck, recursive chown() and so on. For these /* Many of our operations might be slow due to crypto, fsck, recursive chown() and so on. For these
* operations permit a *very* long timeout */ * operations permit a *very* long time-out */
#define HOME_SLOW_BUS_CALL_TIMEOUT_USEC (2*USEC_PER_MINUTE) #define HOME_SLOW_BUS_CALL_TIMEOUT_USEC (2*USEC_PER_MINUTE)
int test_password_one(const char *hashed_password, const char *password); int test_password_one(const char *hashed_password, const char *password);

View File

@ -1718,7 +1718,7 @@ static int wait_for_devlink(const char *path) {
usec_t until; usec_t until;
int r; int r;
/* let's wait for a device link to show up in /dev, with a timeout. This is good to do since we /* let's wait for a device link to show up in /dev, with a time-out. This is good to do since we
* return a /dev/disk/by-uuid/ link to our callers and they likely want to access it right-away, * return a /dev/disk/by-uuid/ link to our callers and they likely want to access it right-away,
* hence let's wait until udev has caught up with our changes, and wait for the symlink to be * hence let's wait until udev has caught up with our changes, and wait for the symlink to be
* created. */ * created. */

View File

@ -212,6 +212,31 @@ static DnsTransactionState dns_query_candidate_state(DnsQueryCandidate *c) {
return state; return state;
} }
static bool dns_query_candidate_is_routable(DnsQueryCandidate *c, uint16_t type) {
int family;
assert(c);
/* Checks whether the specified RR type matches an address family that is routable on the link(s) the scope of
* this candidate belongs to. Specifically, whether there's a routable IPv4 address on it if we query an A RR,
* or a routable IPv6 address if we query an AAAA RR. */
if (!c->query->suppress_unroutable_family)
return true;
if (c->scope->protocol != DNS_PROTOCOL_DNS)
return true;
family = dns_type_to_af(type);
if (family < 0)
return true;
if (c->scope->link)
return link_relevant(c->scope->link, family, false);
else
return manager_routable(c->scope->manager, family);
}
static int dns_query_candidate_setup_transactions(DnsQueryCandidate *c) { static int dns_query_candidate_setup_transactions(DnsQueryCandidate *c) {
DnsQuestion *question; DnsQuestion *question;
DnsResourceKey *key; DnsResourceKey *key;
@ -228,6 +253,9 @@ static int dns_query_candidate_setup_transactions(DnsQueryCandidate *c) {
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *new_key = NULL; _cleanup_(dns_resource_key_unrefp) DnsResourceKey *new_key = NULL;
DnsResourceKey *qkey; DnsResourceKey *qkey;
if (!dns_query_candidate_is_routable(c, key->type))
continue;
if (c->search_domain) { if (c->search_domain) {
r = dns_resource_key_new_append_suffix(&new_key, key, c->search_domain->name); r = dns_resource_key_new_append_suffix(&new_key, key, c->search_domain->name);
if (r < 0) if (r < 0)

View File

@ -29,8 +29,7 @@ const GptPartitionType gpt_partition_type_table[] = {
{ GPT_SRV, "srv" }, { GPT_SRV, "srv" },
{ GPT_VAR, "var" }, { GPT_VAR, "var" },
{ GPT_TMP, "tmp" }, { GPT_TMP, "tmp" },
{ GPT_USER_HOME, "user-home" }, { GPT_LINUX_GENERIC, "linux-generic", },
{ GPT_LINUX_GENERIC, "linux-generic" },
{} {}
}; };

View File

@ -134,7 +134,7 @@ int nscd_flush_cache(char **databases) {
int r = 0; int r = 0;
char **i; char **i;
/* Tries to invalidate the specified database in nscd. We do this carefully, with a 5s timeout, so that we /* Tries to invalidate the specified database in nscd. We do this carefully, with a 5s time-out, so that we
* don't block indefinitely on another service. */ * don't block indefinitely on another service. */
end = usec_add(now(CLOCK_MONOTONIC), NSCD_FLUSH_CACHE_TIMEOUT_USEC); end = usec_add(now(CLOCK_MONOTONIC), NSCD_FLUSH_CACHE_TIMEOUT_USEC);

View File

@ -1265,7 +1265,7 @@ static int path_set_attribute(Item *item, const char *path) {
static int write_one_file(Item *i, const char *path) { static int write_one_file(Item *i, const char *path) {
_cleanup_close_ int fd = -1, dir_fd = -1; _cleanup_close_ int fd = -1, dir_fd = -1;
char *bn; char *bn;
int r; int flags, r;
assert(i); assert(i);
assert(path); assert(path);
@ -1280,19 +1280,15 @@ static int write_one_file(Item *i, const char *path) {
bn = basename(path); bn = basename(path);
flags = O_NONBLOCK|O_CLOEXEC|O_WRONLY|O_NOCTTY;
/* Follows symlinks */ /* Follows symlinks */
fd = openat(dir_fd, bn, fd = openat(dir_fd, bn, i->append_or_force ? flags|O_APPEND : flags, i->mode);
O_NONBLOCK|O_CLOEXEC|O_WRONLY|O_NOCTTY|(i->append_or_force ? O_APPEND : 0),
i->mode);
if (fd < 0) { if (fd < 0) {
if (errno == ENOENT) { if (errno == ENOENT) {
log_debug_errno(errno, "Not writing missing file \"%s\": %m", path); log_debug_errno(errno, "Not writing missing file \"%s\": %m", path);
return 0; return 0;
} }
if (i->allow_failure)
return log_debug_errno(errno, "Failed to open file \"%s\", ignoring: %m", path);
return log_error_errno(errno, "Failed to open file \"%s\": %m", path); return log_error_errno(errno, "Failed to open file \"%s\": %m", path);
} }
@ -1629,7 +1625,7 @@ static int create_subvolume(Item *i, const char *path) {
log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (unsupported fs or dir not a subvolume): %m", i->path); log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (unsupported fs or dir not a subvolume): %m", i->path);
else if (r == -EROFS) else if (r == -EROFS)
log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (fs is read-only).", i->path); log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (fs is read-only).", i->path);
else if (r == -ENOTCONN) else if (r == -ENOPROTOOPT)
log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (quota support is disabled).", i->path); log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (quota support is disabled).", i->path);
else if (r < 0) else if (r < 0)
q = log_error_errno(r, "Failed to adjust quota for subvolume \"%s\": %m", i->path); q = log_error_errno(r, "Failed to adjust quota for subvolume \"%s\": %m", i->path);

View File

@ -715,8 +715,7 @@ static int run(int argc, char *argv[]) {
n = now(CLOCK_MONOTONIC); n = now(CLOCK_MONOTONIC);
if (n >= usec_add(start_time, RUNTIME_MAX_USEC)) { if (n >= usec_add(start_time, RUNTIME_MAX_USEC)) {
char buf[FORMAT_TIMESPAN_MAX]; char buf[FORMAT_TIMESPAN_MAX];
log_debug("Exiting worker, ran for %s, that's enough.", log_debug("Exiting worker, ran for %s, that's enough.", format_timespan(buf, sizeof(buf), usec_sub_unsigned(n, start_time), 0));
format_timespan(buf, sizeof(buf), usec_sub_unsigned(n, start_time), 0));
break; break;
} }
@ -724,8 +723,7 @@ static int run(int argc, char *argv[]) {
last_busy_usec = n; last_busy_usec = n;
else if (listen_idle_usec != USEC_INFINITY && n >= usec_add(last_busy_usec, listen_idle_usec)) { else if (listen_idle_usec != USEC_INFINITY && n >= usec_add(last_busy_usec, listen_idle_usec)) {
char buf[FORMAT_TIMESPAN_MAX]; char buf[FORMAT_TIMESPAN_MAX];
log_debug("Exiting worker, been idle for %s, .", log_debug("Exiting worker, been idle for %s, .", format_timespan(buf, sizeof(buf), usec_sub_unsigned(n, last_busy_usec), 0));
format_timespan(buf, sizeof(buf), usec_sub_unsigned(n, last_busy_usec), 0));
break; break;
} }
@ -738,7 +736,7 @@ static int run(int argc, char *argv[]) {
(void) rename_process("systemd-userwork: processing..."); (void) rename_process("systemd-userwork: processing...");
if (fd == -EAGAIN) if (fd == -EAGAIN)
continue; /* The listening socket has SO_RECVTIMEO set, hence a timeout is expected continue; /* The listening socket as SO_RECVTIMEO set, hence a time-out is expected
* after a while, let's check if it's time to exit though. */ * after a while, let's check if it's time to exit though. */
if (fd == -EINTR) if (fd == -EINTR)
continue; /* Might be that somebody attached via strace, let's just continue in that continue; /* Might be that somebody attached via strace, let's just continue in that

View File

@ -25,5 +25,5 @@
# These changes are automatically applied on future re-boots. # These changes are automatically applied on future re-boots.
d /var/lib/systemd/pstore 0755 root root 14d d /var/lib/systemd/pstore 0755 root root 14d
#w- /sys/module/printk/parameters/always_kmsg_dump - - - - Y #w /sys/module/printk/parameters/always_kmsg_dump - - - - Y
w- /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y w /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y

View File

@ -25,6 +25,7 @@ LimitNOFILE=@HIGH_RLIMIT_NOFILE@
LockPersonality=yes LockPersonality=yes
MemoryDenyWriteExecute=yes MemoryDenyWriteExecute=yes
NoNewPrivileges=yes NoNewPrivileges=yes
PrivateNetwork=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_ALG RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_ALG
RestrictNamespaces=mnt RestrictNamespaces=mnt
RestrictRealtime=yes RestrictRealtime=yes

View File

@ -26,5 +26,5 @@ ExecStop=@rootlibexecdir@/systemd-random-seed save
# This service waits until the kernel's entropy pool is initialized, and may be # This service waits until the kernel's entropy pool is initialized, and may be
# used as ordering barrier for service that require an initialized entropy # used as ordering barrier for service that require an initialized entropy
# pool. Since initialization can take a while on entropy-starved systems, let's # pool. Since initialization can take a while on entropy-starved systems, let's
# increase the timeout substantially here. # increase the time-out substantially here.
TimeoutSec=10min TimeoutSec=10min