New upstream version 249.5

This commit is contained in:
Michael Biebl 2021-10-12 19:48:56 +02:00
parent 2c6f20efa6
commit ce5f39bdc4
93 changed files with 850 additions and 422 deletions

3
NEWS
View File

@ -3867,6 +3867,9 @@ CHANGES WITH 240:
Consult the kernel documentation for details on this sysctl:
https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
* The v239 change to turn on "net.ipv4.tcp_ecn" by default has been
reverted.
* CPUAccounting=yes no longer enables the CPU controller when using
kernel 4.15+ and the unified cgroup hierarchy, as required accounting

View File

@ -86,7 +86,7 @@ If you have a portable service image, maybe in a raw disk image called
`foobar_0.7.23.raw`, then attaching the services to the host is as easy as:
```
# /usr/lib/systemd/portablectl attach foobar_0.7.23.raw
# portablectl attach foobar_0.7.23.raw
```
This command does the following:
@ -268,7 +268,7 @@ include template units such as `foobar@.service`, so that instantiation is as
simple as:
```
# /usr/lib/systemd/portablectl attach foobar_0.7.23.raw
# portablectl attach foobar_0.7.23.raw
# systemctl enable --now foobar@instancea.service
# systemctl enable --now foobar@instanceb.service

View File

@ -226,8 +226,9 @@ sensor:modalias:acpi:BOSC0200*:dmi:*:svnChuwi*:pnHi13:*
# Chuwi HiBook does not have its product name filled, so we
# match the entire dmi-alias, assuming that the use of a BOSC0200 +
# bios-version + bios-date combo is unique
sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/07/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnHampoo:rnCherryTrailCR:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/28/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnHampoo:rnCherryTrailCR:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
# '*' in ":*svn" is there because kernels >= 5.8 have inserted a br field there
sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/07/2016:*svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnHampoo:rnCherryTrailCR:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/28/2016:*svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnHampoo:rnCherryTrailCR:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
# Chuwi HiBook Pro (CWI526)
@ -237,7 +238,8 @@ sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo*:pnP1D6_C109K:*
# Chuwi CoreBook
# Chuwi CoreBook does not have its product name filled, so we
# match the entire dmi-alias
sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvrY13D_KB133.103:bd06/01/2018:svnHampoo:pnDefaultstring:pvrV100:rvnHampoo:rnY13D_KB133:rvrV100:cvnDefaultstring:ct9:cvrDefaultstring:*
# '*' in ":*svn" is there because kernels >= 5.8 have inserted a br field there
sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvrY13D_KB133.103:bd06/01/2018:*svnHampoo:pnDefaultstring:pvrV100:rvnHampoo:rnY13D_KB133:rvrV100:cvnDefaultstring:ct9:cvrDefaultstring:*
ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1
#########################################
@ -394,13 +396,14 @@ sensor:modalias:acpi:KIOX000A*:dmi:bvnINSYDECorp.:bvrBYT70A.YNCHENG.WIN.007:*:sv
# and no other devices have both board_name *and* product_name set to
# "Default string". So combined with the sensor modalias and BIOS date this
# should be unique enough to identify the GPDwin
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd10/25/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd11/18/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd12/23/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd12/26/2016:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd02/21/2017:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd03/20/2017:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/25/2017:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
# '*' in ":*svn" is there because kernels >= 5.8 have inserted a br field there
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd10/25/2016:*svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd11/18/2016:*svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd12/23/2016:*svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd12/26/2016:*svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd02/21/2017:*svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd03/20/2017:*svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/25/2017:*svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnAMICorporation:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
ACCEL_LOCATION=base
#########################################
@ -674,7 +677,8 @@ sensor:modalias:acpi:BMA250E*:dmi:bvnINSYDECorp.:bvrONDA.W89*:svnInsyde:pnONDATa
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
# Onda v975w, generic DMI strings, match entire dmi modalias inc. bios-date
sensor:modalias:acpi:SMO8500*:dmi:bvnAmericanMegatrendsInc.:bvr5.6.5:bd07/25/2014:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:*
# '*' in ":*svn" is there because kernels >= 5.8 have inserted a br field there
sensor:modalias:acpi:SMO8500*:dmi:bvnAmericanMegatrendsInc.:bvr5.6.5:bd07/25/2014:*svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:*
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
#########################################
@ -683,7 +687,8 @@ sensor:modalias:acpi:SMO8500*:dmi:bvnAmericanMegatrendsInc.:bvr5.6.5:bd07/25/201
# One-netbook OneMix 2s
# OneMix 2s has no product name filled, matching entire dmi-alias
sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.12:bd10/26/2018:br5.12:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnDefaultstring:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
# '*' in ":*svn" is there because kernels >= 5.8 have inserted a br field there
sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.12:bd10/26/2018:*svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnDefaultstring:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
# One-netbook OneMix 3 Pro
@ -692,7 +697,8 @@ sensor:modalias:acpi:BOSC0200*:dmi:*svnONE-NETBOOKTECHNOLOGYCO*:pnOne-Mix3Pro:*
# One-netbook OneMix 3s
# OneMix 3s has no product name filled, matching entire dmi-alias
sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.12:bd07/17/2019:br5.12:svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnDefaultstring:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
# '*' in ":*svn" is there because kernels >= 5.8 have inserted a br field there
sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.12:bd07/17/2019:*svnDefaultstring:pnDefaultstring:pvrDefaultstring:rvnDefaultstring:rnDefaultstring:rvrDefaultstring:cvnDefaultstring:ct3:cvrDefaultstring:*
ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1
#########################################
@ -724,8 +730,9 @@ sensor:modalias:acpi:BMA250E*:dmi:*:svnShenzhenPLOYER*:pnMOMO7W:*
# The Point of View TAB-P800W does not have its product name filled, so we
# match the entire dmi-alias, assuming that the use of a BMA250E +
# bios-version + bios-date combo is unique
sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr3BAIR1013:bd08/22/2014:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:*
sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr3BAIR1014:bd10/24/2014:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:*
# '*' in ":*svn" is there because kernels >= 5.8 have inserted a br field there
sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr3BAIR1013:bd08/22/2014:*svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:*
sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr3BAIR1014:bd10/24/2014:*svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:*
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
# Point of View TAB-P1005W-232 (v2.0)
@ -803,7 +810,8 @@ sensor:modalias:acpi:SMO8500*:dmi:*bd12/19/2014:*:rvnTECLAST:rntPAD:*
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
# Teclast X98 Plus I (A5C6), generic DMI strings, match entire dmi modalias inc. bios-date
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.011:bd11/03/2015:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnCherryTrailCR:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:*
# '*' in ":*svn" is there because kernels >= 5.8 have inserted a br field there
sensor:modalias:acpi:KIOX000A*:dmi:bvnAmericanMegatrendsInc.:bvr5.011:bd11/03/2015:*svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnCherryTrailCR:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:*
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
# Teclast X98 Plus II
@ -815,7 +823,8 @@ sensor:modalias:acpi:KIOX000A*:dmi:*:svnTECLAST:pnX98PlusII:*
#########################################
# Thundersoft TST168 tablet, generic DMI strings, match entire dmi modalias inc. bios-date
sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr5.6.5:bd04/15/2014:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:*
# '*' in ":*svn" is there because kernels >= 5.8 have inserted a br field there
sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr5.6.5:bd04/15/2014:*svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:*
ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1
#########################################
@ -883,7 +892,8 @@ sensor:modalias:acpi:SMO8500*:dmi:*:svnUMAX:pnVisionBook10WiPlus:*
# The Winpad A15 does not have its product name filled, so we
# match the entire dmi-alias, assuming that the use of a SMO8500 +
# bios-version + bios-date combo is unique
sensor:modalias:acpi:SMO8500*:dmi:bvnAmericanMegatrendsInc.:bvr5.6.5:bd11/20/2014:br5.6:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:*
# '*' in ":*svn" is there because kernels >= 5.8 have inserted a br field there
sensor:modalias:acpi:SMO8500*:dmi:bvnAmericanMegatrendsInc.:bvr5.6.5:bd11/20/2014:*svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:*
ACCEL_MOUNT_MATRIX=0, -1, 0; 1, 0, 0; 0, 0, -1
#########################################

View File

@ -1711,7 +1711,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
readonly s OnFailureJobMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b IgnoreOnIsolate = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly b NeedDaemonReload = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly as Markers = ['...', ...];

View File

@ -1,9 +1,17 @@
#include <stdio.h>
#include <stdlib.h>
#include <sd-path.h>
int main(void) {
int r;
char *t;
sd_path_lookup(SD_PATH_USER_DOCUMENTS, NULL, &t);
r = sd_path_lookup(SD_PATH_USER_DOCUMENTS, NULL, &t);
if (r < 0)
return EXIT_FAILURE;
printf("~/Documents: %s\n", t);
free(t);
return EXIT_SUCCESS;
}

View File

@ -126,8 +126,9 @@
<listitem><para>Takes a boolean argument. Controls whether network time synchronization is active and
enabled (if available). If the argument is true, this enables and starts the first existing network
synchronization service. If the argument is false, then this disables and stops the known network
synchronization services. The way that the list of services is built is described below.</para>
</listitem>
synchronization services. The way that the list of services is built is described in
<citerefentry><refentrytitle>systemd-timedated.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
</para></listitem>
</varlistentry>
</variablelist>

View File

@ -35,7 +35,7 @@ conf.set10('BUILD_MODE_DEVELOPER', get_option('mode') == 'developer',
want_ossfuzz = get_option('oss-fuzz')
want_libfuzzer = get_option('llvm-fuzz')
if want_ossfuzz + want_libfuzzer > 1
if want_ossfuzz and want_libfuzzer
error('only one of oss-fuzz or llvm-fuzz can be specified')
endif
@ -2495,14 +2495,16 @@ if conf.get('ENABLE_LOCALED') == 1
if conf.get('HAVE_XKBCOMMON') == 1
# logind will load libxkbcommon.so dynamically on its own
deps = [libdl]
extra_includes = [libxkbcommon.get_pkgconfig_variable('includedir')]
else
deps = []
extra_includes = []
endif
executable(
'systemd-localed',
systemd_localed_sources,
include_directories : includes,
include_directories : includes + extra_includes,
link_with : [libshared],
dependencies : deps,
install_rpath : rootlibexecdir,

View File

@ -197,7 +197,7 @@ option('default-hierarchy', type : 'combo',
choices : ['legacy', 'hybrid', 'unified'], value : 'unified',
description : 'default cgroup hierarchy')
option('default-net-naming-scheme', type : 'combo',
choices : ['latest', 'v238', 'v239', 'v240'],
choices : ['latest', 'v238', 'v239', 'v240', 'v241', 'v243', 'v245', 'v247', 'v249'],
description : 'default net.naming-scheme= value')
option('status-unit-format-default', type : 'combo',
choices : ['description', 'name', 'combined'],

View File

@ -577,6 +577,7 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
word = e+1;
state = WORD;
nest--;
} else if (*e == ':') {
if (flags & REPLACE_ENV_ALLOW_EXTENDED) {
len = e - word - 2;

View File

@ -7,6 +7,7 @@
#include <sys/types.h>
#include "ether-addr-util.h"
#include "hexdecoct.h"
#include "macro.h"
#include "string-util.h"
@ -15,12 +16,13 @@ char* hw_addr_to_string(const struct hw_addr_data *addr, char buffer[HW_ADDR_TO_
assert(buffer);
assert(addr->length <= HW_ADDR_MAX_SIZE);
for (size_t i = 0; i < addr->length; i++) {
sprintf(&buffer[3*i], "%02"PRIx8, addr->bytes[i]);
if (i < addr->length - 1)
buffer[3*i + 2] = ':';
for (size_t i = 0, j = 0; i < addr->length; i++) {
buffer[j++] = hexchar(addr->bytes[i] >> 4);
buffer[j++] = hexchar(addr->bytes[i] & 0x0f);
buffer[j++] = ':';
}
buffer[addr->length > 0 ? addr->length * 3 - 1 : 0] = '\0';
return buffer;
}

View File

@ -30,14 +30,16 @@
/* The maximum size of the file we'll read in one go in read_full_file() (64M). */
#define READ_FULL_BYTES_MAX (64U*1024U*1024U - 1U)
/* The maximum size of virtual files we'll read in one go in read_virtual_file() (4M). Note that this limit
* is different (and much lower) than the READ_FULL_BYTES_MAX limit. This reflects the fact that we use
* different strategies for reading virtual and regular files: virtual files are generally size constrained:
* there we allocate the full buffer size in advance. Regular files OTOH can be much larger, and here we grow
* the allocations exponentially in a loop. In glibc large allocations are immediately backed by mmap()
* making them relatively slow (measurably so). Thus, when allocating the full buffer in advance the large
* limit is a problem. When allocating piecemeal it's not. Hence pick two distinct limits. */
#define READ_VIRTUAL_BYTES_MAX (4U*1024U*1024U - 1U)
/* The maximum size of virtual files (i.e. procfs, sysfs, and other virtual "API" files) we'll read in one go
* in read_virtual_file(). Note that this limit is different (and much lower) than the READ_FULL_BYTES_MAX
* limit. This reflects the fact that we use different strategies for reading virtual and regular files:
* virtual files we generally have to read in a single read() syscall since the kernel doesn't support
* continuation read()s for them. Thankfully they are somewhat size constrained. Thus we can allocate the
* full potential buffer in advance. Regular files OTOH can be much larger, and there we grow the allocations
* exponentially in a loop. We use a size limit of 4M-2 because 4M-1 is the maximum buffer that /proc/sys/
* allows us to read() (larger reads will fail with ENOMEM), and we want to read one extra byte so that we
* can detect EOFs. */
#define READ_VIRTUAL_BYTES_MAX (4U*1024U*1024U - 2U)
int fopen_unlocked(const char *path, const char *options, FILE **ret) {
assert(ret);
@ -393,7 +395,7 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
* contents* may be returned. (Though the read is still done using one syscall.) Returns 0 on
* partial success, 1 if untruncated contents were read. */
fd = open(filename, O_RDONLY|O_CLOEXEC);
fd = open(filename, O_RDONLY|O_NOCTTY|O_CLOEXEC);
if (fd < 0)
return -errno;
@ -431,6 +433,11 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
}
n_retries--;
} else if (n_retries > 1) {
/* Files in /proc are generally smaller than the page size so let's start with a page size
* buffer from malloc and only use the max buffer on the final try. */
size = MIN3(page_size() - 1, READ_VIRTUAL_BYTES_MAX, max_size);
n_retries = 1;
} else {
size = MIN(READ_VIRTUAL_BYTES_MAX, max_size);
n_retries = 0;
@ -463,9 +470,14 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
if (n <= size)
break;
/* If a maximum size is specified and we already read as much, no need to try again */
if (max_size != SIZE_MAX && n >= max_size) {
n = max_size;
/* If a maximum size is specified and we already read more we know the file is larger, and
* can handle this as truncation case. Note that if the size of what we read equals the
* maximum size then this doesn't mean truncation, the file might or might not end on that
* byte. We need to rerun the loop in that case, with a larger buffer size, so that we read
* at least one more byte to be able to distinguish EOF from truncation. */
if (max_size != SIZE_MAX && n > max_size) {
n = size; /* Make sure we never use more than what we sized the buffer for (so that
* we have one free byte in it for the trailing NUL we add below).*/
truncated = true;
break;
}

View File

@ -1,164 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
* INET An implementation of the TCP/IP protocol suite for the LINUX
* operating system. INET is implemented using the BSD Socket
* interface as the means of communication with the user level.
*
* Global definitions for the ARP (RFC 826) protocol.
*
* Version: @(#)if_arp.h 1.0.1 04/16/93
*
* Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1986-1988
* Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source.
* Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Florian La Roche,
* Jonathan Layes <layes@loran.com>
* Arnaldo Carvalho de Melo <acme@conectiva.com.br> ARPHRD_HWX25
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _UAPI_LINUX_IF_ARP_H
#define _UAPI_LINUX_IF_ARP_H
#include <linux/netdevice.h>
/* ARP protocol HARDWARE identifiers. */
#define ARPHRD_NETROM 0 /* from KA9Q: NET/ROM pseudo */
#define ARPHRD_ETHER 1 /* Ethernet 10Mbps */
#define ARPHRD_EETHER 2 /* Experimental Ethernet */
#define ARPHRD_AX25 3 /* AX.25 Level 2 */
#define ARPHRD_PRONET 4 /* PROnet token ring */
#define ARPHRD_CHAOS 5 /* Chaosnet */
#define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet/TR/TB */
#define ARPHRD_ARCNET 7 /* ARCnet */
#define ARPHRD_APPLETLK 8 /* APPLEtalk */
#define ARPHRD_DLCI 15 /* Frame Relay DLCI */
#define ARPHRD_ATM 19 /* ATM */
#define ARPHRD_METRICOM 23 /* Metricom STRIP (new IANA id) */
#define ARPHRD_IEEE1394 24 /* IEEE 1394 IPv4 - RFC 2734 */
#define ARPHRD_EUI64 27 /* EUI-64 */
#define ARPHRD_INFINIBAND 32 /* InfiniBand */
/* Dummy types for non ARP hardware */
#define ARPHRD_SLIP 256
#define ARPHRD_CSLIP 257
#define ARPHRD_SLIP6 258
#define ARPHRD_CSLIP6 259
#define ARPHRD_RSRVD 260 /* Notional KISS type */
#define ARPHRD_ADAPT 264
#define ARPHRD_ROSE 270
#define ARPHRD_X25 271 /* CCITT X.25 */
#define ARPHRD_HWX25 272 /* Boards with X.25 in firmware */
#define ARPHRD_CAN 280 /* Controller Area Network */
#define ARPHRD_PPP 512
#define ARPHRD_CISCO 513 /* Cisco HDLC */
#define ARPHRD_HDLC ARPHRD_CISCO
#define ARPHRD_LAPB 516 /* LAPB */
#define ARPHRD_DDCMP 517 /* Digital's DDCMP protocol */
#define ARPHRD_RAWHDLC 518 /* Raw HDLC */
#define ARPHRD_RAWIP 519 /* Raw IP */
#define ARPHRD_TUNNEL 768 /* IPIP tunnel */
#define ARPHRD_TUNNEL6 769 /* IP6IP6 tunnel */
#define ARPHRD_FRAD 770 /* Frame Relay Access Device */
#define ARPHRD_SKIP 771 /* SKIP vif */
#define ARPHRD_LOOPBACK 772 /* Loopback device */
#define ARPHRD_LOCALTLK 773 /* Localtalk device */
#define ARPHRD_FDDI 774 /* Fiber Distributed Data Interface */
#define ARPHRD_BIF 775 /* AP1000 BIF */
#define ARPHRD_SIT 776 /* sit0 device - IPv6-in-IPv4 */
#define ARPHRD_IPDDP 777 /* IP over DDP tunneller */
#define ARPHRD_IPGRE 778 /* GRE over IP */
#define ARPHRD_PIMREG 779 /* PIMSM register interface */
#define ARPHRD_HIPPI 780 /* High Performance Parallel Interface */
#define ARPHRD_ASH 781 /* Nexus 64Mbps Ash */
#define ARPHRD_ECONET 782 /* Acorn Econet */
#define ARPHRD_IRDA 783 /* Linux-IrDA */
/* ARP works differently on different FC media .. so */
#define ARPHRD_FCPP 784 /* Point to point fibrechannel */
#define ARPHRD_FCAL 785 /* Fibrechannel arbitrated loop */
#define ARPHRD_FCPL 786 /* Fibrechannel public loop */
#define ARPHRD_FCFABRIC 787 /* Fibrechannel fabric */
/* 787->799 reserved for fibrechannel media types */
#define ARPHRD_IEEE802_TR 800 /* Magic type ident for TR */
#define ARPHRD_IEEE80211 801 /* IEEE 802.11 */
#define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */
#define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */
#define ARPHRD_IEEE802154 804
#define ARPHRD_IEEE802154_MONITOR 805 /* IEEE 802.15.4 network monitor */
#define ARPHRD_PHONET 820 /* PhoNet media type */
#define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */
#define ARPHRD_CAIF 822 /* CAIF media type */
#define ARPHRD_IP6GRE 823 /* GRE over IPv6 */
#define ARPHRD_NETLINK 824 /* Netlink header */
#define ARPHRD_6LOWPAN 825 /* IPv6 over LoWPAN */
#define ARPHRD_VSOCKMON 826 /* Vsock monitor header */
#define ARPHRD_VOID 0xFFFF /* Void type, nothing is known */
#define ARPHRD_NONE 0xFFFE /* zero header length */
/* ARP protocol opcodes. */
#define ARPOP_REQUEST 1 /* ARP request */
#define ARPOP_REPLY 2 /* ARP reply */
#define ARPOP_RREQUEST 3 /* RARP request */
#define ARPOP_RREPLY 4 /* RARP reply */
#define ARPOP_InREQUEST 8 /* InARP request */
#define ARPOP_InREPLY 9 /* InARP reply */
#define ARPOP_NAK 10 /* (ATM)ARP NAK */
/* ARP ioctl request. */
struct arpreq {
struct sockaddr arp_pa; /* protocol address */
struct sockaddr arp_ha; /* hardware address */
int arp_flags; /* flags */
struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
char arp_dev[IFNAMSIZ];
};
struct arpreq_old {
struct sockaddr arp_pa; /* protocol address */
struct sockaddr arp_ha; /* hardware address */
int arp_flags; /* flags */
struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
};
/* ARP Flag values. */
#define ATF_COM 0x02 /* completed entry (ha valid) */
#define ATF_PERM 0x04 /* permanent entry */
#define ATF_PUBL 0x08 /* publish entry */
#define ATF_USETRAILERS 0x10 /* has requested trailers */
#define ATF_NETMASK 0x20 /* want to use a netmask (only
for proxy entries) */
#define ATF_DONTPUB 0x40 /* don't answer this addresses */
/*
* This structure defines an ethernet arp header.
*/
struct arphdr {
__be16 ar_hrd; /* format of hardware address */
__be16 ar_pro; /* format of protocol address */
unsigned char ar_hln; /* length of hardware address */
unsigned char ar_pln; /* length of protocol address */
__be16 ar_op; /* ARP opcode (command) */
#if 0
/*
* Ethernet looks like this : This bit is variable sized however...
*/
unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
unsigned char ar_sip[4]; /* sender IP address */
unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
unsigned char ar_tip[4]; /* target IP address */
#endif
};
#endif /* _UAPI_LINUX_IF_ARP_H */

View File

@ -88,7 +88,6 @@ basic_sources = files('''
linux/hdlc/ioctl.h
linux/if.h
linux/if_addr.h
linux/if_arp.h
linux/if_bonding.h
linux/if_bridge.h
linux/if_ether.h

View File

@ -157,6 +157,19 @@ static bool filename_possibly_with_slash_suffix(const char *s) {
return filename_is_valid(copied);
}
static bool is_name_to_handle_at_fatal_error(int err) {
/* name_to_handle_at() can return "acceptable" errors that are due to the context. For
* example the kernel does not support name_to_handle_at() at all (ENOSYS), or the syscall
* was blocked (EACCES/EPERM; maybe through seccomp, because we are running inside of a
* container), or the mount point is not triggered yet (EOVERFLOW, think nfs4), or some
* general name_to_handle_at() flakiness (EINVAL). However other errors are not supposed to
* happen and therefore are considered fatal ones. */
assert(err < 0);
return !IN_SET(err, -EOPNOTSUPP, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL);
}
int fd_is_mount_point(int fd, const char *filename, int flags) {
_cleanup_free_ struct file_handle *h = NULL, *h_parent = NULL;
int mount_id = -1, mount_id_parent = -1;
@ -206,39 +219,40 @@ int fd_is_mount_point(int fd, const char *filename, int flags) {
return false; /* symlinks are never mount points */
r = name_to_handle_at_loop(fd, filename, &h, &mount_id, flags);
if (IN_SET(r, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL))
/* This kernel does not support name_to_handle_at() at all (ENOSYS), or the syscall was blocked
* (EACCES/EPERM; maybe through seccomp, because we are running inside of a container?), or the mount
* point is not triggered yet (EOVERFLOW, think nfs4), or some general name_to_handle_at() flakiness
* (EINVAL): fall back to simpler logic. */
goto fallback_fdinfo;
else if (r == -EOPNOTSUPP)
/* This kernel or file system does not support name_to_handle_at(), hence let's see if the upper fs
* supports it (in which case it is a mount point), otherwise fall back to the traditional stat()
* logic */
if (r < 0) {
if (is_name_to_handle_at_fatal_error(r))
return r;
if (r != -EOPNOTSUPP)
goto fallback_fdinfo;
/* This kernel or file system does not support name_to_handle_at(), hence let's see
* if the upper fs supports it (in which case it is a mount point), otherwise fall
* back to the traditional stat() logic */
nosupp = true;
else if (r < 0)
return r;
}
r = name_to_handle_at_loop(fd, "", &h_parent, &mount_id_parent, AT_EMPTY_PATH);
if (r == -EOPNOTSUPP) {
if (nosupp)
/* Neither parent nor child do name_to_handle_at()? We have no choice but to fall back. */
if (r < 0) {
if (is_name_to_handle_at_fatal_error(r))
return r;
if (r != -EOPNOTSUPP)
goto fallback_fdinfo;
if (nosupp)
/* Both the parent and the directory can't do name_to_handle_at() */
goto fallback_fdinfo;
else
/* The parent can't do name_to_handle_at() but the directory we are interested in can? If so,
* it must be a mount point. */
return 1;
} else if (r < 0)
return r;
/* The parent can do name_to_handle_at() but the directory we are interested in can't? If so, it must
* be a mount point. */
/* The parent can't do name_to_handle_at() but the directory we are
* interested in can? If so, it must be a mount point. */
return 1;
}
/* The parent can do name_to_handle_at() but the directory we are interested in can't? If
* so, it must be a mount point. */
if (nosupp)
return 1;
/* If the file handle for the directory we are interested in and its parent are identical, we assume
* this is the root directory, which is a mount point. */
/* If the file handle for the directory we are interested in and its parent are identical,
* we assume this is the root directory, which is a mount point. */
if (h->handle_bytes == h_parent->handle_bytes &&
h->handle_type == h_parent->handle_type &&
@ -338,10 +352,10 @@ int path_get_mnt_id(const char *path, int *ret) {
}
r = name_to_handle_at_loop(AT_FDCWD, path, NULL, ret, 0);
if (IN_SET(r, -EOPNOTSUPP, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL)) /* kernel/fs don't support this, or seccomp blocks access, or untriggered mount, or name_to_handle_at() is flaky */
return fd_fdinfo_mnt_id(AT_FDCWD, path, 0, ret);
if (r == 0 || is_name_to_handle_at_fatal_error(r))
return r;
return r;
return fd_fdinfo_mnt_id(AT_FDCWD, path, 0, ret);
}
bool fstype_is_network(const char *fstype) {

View File

@ -628,7 +628,11 @@ static int check_x_access(const char *path, int *ret_fd) {
return r;
r = access_fd(fd, X_OK);
if (r < 0)
if (r == -ENOSYS) {
/* /proc is not mounted. Fallback to access(). */
if (access(path, X_OK) < 0)
return -errno;
} else if (r < 0)
return r;
if (ret_fd)

View File

@ -277,6 +277,28 @@ static inline int getsockopt_int(int fd, int level, int optname, int *ret) {
int socket_bind_to_ifname(int fd, const char *ifname);
int socket_bind_to_ifindex(int fd, int ifindex);
/* Define a 64bit version of timeval/timespec in any case, even on 32bit userspace. */
struct timeval_large {
uint64_t tvl_sec, tvl_usec;
};
struct timespec_large {
uint64_t tvl_sec, tvl_nsec;
};
/* glibc duplicates timespec/timeval on certain 32bit archs, once in 32bit and once in 64bit.
* See __convert_scm_timestamps() in glibc source code. Hence, we need additional buffer space for them
* to prevent from recvmsg_safe() returning -EXFULL. */
#define CMSG_SPACE_TIMEVAL \
((sizeof(struct timeval) == sizeof(struct timeval_large)) ? \
CMSG_SPACE(sizeof(struct timeval)) : \
CMSG_SPACE(sizeof(struct timeval)) + \
CMSG_SPACE(sizeof(struct timeval_large)))
#define CMSG_SPACE_TIMESPEC \
((sizeof(struct timespec) == sizeof(struct timespec_large)) ? \
CMSG_SPACE(sizeof(struct timespec)) : \
CMSG_SPACE(sizeof(struct timespec)) + \
CMSG_SPACE(sizeof(struct timespec_large)))
ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags);
int socket_get_family(int fd, int *ret);

View File

@ -284,7 +284,7 @@ int unit_file_build_name_map(
continue;
}
FOREACH_DIRENT(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) {
FOREACH_DIRENT_ALL(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) {
char *filename;
_cleanup_free_ char *_filename_free = NULL, *simplified = NULL;
const char *suffix, *dst = NULL;

View File

@ -235,8 +235,36 @@ static int detect_vm_dmi(void) {
/* The DMI vendor tables in /sys/class/dmi/id don't help us distinguish between Amazon EC2
* virtual machines and bare-metal instances, so we need to look at SMBIOS. */
if (r == VIRTUALIZATION_AMAZON && detect_vm_smbios() == SMBIOS_VM_BIT_UNSET)
return VIRTUALIZATION_NONE;
if (r == VIRTUALIZATION_AMAZON) {
switch (detect_vm_smbios()) {
case SMBIOS_VM_BIT_SET:
return VIRTUALIZATION_AMAZON;
case SMBIOS_VM_BIT_UNSET:
return VIRTUALIZATION_NONE;
case SMBIOS_VM_BIT_UNKNOWN: {
/* The DMI information we are after is only accessible to the root user,
* so we fallback to using the product name which is less restricted
* to distinguish metal systems from virtualized instances */
_cleanup_free_ char *s = NULL;
r = read_full_virtual_file("/sys/class/dmi/id/product_name", &s, NULL);
/* In EC2, virtualized is much more common than metal, so if for some reason
* we fail to read the DMI data, assume we are virtualized. */
if (r < 0) {
log_debug_errno(r, "Can't read /sys/class/dmi/id/product_name,"
" assuming virtualized: %m");
return VIRTUALIZATION_AMAZON;
}
if (endswith(truncate_nl(s), ".metal")) {
log_debug("DMI product name ends with '.metal', assuming no virtualization");
return VIRTUALIZATION_NONE;
} else
return VIRTUALIZATION_AMAZON;
}
default:
assert_not_reached("Bad virtualization value");
}
}
/* If we haven't identified a VM, but the firmware indicates that there is one, indicate as much. We
* have no further information about what it is. */

View File

@ -711,7 +711,7 @@ static int find_slot(sd_id128_t uuid, const char *path, uint16_t *id) {
for (i = 0; i < n; i++)
if (i != options[i]) {
*id = i;
return 1;
return 0;
}
/* use the next one */

View File

@ -814,12 +814,6 @@ static int automount_start(Unit *u) {
if (r < 0)
return r;
r = unit_test_start_limit(u);
if (r < 0) {
automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT);
return r;
}
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@ -1065,6 +1059,21 @@ static bool automount_supported(void) {
return supported;
}
static int automount_test_start_limit(Unit *u) {
Automount *a = AUTOMOUNT(u);
int r;
assert(a);
r = unit_test_start_limit(u);
if (r < 0) {
automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT);
return r;
}
return 0;
}
static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
[AUTOMOUNT_SUCCESS] = "success",
[AUTOMOUNT_FAILURE_RESOURCES] = "resources",
@ -1127,4 +1136,6 @@ const UnitVTable automount_vtable = {
[JOB_FAILED] = "Failed to unset automount %s.",
},
},
.test_start_limit = automount_test_start_limit,
};

View File

@ -1421,6 +1421,10 @@ int bus_set_transient_exec_command(
if (r < 0)
return r;
if (strv_isempty(argv))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"\"%s\" argv cannot be empty", name);
r = is_ex_prop ? sd_bus_message_read_strv(message, &ex_opts) : sd_bus_message_read(message, "b", &b);
if (r < 0)
return r;

View File

@ -909,7 +909,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
SD_BUS_PROPERTY("OnSuccessJobMode", "s", property_get_job_mode, offsetof(Unit, on_success_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OnFailureJobMode", "s", property_get_job_mode, offsetof(Unit, on_failure_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IgnoreOnIsolate", "b", bus_property_get_bool, offsetof(Unit, ignore_on_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NeedDaemonReload", "b", property_get_need_daemon_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NeedDaemonReload", "b", property_get_need_daemon_reload, 0, 0),
SD_BUS_PROPERTY("Markers", "as", property_get_markers, offsetof(Unit, markers), 0),
SD_BUS_PROPERTY("JobTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobRunningTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_running_timeout), SD_BUS_VTABLE_PROPERTY_CONST),

View File

@ -800,7 +800,7 @@ int config_parse_exec(
if (!separate_argv0) {
char *w = NULL;
if (!GREEDY_REALLOC(n, nlen + 2))
if (!GREEDY_REALLOC0(n, nlen + 2))
return log_oom();
w = strdup(path);
@ -832,7 +832,7 @@ int config_parse_exec(
p += 2;
p += strspn(p, WHITESPACE);
if (!GREEDY_REALLOC(n, nlen + 2))
if (!GREEDY_REALLOC0(n, nlen + 2))
return log_oom();
w = strdup(";");

View File

@ -2454,6 +2454,9 @@ static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
/* Push variables into the manager environment block */
setenv_manager_environment();
/* Parse log environment variables again to take into account any new environment variables. */
log_parse_environment();
return 0;
}

View File

@ -193,7 +193,7 @@ foreach item : in_files
output: file,
command : [meson_render_jinja2, config_h, '@INPUT@'],
capture : true,
install : dir != 'no',
install : (dir == pkgsysconfdir) ? install_sysconfdir_samples : (dir != 'no'),
install_dir : dir)
endforeach

View File

@ -1168,12 +1168,6 @@ static int mount_start(Unit *u) {
assert(IN_SET(m->state, MOUNT_DEAD, MOUNT_FAILED));
r = unit_test_start_limit(u);
if (r < 0) {
mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT);
return r;
}
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@ -1582,6 +1576,10 @@ static int mount_setup_new_unit(
if (r < 0)
return r;
r = mount_add_non_exec_dependencies(MOUNT(u));
if (r < 0)
return r;
/* This unit was generated because /proc/self/mountinfo reported it. Remember this, so that by the time we load
* the unit file for it (and thus add in extra deps right after) we know what source to attributes the deps
* to. */
@ -2139,6 +2137,21 @@ static int mount_can_clean(Unit *u, ExecCleanMask *ret) {
return exec_context_get_clean_mask(&m->exec_context, ret);
}
static int mount_test_start_limit(Unit *u) {
Mount *m = MOUNT(u);
int r;
assert(m);
r = unit_test_start_limit(u);
if (r < 0) {
mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT);
return r;
}
return 0;
}
static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
[MOUNT_EXEC_MOUNT] = "ExecMount",
[MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
@ -2236,4 +2249,6 @@ const UnitVTable mount_vtable = {
[JOB_TIMEOUT] = "Timed out unmounting %s.",
},
},
.test_start_limit = mount_test_start_limit,
};

View File

@ -590,12 +590,6 @@ static int path_start(Unit *u) {
if (r < 0)
return r;
r = unit_test_start_limit(u);
if (r < 0) {
path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT);
return r;
}
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@ -811,6 +805,21 @@ static void path_reset_failed(Unit *u) {
p->result = PATH_SUCCESS;
}
static int path_test_start_limit(Unit *u) {
Path *p = PATH(u);
int r;
assert(p);
r = unit_test_start_limit(u);
if (r < 0) {
path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT);
return r;
}
return 0;
}
static const char* const path_type_table[_PATH_TYPE_MAX] = {
[PATH_EXISTS] = "PathExists",
[PATH_EXISTS_GLOB] = "PathExistsGlob",
@ -865,4 +874,6 @@ const UnitVTable path_vtable = {
.reset_failed = path_reset_failed,
.bus_set_property = bus_path_set_property,
.test_start_limit = path_test_start_limit,
};

View File

@ -548,6 +548,22 @@ static int service_verify(Service *s) {
assert(s);
assert(UNIT(s)->load_state == UNIT_LOADED);
for (ServiceExecCommand c = 0; c < _SERVICE_EXEC_COMMAND_MAX; c++) {
ExecCommand *command;
LIST_FOREACH(command, command, s->exec_command[c]) {
if (!path_is_absolute(command->path) && !filename_is_valid(command->path))
return log_unit_error_errno(UNIT(s), SYNTHETIC_ERRNO(ENOEXEC),
"Service %s= binary path \"%s\" is neither a valid executable name nor an absolute path. Refusing.",
command->path,
service_exec_command_to_string(c));
if (strv_isempty(command->argv))
return log_unit_error_errno(UNIT(s), SYNTHETIC_ERRNO(ENOEXEC),
"Service has an empty argv in %s=. Refusing.",
service_exec_command_to_string(c));
}
}
if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP] &&
UNIT(s)->success_action == EMERGENCY_ACTION_NONE)
/* FailureAction= only makes sense if one of the start or stop commands is specified.
@ -2440,13 +2456,6 @@ static int service_start(Unit *u) {
assert(IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED));
/* Make sure we don't enter a busy loop of some kind. */
r = unit_test_start_limit(u);
if (r < 0) {
service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false);
return r;
}
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@ -4442,6 +4451,22 @@ static const char *service_finished_job(Unit *u, JobType t, JobResult result) {
return NULL;
}
static int service_test_start_limit(Unit *u) {
Service *s = SERVICE(u);
int r;
assert(s);
/* Make sure we don't enter a busy loop of some kind. */
r = unit_test_start_limit(u);
if (r < 0) {
service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false);
return r;
}
return 0;
}
static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
[SERVICE_RESTART_NO] = "no",
[SERVICE_RESTART_ON_SUCCESS] = "on-success",
@ -4604,4 +4629,6 @@ const UnitVTable service_vtable = {
},
.finished_job = service_finished_job,
},
.test_start_limit = service_test_start_limit,
};

View File

@ -34,6 +34,7 @@
#include "process-util.h"
#include "selinux-util.h"
#include "serialize.h"
#include "service.h"
#include "signal-util.h"
#include "smack-util.h"
#include "socket.h"
@ -2514,12 +2515,6 @@ static int socket_start(Unit *u) {
assert(IN_SET(s->state, SOCKET_DEAD, SOCKET_FAILED));
r = unit_test_start_limit(u);
if (r < 0) {
socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT);
return r;
}
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@ -3428,6 +3423,21 @@ static int socket_can_clean(Unit *u, ExecCleanMask *ret) {
return exec_context_get_clean_mask(&s->exec_context, ret);
}
static int socket_test_start_limit(Unit *u) {
Socket *s = SOCKET(u);
int r;
assert(s);
r = unit_test_start_limit(u);
if (r < 0) {
socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT);
return r;
}
return 0;
}
static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
[SOCKET_EXEC_START_PRE] = "ExecStartPre",
[SOCKET_EXEC_START_CHOWN] = "ExecStartChown",
@ -3554,4 +3564,6 @@ const UnitVTable socket_vtable = {
[JOB_TIMEOUT] = "Timed out stopping %s.",
},
},
.test_start_limit = socket_test_start_limit,
};

View File

@ -5,7 +5,6 @@ typedef struct Socket Socket;
typedef struct SocketPeer SocketPeer;
#include "mount.h"
#include "service.h"
#include "socket-util.h"
#include "unit.h"

View File

@ -933,12 +933,6 @@ static int swap_start(Unit *u) {
if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING)
return -EAGAIN;
r = unit_test_start_limit(u);
if (r < 0) {
swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT);
return r;
}
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@ -1588,6 +1582,21 @@ static int swap_can_clean(Unit *u, ExecCleanMask *ret) {
return exec_context_get_clean_mask(&s->exec_context, ret);
}
static int swap_test_start_limit(Unit *u) {
Swap *s = SWAP(u);
int r;
assert(s);
r = unit_test_start_limit(u);
if (r < 0) {
swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT);
return r;
}
return 0;
}
static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
[SWAP_EXEC_ACTIVATE] = "ExecActivate",
[SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
@ -1683,4 +1692,6 @@ const UnitVTable swap_vtable = {
[JOB_TIMEOUT] = "Timed out deactivating swap %s.",
},
},
.test_start_limit = swap_test_start_limit,
};

View File

@ -635,12 +635,6 @@ static int timer_start(Unit *u) {
if (r < 0)
return r;
r = unit_test_start_limit(u);
if (r < 0) {
timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT);
return r;
}
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@ -901,6 +895,21 @@ static int timer_can_clean(Unit *u, ExecCleanMask *ret) {
return 0;
}
static int timer_test_start_limit(Unit *u) {
Timer *t = TIMER(u);
int r;
assert(t);
r = unit_test_start_limit(u);
if (r < 0) {
timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT);
return r;
}
return 0;
}
static const char* const timer_base_table[_TIMER_BASE_MAX] = {
[TIMER_ACTIVE] = "OnActiveSec",
[TIMER_BOOT] = "OnBootSec",
@ -960,4 +969,6 @@ const UnitVTable timer_vtable = {
.timezone_change = timer_timezone_change,
.bus_set_property = bus_timer_set_property,
.test_start_limit = timer_test_start_limit,
};

View File

@ -1851,6 +1851,13 @@ int unit_start(Unit *u) {
assert(u);
/* Check start rate limiting early so that failure conditions don't cause us to enter a busy loop. */
if (UNIT_VTABLE(u)->test_start_limit) {
int r = UNIT_VTABLE(u)->test_start_limit(u);
if (r < 0)
return r;
}
/* If this is already started, then this will succeed. Note that this will even succeed if this unit
* is not startable by the user. This is relied on to detect when we need to wait for units and when
* waiting is finished. */

View File

@ -649,6 +649,10 @@ typedef struct UnitVTable {
* of this type will immediately fail. */
bool (*supported)(void);
/* If this function is set, it's invoked first as part of starting a unit to allow start rate
* limiting checks to occur before we do anything else. */
int (*test_start_limit)(Unit *u);
/* The strings to print in status messages */
UnitStatusMessageFormats status_message_formats;

View File

@ -1186,6 +1186,10 @@ static int check_units_active(void) {
return false;
r = sd_bus_default_system(&bus);
if (r == -ENOENT) {
log_debug("D-Bus is not running, skipping active unit check");
return 0;
}
if (r < 0)
return log_error_errno(r, "Failed to acquire bus: %m");

View File

@ -299,6 +299,8 @@ static int module_callback(Dwfl_Module *mod, void **userdata, const char *name,
program_header->p_offset,
program_header->p_filesz,
ELF_T_NHDR);
if (!data)
continue;
Elf *memelf = elf_memory(data->d_buf, data->d_size);
if (!memelf)

View File

@ -58,8 +58,8 @@ int home_prepare_cifs(
f = safe_fclose(f);
if (asprintf(&options, "credentials=%s,uid=" UID_FMT ",forceuid,gid=" UID_FMT ",forcegid,file_mode=0%3o,dir_mode=0%3o",
p, h->uid, h->uid, h->access_mode, h->access_mode) < 0)
if (asprintf(&options, "credentials=%s,uid=" UID_FMT ",forceuid,gid=" GID_FMT ",forcegid,file_mode=0%3o,dir_mode=0%3o",
p, h->uid, user_record_gid(h), user_record_access_mode(h), user_record_access_mode(h)) < 0)
return log_oom();
r = safe_fork("(mount)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_STDOUT_TO_STDERR, &mount_pid);
@ -71,7 +71,7 @@ int home_prepare_cifs(
h->cifs_service, "/run/systemd/user-home-mount",
"-o", options, NULL);
log_error_errno(errno, "Failed to execute fsck: %m");
log_error_errno(errno, "Failed to execute mount: %m");
_exit(EXIT_FAILURE);
}
@ -86,7 +86,8 @@ int home_prepare_cifs(
}
if (!mounted)
return log_error_errno(ENOKEY, "Failed to mount home directory with supplied password.");
return log_error_errno(SYNTHETIC_ERRNO(ENOKEY),
"Failed to mount home directory with supplied password.");
setup->root_fd = open("/run/systemd/user-home-mount", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
}

View File

@ -69,9 +69,10 @@ int home_move_mount(const char *user_name_and_realm, const char *target) {
const char *d;
int r;
assert(user_name_and_realm);
assert(target);
/* If user_name_and_realm is set, then we'll mount a subdir of the source mount into the host. If
* it's NULL we'll move the mount itself */
if (user_name_and_realm) {
subdir = path_join("/run/systemd/user-home-mount/", user_name_and_realm);
if (!subdir)

View File

@ -281,7 +281,6 @@ static int handle_generic_user_record_error(
const sd_bus_error *error) {
assert(user_name);
assert(secret);
assert(error);
int r;
@ -301,6 +300,8 @@ static int handle_generic_user_record_error(
} else if (sd_bus_error_has_name(error, BUS_ERROR_BAD_PASSWORD)) {
_cleanup_(erase_and_freep) char *newp = NULL;
assert(secret);
/* This didn't work? Ask for an (additional?) password */
if (strv_isempty(secret->password))
@ -326,6 +327,8 @@ static int handle_generic_user_record_error(
} else if (sd_bus_error_has_name(error, BUS_ERROR_BAD_PASSWORD_AND_NO_TOKEN)) {
_cleanup_(erase_and_freep) char *newp = NULL;
assert(secret);
if (strv_isempty(secret->password)) {
(void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Security token of user %s not inserted.", user_name);
r = pam_prompt(handle, PAM_PROMPT_ECHO_OFF, &newp, "Try again with password: ");
@ -350,6 +353,8 @@ static int handle_generic_user_record_error(
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_PIN_NEEDED)) {
_cleanup_(erase_and_freep) char *newp = NULL;
assert(secret);
r = pam_prompt(handle, PAM_PROMPT_ECHO_OFF, &newp, "Security token PIN: ");
if (r != PAM_SUCCESS)
return PAM_CONV_ERR; /* no logging here */
@ -367,6 +372,8 @@ static int handle_generic_user_record_error(
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_PROTECTED_AUTHENTICATION_PATH_NEEDED)) {
assert(secret);
(void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Please authenticate physically on security token of user %s.", user_name);
r = user_record_set_pkcs11_protected_authentication_path_permitted(secret, true);
@ -377,6 +384,8 @@ static int handle_generic_user_record_error(
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED)) {
assert(secret);
(void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Please confirm presence on security token of user %s.", user_name);
r = user_record_set_fido2_user_presence_permitted(secret, true);
@ -387,6 +396,8 @@ static int handle_generic_user_record_error(
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_USER_VERIFICATION_NEEDED)) {
assert(secret);
(void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Please verify user on security token of user %s.", user_name);
r = user_record_set_fido2_user_verification_permitted(secret, true);
@ -403,6 +414,8 @@ static int handle_generic_user_record_error(
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_BAD_PIN)) {
_cleanup_(erase_and_freep) char *newp = NULL;
assert(secret);
(void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Security token PIN incorrect for user %s.", user_name);
r = pam_prompt(handle, PAM_PROMPT_ECHO_OFF, &newp, "Sorry, retry security token PIN: ");
if (r != PAM_SUCCESS)
@ -422,6 +435,8 @@ static int handle_generic_user_record_error(
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_BAD_PIN_FEW_TRIES_LEFT)) {
_cleanup_(erase_and_freep) char *newp = NULL;
assert(secret);
(void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Security token PIN of user %s incorrect (only a few tries left!)", user_name);
r = pam_prompt(handle, PAM_PROMPT_ECHO_OFF, &newp, "Sorry, retry security token PIN: ");
if (r != PAM_SUCCESS)
@ -441,6 +456,8 @@ static int handle_generic_user_record_error(
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_BAD_PIN_ONE_TRY_LEFT)) {
_cleanup_(erase_and_freep) char *newp = NULL;
assert(secret);
(void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Security token PIN of user %s incorrect (only one try left!)", user_name);
r = pam_prompt(handle, PAM_PROMPT_ECHO_OFF, &newp, "Sorry, retry security token PIN: ");
if (r != PAM_SUCCESS)

View File

@ -43,7 +43,7 @@ static int help(void) {
" --version Show package version\n"
" -s --strict When updating, return non-zero exit value on any parsing error\n"
" --usr Generate in " UDEVLIBEXECDIR " instead of /etc/udev\n"
" -r --root=PATH Alternative root path in the filesystem\n\n"
" -r --root=PATH Alternative root path in the filesystem\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
ansi_highlight(),

View File

@ -2074,6 +2074,11 @@ static int simple_varlink_call(const char *option, const char *method) {
}
static int flush_to_var(void) {
if (access("/run/systemd/journal/flushed", F_OK) >= 0)
return 0; /* Already flushed, no need to contact journald */
if (errno != ENOENT)
return log_error_errno(errno, "Unable to check for existence of /run/systemd/journal/flushed: %m");
return simple_varlink_call("--flush", "io.systemd.Journal.FlushToVar");
}

View File

@ -1275,11 +1275,14 @@ int server_process_datagram(
/* We use NAME_MAX space for the SELinux label here. The kernel currently enforces no limit, but
* according to suggestions from the SELinux people this will change and it will probably be
* identical to NAME_MAX. For now we use that, but this should be updated one day when the final
* limit is known. */
* limit is known.
*
* Here, we need to explicitly initialize the buffer with zero, as glibc has a bug in
* __convert_scm_timestamps(), which assumes the buffer is initialized. See #20741. */
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) +
CMSG_SPACE(sizeof(struct timeval)) +
CMSG_SPACE_TIMEVAL +
CMSG_SPACE(sizeof(int)) + /* fd */
CMSG_SPACE(NAME_MAX) /* selinux label */) control;
CMSG_SPACE(NAME_MAX) /* selinux label */) control = {};
union sockaddr_union sa = {};

View File

@ -148,8 +148,9 @@ int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *ret_dst,
triple_timestamp *ret_timestamp) {
/* This needs to be initialized with zero. See #20741. */
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int)) + /* ttl */
CMSG_SPACE(sizeof(struct timeval))) control;
CMSG_SPACE_TIMEVAL) control = {};
struct iovec iov = {};
union sockaddr_union sa = {};
struct msghdr msg = {
@ -186,7 +187,6 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *ret_dst,
/* namelen == 0 only happens when running the test-suite over a socketpair */
assert(!(msg.msg_flags & MSG_CTRUNC));
assert(!(msg.msg_flags & MSG_TRUNC));
CMSG_FOREACH(cmsg, &msg) {

View File

@ -192,7 +192,7 @@ int sd_dhcp_client_id_to_string(const void *data, size_t len, char **ret) {
if (len != sizeof_field(sd_dhcp_client_id, eth))
return -EINVAL;
r = asprintf(&t, "%x:%x:%x:%x:%x:%x",
r = asprintf(&t, "%02x:%02x:%02x:%02x:%02x:%02x",
client_id->eth.haddr[0],
client_id->eth.haddr[1],
client_id->eth.haddr[2],
@ -726,7 +726,7 @@ static int client_notify(sd_dhcp_client *client, int event) {
static int client_initialize(sd_dhcp_client *client) {
assert_return(client, -EINVAL);
client->receive_message = sd_event_source_unref(client->receive_message);
client->receive_message = sd_event_source_disable_unref(client->receive_message);
client->fd = safe_close(client->fd);
@ -1492,7 +1492,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
assert(client);
client->receive_message = sd_event_source_unref(client->receive_message);
client->receive_message = sd_event_source_disable_unref(client->receive_message);
client->fd = safe_close(client->fd);
client->state = DHCP_STATE_REBINDING;
@ -1847,7 +1847,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
client->start_delay = 0;
(void) event_source_disable(client->timeout_resend);
client->receive_message = sd_event_source_unref(client->receive_message);
client->receive_message = sd_event_source_disable_unref(client->receive_message);
client->fd = safe_close(client->fd);
client->state = DHCP_STATE_BOUND;
@ -2229,17 +2229,15 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
log_dhcp_client(client, "FREE");
client_initialize(client);
client->timeout_resend = sd_event_source_unref(client->timeout_resend);
client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
client->timeout_expire = sd_event_source_unref(client->timeout_expire);
client_initialize(client);
sd_dhcp_client_detach_event(client);
sd_dhcp_lease_unref(client->lease);
set_free(client->req_opts);
free(client->hostname);
free(client->vendor_class_identifier);

View File

@ -267,8 +267,8 @@ int sd_dhcp_server_stop(sd_dhcp_server *server) {
if (!server)
return 0;
server->receive_message = sd_event_source_unref(server->receive_message);
server->receive_broadcast = sd_event_source_unref(server->receive_broadcast);
server->receive_message = sd_event_source_disable_unref(server->receive_message);
server->receive_broadcast = sd_event_source_disable_unref(server->receive_broadcast);
server->fd_raw = safe_close(server->fd_raw);
server->fd = safe_close(server->fd);

View File

@ -120,7 +120,7 @@ static void ipv4acd_reset(sd_ipv4acd *acd) {
assert(acd);
(void) event_source_disable(acd->timer_event_source);
acd->receive_message_event_source = sd_event_source_unref(acd->receive_message_event_source);
acd->receive_message_event_source = sd_event_source_disable_unref(acd->receive_message_event_source);
acd->fd = safe_close(acd->fd);
@ -130,9 +130,8 @@ static void ipv4acd_reset(sd_ipv4acd *acd) {
static sd_ipv4acd *ipv4acd_free(sd_ipv4acd *acd) {
assert(acd);
acd->timer_event_source = sd_event_source_unref(acd->timer_event_source);
ipv4acd_reset(acd);
sd_event_source_unref(acd->timer_event_source);
sd_ipv4acd_detach_event(acd);
free(acd->ifname);
return mfree(acd);

View File

@ -239,7 +239,7 @@ static void lldp_reset(sd_lldp *lldp) {
assert(lldp);
(void) event_source_disable(lldp->timer_event_source);
lldp->io_event_source = sd_event_source_unref(lldp->io_event_source);
lldp->io_event_source = sd_event_source_disable_unref(lldp->io_event_source);
lldp->fd = safe_close(lldp->fd);
}
@ -365,10 +365,11 @@ const char *sd_lldp_get_ifname(sd_lldp *lldp) {
static sd_lldp* lldp_free(sd_lldp *lldp) {
assert(lldp);
lldp->timer_event_source = sd_event_source_unref(lldp->timer_event_source);
lldp_reset(lldp);
sd_event_source_unref(lldp->timer_event_source);
sd_lldp_detach_event(lldp);
lldp_flush_neighbors(lldp);
hashmap_free(lldp->neighbor_by_id);

View File

@ -133,18 +133,19 @@ static void ndisc_reset(sd_ndisc *nd) {
(void) event_source_disable(nd->timeout_event_source);
(void) event_source_disable(nd->timeout_no_ra);
nd->retransmit_time = 0;
nd->recv_event_source = sd_event_source_unref(nd->recv_event_source);
nd->recv_event_source = sd_event_source_disable_unref(nd->recv_event_source);
nd->fd = safe_close(nd->fd);
}
static sd_ndisc *ndisc_free(sd_ndisc *nd) {
assert(nd);
nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra);
ndisc_reset(nd);
sd_event_source_unref(nd->timeout_event_source);
sd_event_source_unref(nd->timeout_no_ra);
sd_ndisc_detach_event(nd);
free(nd->ifname);
return mfree(nd);
}

View File

@ -89,8 +89,7 @@ static void radv_reset(sd_radv *ra) {
(void) event_source_disable(ra->timeout_event_source);
ra->recv_event_source =
sd_event_source_unref(ra->recv_event_source);
ra->recv_event_source = sd_event_source_disable_unref(ra->recv_event_source);
ra->ra_sent = 0;
}
@ -116,10 +115,9 @@ static sd_radv *radv_free(sd_radv *ra) {
free(ra->rdnss);
free(ra->dnssl);
ra->timeout_event_source = sd_event_source_unref(ra->timeout_event_source);
radv_reset(ra);
sd_event_source_unref(ra->timeout_event_source);
sd_radv_detach_event(ra);
ra->fd = safe_close(ra->fd);

View File

@ -4154,7 +4154,7 @@ _public_ int sd_event_loop(sd_event *e) {
assert_return(!event_pid_changed(e), -ECHILD);
assert_return(e->state == SD_EVENT_INITIAL, -EBUSY);
_unused_ _cleanup_(sd_event_unrefp) sd_event *ref = NULL;
_unused_ _cleanup_(sd_event_unrefp) sd_event *ref = sd_event_ref(e);
while (e->state != SD_EVENT_FINISHED) {
r = sd_event_run(e, UINT64_MAX);

View File

@ -3158,7 +3158,11 @@ _public_ int sd_journal_enumerate_fields(sd_journal *j, const char **field) {
if (JOURNAL_HEADER_CONTAINS(of->header, n_fields) && le64toh(of->header->n_fields) <= 0)
continue;
r = journal_file_find_field_object_with_hash(of, o->field.payload, sz, le64toh(o->field.hash), NULL, NULL);
if (!JOURNAL_HEADER_KEYED_HASH(f->header) && !JOURNAL_HEADER_KEYED_HASH(of->header))
r = journal_file_find_field_object_with_hash(of, o->field.payload, sz,
le64toh(o->field.hash), NULL, NULL);
else
r = journal_file_find_field_object(of, o->field.payload, sz, NULL, NULL);
if (r < 0)
return r;
if (r > 0) {
@ -3174,7 +3178,7 @@ _public_ int sd_journal_enumerate_fields(sd_journal *j, const char **field) {
if (memchr(o->field.payload, 0, sz))
return -EBADMSG;
if (sz > j->data_threshold)
if (j->data_threshold > 0 && sz > j->data_threshold)
sz = j->data_threshold;
if (!GREEDY_REALLOC(j->fields_buffer, sz + 1))

View File

@ -560,7 +560,7 @@ static void log_xkb(struct xkb_context *ctx, enum xkb_log_level lvl, const char
fmt = strjoina("libxkbcommon: ", format);
DISABLE_WARNING_FORMAT_NONLITERAL;
log_internalv(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, fmt, args);
log_internalv(LOG_DEBUG, 0, PROJECT_FILE, __LINE__, __func__, fmt, args);
REENABLE_WARNING;
}

View File

@ -67,22 +67,24 @@ pam_systemd_c = files('pam_systemd.c')
enable_logind = conf.get('ENABLE_LOGIND') == 1
in_files = [
['logind.conf', pkgsysconfdir, enable_logind],
['logind.conf', pkgsysconfdir, enable_logind and install_sysconfdir_samples],
['70-uaccess.rules', udevrulesdir, enable_logind and conf.get('HAVE_ACL') == 1],
['71-seat.rules', udevrulesdir, enable_logind],
['73-seat-late.rules', udevrulesdir, enable_logind],
['systemd-user', pamconfdir, enable_logind and pamconfdir != 'no']]
['systemd-user', pamconfdir, enable_logind]]
foreach tuple : in_files
file = tuple[0]
dir = tuple[1]
install = (dir == pkgsysconfdir) ? install_sysconfdir_samples : (dir != 'no')
custom_target(
file,
input : file + '.in',
output: file,
command : [meson_render_jinja2, config_h, '@INPUT@'],
capture : true,
install : tuple[2],
install_dir : tuple[1])
install : tuple[2] and install,
install_dir : dir)
endforeach
if enable_logind

View File

@ -332,6 +332,9 @@ static int parse_argv(int argc, char *argv[]) {
assert_not_reached("Unhandled option");
}
if (arg_user)
arg_ask_password = false;
if (arg_user && arg_transport != BUS_TRANSPORT_LOCAL)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Execution in user context is not supported on non-local systems.");

View File

@ -1404,17 +1404,21 @@ static int link_initialized(Link *link, sd_device *device) {
assert(link);
assert(device);
if (link->state != LINK_STATE_PENDING)
return 0;
/* Always replace with the new sd_device object. As the sysname (and possibly other properties
* or sysattrs) may be outdated. */
sd_device_ref(device);
sd_device_unref(link->sd_device);
link->sd_device = device;
if (link->sd_device)
/* Do not ignore unamanaged state case here. If an interface is renamed after being once
* configured, and the corresponding .network file has Name= in [Match] section, then the
* interface may be already in unmanaged state. See #20657. */
if (!IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_UNMANAGED))
return 0;
log_link_debug(link, "udev initialized link");
link_set_state(link, LINK_STATE_INITIALIZED);
link->sd_device = sd_device_ref(device);
/* udev has initialized the link, but we don't know if we have yet
* processed the NEWLINK messages with the latest state. Do a GETLINK,
* when it returns we know that the pending NEWLINKs have already been

View File

@ -413,7 +413,7 @@ int link_lldp_emit_start(Link *link) {
void link_lldp_emit_stop(Link *link) {
assert(link);
link->lldp_emit_event_source = sd_event_source_unref(link->lldp_emit_event_source);
link->lldp_emit_event_source = sd_event_source_disable_unref(link->lldp_emit_event_source);
}
int config_parse_lldp_mud(

View File

@ -290,7 +290,7 @@ Route *route_free(Route *route) {
ordered_set_free_with_destructor(route->multipath_routes, multipath_route_free);
sd_event_source_unref(route->expire);
sd_event_source_disable_unref(route->expire);
return mfree(route);
}
@ -1273,7 +1273,7 @@ static int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdat
}
static int route_add_and_setup_timer_one(Link *link, const Route *route, const MultipathRoute *m, const NextHop *nh, uint8_t nh_weight, Route **ret) {
_cleanup_(sd_event_source_unrefp) sd_event_source *expire = NULL;
_cleanup_(sd_event_source_disable_unrefp) sd_event_source *expire = NULL;
Route *nr;
int r;
@ -1311,7 +1311,7 @@ static int route_add_and_setup_timer_one(Link *link, const Route *route, const M
return log_link_error_errno(link, r, "Could not arm expiration timer: %m");
}
sd_event_source_unref(nr->expire);
sd_event_source_disable_unref(nr->expire);
nr->expire = TAKE_PTR(expire);
*ret = nr;

View File

@ -1115,7 +1115,7 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
r = routing_policy_rule_update_priority(rule, tmp->priority);
if (r < 0)
log_warning_errno(r, "Failed to update priority of remembered routing policy rule, ignoring: %m");
} else if (!m->manage_foreign_routes)
} else if (!m->manage_foreign_rules)
log_routing_policy_rule_debug(tmp, "Ignoring received foreign", NULL, m);
else {
log_routing_policy_rule_debug(tmp, "Remembering foreign", NULL, m);

View File

@ -5354,7 +5354,7 @@ static int cant_be_in_netns(void) {
if (fd < 0)
return log_error_errno(errno, "Failed to allocate udev control socket: %m");
if (connect(fd, &sa.un, SOCKADDR_UN_LEN(sa.un)) < 0) {
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
if (errno == ENOENT || ERRNO_IS_DISCONNECT(errno))
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),

View File

@ -2,6 +2,7 @@
#include <nss.h>
#include <pthread.h>
#include <string.h>
#include "env-util.h"
#include "errno-util.h"
@ -139,6 +140,155 @@ NSS_GRENT_PROTOTYPES(systemd);
NSS_SGENT_PROTOTYPES(systemd);
NSS_INITGROUPS_PROTOTYPE(systemd);
/* Since our NSS functions implement reentrant glibc APIs, we have to guarantee
* all the string pointers we return point into the buffer provided by the
* caller, not into our own static memory. */
static enum nss_status copy_synthesized_passwd(
struct passwd *dest,
const struct passwd *src,
char *buffer, size_t buflen,
int *errnop) {
size_t required;
assert(dest);
assert(src);
assert(src->pw_name);
assert(src->pw_passwd);
assert(src->pw_gecos);
assert(src->pw_dir);
assert(src->pw_shell);
required = strlen(src->pw_name) + 1;
required += strlen(src->pw_passwd) + 1;
required += strlen(src->pw_gecos) + 1;
required += strlen(src->pw_dir) + 1;
required += strlen(src->pw_shell) + 1;
if (buflen < required) {
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
assert(buffer);
*dest = *src;
/* String fields point into the user-provided buffer */
dest->pw_name = buffer;
dest->pw_passwd = stpcpy(dest->pw_name, src->pw_name) + 1;
dest->pw_gecos = stpcpy(dest->pw_passwd, src->pw_passwd) + 1;
dest->pw_dir = stpcpy(dest->pw_gecos, src->pw_gecos) + 1;
dest->pw_shell = stpcpy(dest->pw_dir, src->pw_dir) + 1;
strcpy(dest->pw_shell, src->pw_shell);
return NSS_STATUS_SUCCESS;
}
static enum nss_status copy_synthesized_spwd(
struct spwd *dest,
const struct spwd *src,
char *buffer, size_t buflen,
int *errnop) {
size_t required;
assert(dest);
assert(src);
assert(src->sp_namp);
assert(src->sp_pwdp);
required = strlen(src->sp_namp) + 1;
required += strlen(src->sp_pwdp) + 1;
if (buflen < required) {
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
assert(buffer);
*dest = *src;
/* String fields point into the user-provided buffer */
dest->sp_namp = buffer;
dest->sp_pwdp = stpcpy(dest->sp_namp, src->sp_namp) + 1;
strcpy(dest->sp_pwdp, src->sp_pwdp);
return NSS_STATUS_SUCCESS;
}
static enum nss_status copy_synthesized_group(
struct group *dest,
const struct group *src,
char *buffer, size_t buflen,
int *errnop) {
size_t required;
assert(dest);
assert(src);
assert(src->gr_name);
assert(src->gr_passwd);
assert(src->gr_mem);
assert(!*src->gr_mem); /* Our synthesized records' gr_mem is always just NULL... */
required = strlen(src->gr_name) + 1;
required += strlen(src->gr_passwd) + 1;
required += 1; /* ...but that NULL still needs to be stored into the buffer! */
if (buflen < required) {
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
assert(buffer);
*dest = *src;
/* String fields point into the user-provided buffer */
dest->gr_name = buffer;
dest->gr_passwd = stpcpy(dest->gr_name, src->gr_name) + 1;
dest->gr_mem = (char **) strcpy(dest->gr_passwd, src->gr_passwd) + 1;
*dest->gr_mem = NULL;
return NSS_STATUS_SUCCESS;
}
static enum nss_status copy_synthesized_sgrp(
struct sgrp *dest,
const struct sgrp *src,
char *buffer, size_t buflen,
int *errnop) {
size_t required;
assert(dest);
assert(src);
assert(src->sg_namp);
assert(src->sg_passwd);
required = strlen(src->sg_namp) + 1;
required += strlen(src->sg_passwd) + 1;
if (buflen < required) {
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
assert(buffer);
*dest = *src;
/* String fields point into the user-provided buffer */
dest->sg_namp = buffer;
dest->sg_passwd = stpcpy(dest->sg_namp, src->sg_namp) + 1;
strcpy(dest->sg_passwd, src->sg_passwd);
return NSS_STATUS_SUCCESS;
}
enum nss_status _nss_systemd_getpwnam_r(
const char *name,
struct passwd *pwd,
@ -164,17 +314,14 @@ enum nss_status _nss_systemd_getpwnam_r(
/* Synthesize entries for the root and nobody users, in case they are missing in /etc/passwd */
if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
if (streq(name, root_passwd.pw_name)) {
*pwd = root_passwd;
return NSS_STATUS_SUCCESS;
}
if (streq(name, root_passwd.pw_name))
return copy_synthesized_passwd(pwd, &root_passwd, buffer, buflen, errnop);
if (streq(name, nobody_passwd.pw_name)) {
if (!synthesize_nobody())
return NSS_STATUS_NOTFOUND;
*pwd = nobody_passwd;
return NSS_STATUS_SUCCESS;
return copy_synthesized_passwd(pwd, &nobody_passwd, buffer, buflen, errnop);
}
} else if (STR_IN_SET(name, root_passwd.pw_name, nobody_passwd.pw_name))
@ -211,17 +358,14 @@ enum nss_status _nss_systemd_getpwuid_r(
/* Synthesize data for the root user and for nobody in case they are missing from /etc/passwd */
if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
if (uid == root_passwd.pw_uid) {
*pwd = root_passwd;
return NSS_STATUS_SUCCESS;
}
if (uid == root_passwd.pw_uid)
return copy_synthesized_passwd(pwd, &root_passwd, buffer, buflen, errnop);
if (uid == nobody_passwd.pw_uid) {
if (!synthesize_nobody())
return NSS_STATUS_NOTFOUND;
*pwd = nobody_passwd;
return NSS_STATUS_SUCCESS;
return copy_synthesized_passwd(pwd, &nobody_passwd, buffer, buflen, errnop);
}
} else if (uid == root_passwd.pw_uid || uid == nobody_passwd.pw_uid)
@ -259,17 +403,14 @@ enum nss_status _nss_systemd_getspnam_r(
/* Synthesize entries for the root and nobody users, in case they are missing in /etc/passwd */
if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
if (streq(name, root_spwd.sp_namp)) {
*spwd = root_spwd;
return NSS_STATUS_SUCCESS;
}
if (streq(name, root_spwd.sp_namp))
return copy_synthesized_spwd(spwd, &root_spwd, buffer, buflen, errnop);
if (streq(name, nobody_spwd.sp_namp)) {
if (!synthesize_nobody())
return NSS_STATUS_NOTFOUND;
*spwd = nobody_spwd;
return NSS_STATUS_SUCCESS;
return copy_synthesized_spwd(spwd, &nobody_spwd, buffer, buflen, errnop);
}
} else if (STR_IN_SET(name, root_spwd.sp_namp, nobody_spwd.sp_namp))
@ -309,17 +450,14 @@ enum nss_status _nss_systemd_getgrnam_r(
/* Synthesize records for root and nobody, in case they are missing from /etc/group */
if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
if (streq(name, root_group.gr_name)) {
*gr = root_group;
return NSS_STATUS_SUCCESS;
}
if (streq(name, root_group.gr_name))
return copy_synthesized_group(gr, &root_group, buffer, buflen, errnop);
if (streq(name, nobody_group.gr_name)) {
if (!synthesize_nobody())
return NSS_STATUS_NOTFOUND;
*gr = nobody_group;
return NSS_STATUS_SUCCESS;
return copy_synthesized_group(gr, &nobody_group, buffer, buflen, errnop);
}
} else if (STR_IN_SET(name, root_group.gr_name, nobody_group.gr_name))
@ -356,17 +494,14 @@ enum nss_status _nss_systemd_getgrgid_r(
/* Synthesize records for root and nobody, in case they are missing from /etc/group */
if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
if (gid == root_group.gr_gid) {
*gr = root_group;
return NSS_STATUS_SUCCESS;
}
if (gid == root_group.gr_gid)
return copy_synthesized_group(gr, &root_group, buffer, buflen, errnop);
if (gid == nobody_group.gr_gid) {
if (!synthesize_nobody())
return NSS_STATUS_NOTFOUND;
*gr = nobody_group;
return NSS_STATUS_SUCCESS;
return copy_synthesized_group(gr, &nobody_group, buffer, buflen, errnop);
}
} else if (gid == root_group.gr_gid || gid == nobody_group.gr_gid)
@ -404,17 +539,14 @@ enum nss_status _nss_systemd_getsgnam_r(
/* Synthesize records for root and nobody, in case they are missing from /etc/group */
if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
if (streq(name, root_sgrp.sg_namp)) {
*sgrp = root_sgrp;
return NSS_STATUS_SUCCESS;
}
if (streq(name, root_sgrp.sg_namp))
return copy_synthesized_sgrp(sgrp, &root_sgrp, buffer, buflen, errnop);
if (streq(name, nobody_sgrp.sg_namp)) {
if (!synthesize_nobody())
return NSS_STATUS_NOTFOUND;
*sgrp = nobody_sgrp;
return NSS_STATUS_SUCCESS;
return copy_synthesized_sgrp(sgrp, &nobody_sgrp, buffer, buflen, errnop);
}
} else if (STR_IN_SET(name, root_sgrp.sg_namp, nobody_sgrp.sg_namp))

View File

@ -35,6 +35,8 @@ int nss_pack_user_record(
assert(hr->user_name);
required = strlen(hr->user_name) + 1;
required += 2; /* strlen(PASSWORD_SEE_SHADOW) + 1 */
assert_se(rn = user_record_real_name(hr));
required += strlen(rn) + 1;
@ -51,12 +53,12 @@ int nss_pack_user_record(
.pw_name = buffer,
.pw_uid = hr->uid,
.pw_gid = user_record_gid(hr),
.pw_passwd = (char*) PASSWORD_SEE_SHADOW,
};
assert(buffer);
pwd->pw_gecos = stpcpy(pwd->pw_name, hr->user_name) + 1;
pwd->pw_passwd = stpcpy(pwd->pw_name, hr->user_name) + 1;
pwd->pw_gecos = stpcpy(pwd->pw_passwd, PASSWORD_SEE_SHADOW) + 1;
pwd->pw_dir = stpcpy(pwd->pw_gecos, rn) + 1;
pwd->pw_shell = stpcpy(pwd->pw_dir, hd) + 1;
strcpy(pwd->pw_shell, shell);

View File

@ -206,7 +206,12 @@ static const char *encrypt_mode_table[_ENCRYPT_MODE_MAX] = {
[ENCRYPT_KEY_FILE_TPM2] = "key-file+tpm2",
};
#if HAVE_LIBCRYPTSETUP
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(encrypt_mode, EncryptMode, ENCRYPT_KEY_FILE);
#else
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(encrypt_mode, EncryptMode, ENCRYPT_KEY_FILE);
#endif
static uint64_t round_down_size(uint64_t v, uint64_t p) {
return (v / p) * p;
@ -2779,7 +2784,7 @@ static int context_copy_blocks(Context *context) {
return log_error_errno(r, "Failed to copy in data from '%s': %m", p->copy_blocks_path);
if (fsync(target_fd) < 0)
return log_error_errno(r, "Failed to synchronize copied data blocks: %m");
return log_error_errno(errno, "Failed to synchronize copied data blocks: %m");
if (p->encrypt != ENCRYPT_OFF) {
encrypted_dev_fd = safe_close(encrypted_dev_fd);
@ -3055,7 +3060,7 @@ static int context_mkfs(Context *context) {
if (p->encrypt != ENCRYPT_OFF) {
if (fsync(encrypted_dev_fd) < 0)
return log_error_errno(r, "Failed to synchronize LUKS volume: %m");
return log_error_errno(errno, "Failed to synchronize LUKS volume: %m");
encrypted_dev_fd = safe_close(encrypted_dev_fd);
r = deactivate_luks(cd, encrypted);

View File

@ -39,8 +39,8 @@ static int resolvconf_help(void) {
"This is a compatibility alias for the resolvectl(1) tool, providing native\n"
"command line compatibility with the resolvconf(8) tool of various Linux\n"
"distributions and BSD systems. Some options supported by other implementations\n"
"are not supported and are ignored: -m, -p. Various options supported by other\n"
"implementations are not supported and will cause the invocation to fail: -u,\n"
"are not supported and are ignored: -m, -p, -u. Various options supported by other\n"
"implementations are not supported and will cause the invocation to fail:\n"
"-I, -i, -l, -R, -r, -v, -V, --enable-updates, --disable-updates,\n"
"--updates-are-enabled.\n"
"\nSee the %2$s for details.\n",
@ -171,8 +171,11 @@ int resolvconf_parse_argv(int argc, char *argv[]) {
log_debug("Switch -%c ignored.", c);
break;
/* Everybody else can agree on the existence of -u but we don't support it. */
/* -u supposedly should "update all subscribers". We have no subscribers, hence let's make
this a NOP, and exit immediately, cleanly. */
case 'u':
log_info("Switch -%c ignored.", c);
return 0;
/* The following options are openresolv inventions we don't support. */
case 'I':

View File

@ -216,6 +216,13 @@ static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) {
return;
}
/* resolv.conf simply doesn't support any other ports than 53, hence there's nothing much we can
* do we have to suppress these entries */
if (dns_server_port(s) != 53) {
log_debug("DNS server %s with non-standard UDP port number, suppressing from generated resolv.conf.", dns_server_string(s));
return;
}
/* Check if the scope this DNS server belongs to is suitable as 'default' route for lookups; resolv.conf does
* not have a syntax to express that, so it must not appear as a global name server to avoid routing unrelated
* domains to it (which is a privacy violation, will most probably fail anyway, and adds unnecessary load) */

View File

@ -506,6 +506,10 @@ static int parse_argv(int argc, char *argv[]) {
assert_not_reached("Unhandled option");
}
/* If we are talking to the per-user instance PolicyKit isn't going to help */
if (arg_user)
arg_ask_password = false;
with_trigger = !!arg_path_property || !!arg_socket_property || arg_with_timer;
/* currently, only single trigger (path, socket, timer) unit can be created simultaneously */

View File

@ -58,6 +58,7 @@ bool (*sym_fido_dev_is_fido2)(const fido_dev_t *) = NULL;
int (*sym_fido_dev_make_cred)(fido_dev_t *, fido_cred_t *, const char *) = NULL;
fido_dev_t* (*sym_fido_dev_new)(void) = NULL;
int (*sym_fido_dev_open)(fido_dev_t *, const char *) = NULL;
int (*sym_fido_dev_close)(fido_dev_t *) = NULL;
const char* (*sym_fido_strerr)(int) = NULL;
int dlopen_libfido2(void) {
@ -106,6 +107,7 @@ int dlopen_libfido2(void) {
DLSYM_ARG(fido_dev_make_cred),
DLSYM_ARG(fido_dev_new),
DLSYM_ARG(fido_dev_open),
DLSYM_ARG(fido_dev_close),
DLSYM_ARG(fido_strerr));
}

View File

@ -60,6 +60,7 @@ extern bool (*sym_fido_dev_is_fido2)(const fido_dev_t *);
extern int (*sym_fido_dev_make_cred)(fido_dev_t *, fido_cred_t *, const char *);
extern fido_dev_t* (*sym_fido_dev_new)(void);
extern int (*sym_fido_dev_open)(fido_dev_t *, const char *);
extern int (*sym_fido_dev_close)(fido_dev_t *);
extern const char* (*sym_fido_strerr)(int);
int dlopen_libfido2(void);
@ -75,8 +76,10 @@ static inline void fido_assert_free_wrapper(fido_assert_t **p) {
}
static inline void fido_dev_free_wrapper(fido_dev_t **p) {
if (*p)
if (*p) {
sym_fido_dev_close(*p);
sym_fido_dev_free(p);
}
}
static inline void fido_cred_free_wrapper(fido_cred_t **p) {

View File

@ -1789,6 +1789,10 @@ int seccomp_restrict_archs(Set *archs) {
for (unsigned i = 0; seccomp_local_archs[i] != SECCOMP_LOCAL_ARCH_END; ++i) {
uint32_t arch = seccomp_local_archs[i];
/* See above comment, our "native" architecture is never blocked. */
if (arch == seccomp_arch_native())
continue;
/* That architecture might have already been blocked by a previous call to seccomp_restrict_archs. */
if (arch == SECCOMP_LOCAL_ARCH_BLOCKED)
continue;

View File

@ -392,15 +392,17 @@ int find_hibernate_location(HibernateLocation **ret_hibernate_location) {
}
/* prefer resume device or highest priority swap with most remaining space */
if (hibernate_location && swap->priority < hibernate_location->swap->priority) {
log_debug("%s: ignoring device with lower priority", swap->device);
continue;
}
if (hibernate_location &&
(swap->priority == hibernate_location->swap->priority
&& swap->size - swap->used < hibernate_location->swap->size - hibernate_location->swap->used)) {
log_debug("%s: ignoring device with lower usable space", swap->device);
continue;
if (sys_resume == 0) {
if (hibernate_location && swap->priority < hibernate_location->swap->priority) {
log_debug("%s: ignoring device with lower priority", swap->device);
continue;
}
if (hibernate_location &&
(swap->priority == hibernate_location->swap->priority
&& swap->size - swap->used < hibernate_location->swap->size - hibernate_location->swap->used)) {
log_debug("%s: ignoring device with lower usable space", swap->device);
continue;
}
}
dev_t swap_device;

View File

@ -182,7 +182,7 @@ static int tpm2_init(const char *device, struct tpm2_context *ret) {
if (!tcti)
return log_oom();
rc = info->init(tcti, &sz, device);
rc = info->init(tcti, &sz, param);
if (rc != TPM2_RC_SUCCESS)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
"Failed to initialize TCTI context: %s", sym_Tss2_RC_Decode(rc));

View File

@ -1913,9 +1913,9 @@ uint64_t user_record_luks_pbkdf_memory_cost(UserRecord *h) {
assert(h);
/* Returns a value with kb granularity, since that's what libcryptsetup expects */
if (h->luks_pbkdf_memory_cost == UINT64_MAX)
return 64*1024*1024; /* We default to 64M, since this should work on smaller systems too */
return streq(user_record_luks_pbkdf_type(h), "pbkdf2") ? 0 : /* doesn't apply for simple pbkdf2 */
64*1024*1024; /* We default to 64M, since this should work on smaller systems too */
return MIN(DIV_ROUND_UP(h->luks_pbkdf_memory_cost, 1024), UINT32_MAX) * 1024;
}
@ -1923,8 +1923,9 @@ uint64_t user_record_luks_pbkdf_memory_cost(UserRecord *h) {
uint64_t user_record_luks_pbkdf_parallel_threads(UserRecord *h) {
assert(h);
if (h->luks_pbkdf_memory_cost == UINT64_MAX)
return 1; /* We default to 1, since this should work on smaller systems too */
if (h->luks_pbkdf_parallel_threads == UINT64_MAX)
return streq(user_record_luks_pbkdf_type(h), "pbkdf2") ? 0 : /* doesn't apply for simple pbkdf2 */
1; /* We default to 1, since this should work on smaller systems too */
return MIN(h->luks_pbkdf_parallel_threads, UINT32_MAX);
}

View File

@ -47,8 +47,8 @@ static int update_timeout(void) {
flags = WDIOS_ENABLECARD;
if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0) {
/* ENOTTY means the watchdog is always enabled so we're fine */
log_full(ERRNO_IS_NOT_SUPPORTED(errno) ? LOG_DEBUG : LOG_WARNING,
"Failed to enable hardware watchdog: %m");
log_full_errno(ERRNO_IS_NOT_SUPPORTED(errno) ? LOG_DEBUG : LOG_WARNING, errno,
"Failed to enable hardware watchdog, ignoring: %m");
if (!ERRNO_IS_NOT_SUPPORTED(errno))
return -errno;
}

View File

@ -925,6 +925,11 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
assert_not_reached("Unhandled option");
}
/* If we are in --user mode, there's no point in talking to PolicyKit or the infra to query system
* passwords */
if (arg_scope != UNIT_FILE_SYSTEM)
arg_ask_password = false;
if (arg_transport == BUS_TRANSPORT_REMOTE && arg_scope != UNIT_FILE_SYSTEM)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Cannot access user instance remotely.");

View File

@ -198,7 +198,7 @@ static void test_replace_env2(bool extended) {
"BAR=bar",
NULL
};
_cleanup_free_ char *t = NULL, *s = NULL, *q = NULL, *r = NULL, *p = NULL, *x = NULL;
_cleanup_free_ char *t = NULL, *s = NULL, *q = NULL, *r = NULL, *p = NULL, *x = NULL, *y = NULL;
unsigned flags = REPLACE_ENV_ALLOW_EXTENDED*extended;
t = replace_env("FOO=${FOO:-${BAR}}", (char**) env, flags);
@ -218,6 +218,9 @@ static void test_replace_env2(bool extended) {
x = replace_env("XXX=${XXX:+${BAR}post}", (char**) env, flags);
assert_se(streq(x, extended ? "XXX=" : "XXX=${XXX:+barpost}"));
y = replace_env("FOO=${FOO}between${BAR:-baz}", (char**) env, flags);
assert_se(streq(y, extended ? "FOO=foobetweenbar" : "FOO=foobetween${BAR:-baz}"));
}
static void test_replace_env_argv(void) {

View File

@ -432,8 +432,10 @@ static void test_exec_systemcallfilter(Manager *m) {
test(m, "exec-systemcallfilter-not-failing.service", 0, CLD_EXITED);
test(m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED);
test(m, "exec-systemcallfilter-not-failing3.service", 0, CLD_EXITED);
test(m, "exec-systemcallfilter-failing.service", SIGSYS, CLD_KILLED);
test(m, "exec-systemcallfilter-failing2.service", SIGSYS, CLD_KILLED);
test(m, "exec-systemcallfilter-failing3.service", SIGSYS, CLD_KILLED);
r = find_executable("python3", NULL);
if (r < 0) {

View File

@ -1028,7 +1028,11 @@ static void test_read_virtual_file(size_t max_size) {
FOREACH_STRING(filename,
"/proc/1/cmdline",
"/etc/nsswitch.conf",
"/sys/kernel/uevent_seqnum") {
"/sys/kernel/uevent_seqnum",
"/proc/kcore",
"/proc/kallsyms",
"/proc/self/exe",
"/proc/self/pagemap") {
_cleanup_free_ char *buf = NULL;
size_t size = 0;
@ -1036,7 +1040,11 @@ static void test_read_virtual_file(size_t max_size) {
r = read_virtual_file(filename, max_size, &buf, &size);
if (r < 0) {
log_info_errno(r, "read_virtual_file(\"%s\", %zu): %m", filename, max_size);
assert_se(ERRNO_IS_PRIVILEGE(r) || r == -ENOENT);
assert_se(ERRNO_IS_PRIVILEGE(r) || /* /proc/kcore is not accessible to unpriv */
IN_SET(r,
-ENOENT, /* Some of the files might be absent */
-EINVAL, /* too small reads from /proc/self/pagemap trigger EINVAL */
-EFBIG)); /* /proc/kcore and /proc/self/pagemap should be too large */
} else
log_info("read_virtual_file(\"%s\", %zu): %s (%zu bytes)", filename, max_size, r ? "non-truncated" : "truncated", size);
}

View File

@ -890,6 +890,66 @@ static void test_load_syscall_filter_set_raw(void) {
assert_se(wait_for_terminate_and_check("syscallrawseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
}
static void test_native_syscalls_filtered(void) {
pid_t pid;
log_info("/* %s */", __func__);
if (!is_seccomp_available()) {
log_notice("Seccomp not available, skipping %s", __func__);
return;
}
if (!have_seccomp_privs()) {
log_notice("Not privileged, skipping %s", __func__);
return;
}
pid = fork();
assert_se(pid >= 0);
if (pid == 0) {
_cleanup_set_free_ Set *arch_s = NULL;
_cleanup_hashmap_free_ Hashmap *s = NULL;
/* Passing "native" or an empty set is equivalent, just do both here. */
assert_se(arch_s = set_new(NULL));
assert_se(seccomp_restrict_archs(arch_s) >= 0);
assert_se(set_put(arch_s, SCMP_ARCH_NATIVE) >= 0);
assert_se(seccomp_restrict_archs(arch_s) >= 0);
assert_se(access("/", F_OK) >= 0);
assert_se(poll(NULL, 0, 0) == 0);
assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, NULL, scmp_act_kill_process(), true) >= 0);
assert_se(access("/", F_OK) >= 0);
assert_se(poll(NULL, 0, 0) == 0);
assert_se(s = hashmap_new(NULL));
#if defined __NR_access && __NR_access >= 0
assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_access + 1), INT_TO_PTR(-1)) >= 0);
log_debug("has access()");
#endif
#if defined __NR_faccessat && __NR_faccessat >= 0
assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat + 1), INT_TO_PTR(-1)) >= 0);
log_debug("has faccessat()");
#endif
#if defined __NR_faccessat2 && __NR_faccessat2 >= 0
assert_se(hashmap_put(s, UINT32_TO_PTR(__NR_faccessat2 + 1), INT_TO_PTR(-1)) >= 0);
log_debug("has faccessat2()");
#endif
assert_se(!hashmap_isempty(s));
assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EUCLEAN), true) >= 0);
assert_se(access("/", F_OK) < 0);
assert_se(errno == EUCLEAN);
_exit(EXIT_SUCCESS);
}
assert_se(wait_for_terminate_and_check("nativeseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
}
static void test_lock_personality(void) {
unsigned long current;
pid_t pid;
@ -1171,6 +1231,7 @@ int main(int argc, char *argv[]) {
test_memory_deny_write_execute_shmat();
test_restrict_archs();
test_load_syscall_filter_set_raw();
test_native_syscalls_filtered();
test_lock_personality();
test_restrict_suid_sgid();

View File

@ -412,7 +412,8 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
.iov_base = &ntpmsg,
.iov_len = sizeof(ntpmsg),
};
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct timespec))) control;
/* This needs to be initialized with zero. See #20741. */
CMSG_BUFFER_TYPE(CMSG_SPACE_TIMESPEC) control = {};
union sockaddr_union server_addr;
struct msghdr msghdr = {
.msg_iov = &iov,
@ -467,6 +468,8 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
switch (cmsg->cmsg_type) {
case SCM_TIMESTAMPNS:
assert(cmsg->cmsg_len == CMSG_LEN(sizeof(struct timespec)));
recv_time = (struct timespec *) CMSG_DATA(cmsg);
break;
}

View File

@ -103,7 +103,6 @@ static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn
_cleanup_(sd_device_unrefp) sd_device *physfn_pcidev = NULL;
const char *physfn_link_file, *syspath;
_cleanup_free_ char *physfn_pci_syspath = NULL;
_cleanup_free_ char *virtfn_pci_syspath = NULL;
struct dirent *dent;
_cleanup_closedir_ DIR *dir = NULL;
char suffix[ALTIFNAMSIZ];
@ -134,7 +133,7 @@ static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn
return -errno;
FOREACH_DIRENT_ALL(dent, dir, break) {
_cleanup_free_ char *virtfn_link_file = NULL;
_cleanup_free_ char *virtfn_link_file = NULL, *virtfn_pci_syspath = NULL;
if (!startswith(dent->d_name, "virtfn"))
continue;

View File

@ -0,0 +1 @@
../TEST-01-BASIC/Makefile

View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -e
TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/17433"
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@"

View File

@ -33,6 +33,8 @@ if install_tests
install_dir : testdata_dir)
install_subdir('testsuite-52.units',
install_dir : testdata_dir)
install_subdir('testsuite-63.units',
install_dir : testdata_dir)
testsuite08_dir = testdata_dir + '/testsuite-08.units'
install_data('testsuite-08.units/-.mount',

View File

@ -635,7 +635,7 @@ Name={}
[Network]
DHCP=ipv4
IPv6AcceptRA=False
DNSSECNegativeTrustAnchors=megasearch.net
DNSSECNegativeTrustAnchors=search.example.com
'''.format(self.iface))
# create second device/dnsmasq for a .company/.lab VPN interface
@ -681,8 +681,8 @@ DNSSECNegativeTrustAnchors=company lab
self.assertIn(b'kettle.cantina.company: 10.241.4.4', out)
# test general domains
out = subprocess.check_output(['resolvectl', 'query', 'megasearch.net'])
self.assertIn(b'megasearch.net: 192.168.42.1', out)
out = subprocess.check_output(['resolvectl', 'query', 'search.example.com'])
self.assertIn(b'search.example.com: 192.168.42.1', out)
with open(self.dnsmasq_log) as f:
general_log = f.read()
@ -696,8 +696,8 @@ DNSSECNegativeTrustAnchors=company lab
self.assertNotIn('.company', general_log)
# general domains should not be sent to the VPN DNS
self.assertRegex(general_log, 'query.*megasearch.net')
self.assertNotIn('megasearch.net', vpn_log)
self.assertRegex(general_log, 'query.*search.example.com')
self.assertNotIn('search.example.com', vpn_log)
def test_resolved_etc_hosts(self):
'''resolved queries to /etc/hosts'''

View File

@ -0,0 +1,9 @@
[Unit]
Description=Test for SystemCallFilter
[Service]
ExecStart=/bin/sh -c '/bin/echo "This should not be seen"'
Type=oneshot
LimitCORE=0
SystemCallArchitectures=native
SystemCallFilter=~write open execve fexecve execveat exit_group close mmap munmap fstat DONOTEXIST

View File

@ -0,0 +1,8 @@
[Unit]
Description=Test for SystemCallFilter
[Service]
ExecStart=/bin/sh -c 'echo "Foo bar"'
Type=oneshot
SystemCallArchitectures=native
SystemCallFilter=

View File

@ -2008,12 +2008,10 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
print('### ip route show table 42 dev dummy98')
print(output)
self.assertRegex(output, 'local 10.20.22.1 proto kernel scope host src 10.20.22.1')
self.assertRegex(output, 'broadcast 10.20.33.0 proto kernel scope link src 10.20.33.1')
self.assertRegex(output, '10.20.33.0/24 proto kernel scope link src 10.20.33.1')
self.assertRegex(output, 'local 10.20.33.1 proto kernel scope host src 10.20.33.1')
self.assertRegex(output, 'broadcast 10.20.33.255 proto kernel scope link src 10.20.33.1')
self.assertRegex(output, 'local 10.20.44.1 proto kernel scope host src 10.20.44.1')
self.assertRegex(output, 'broadcast 10.20.55.0 proto kernel scope link src 10.20.55.1')
self.assertRegex(output, 'local 10.20.55.1 proto kernel scope host src 10.20.55.1')
self.assertRegex(output, 'broadcast 10.20.55.255 proto kernel scope link src 10.20.55.1')
output = check_output('ip -6 route show table 42 dev dummy98')
@ -2040,11 +2038,9 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
print('### ip route show table local dev test1')
print(output)
self.assertRegex(output, 'local 10.21.22.1 proto kernel scope host src 10.21.22.1')
self.assertRegex(output, 'broadcast 10.21.33.0 proto kernel scope link src 10.21.33.1')
self.assertRegex(output, 'local 10.21.33.1 proto kernel scope host src 10.21.33.1')
self.assertRegex(output, 'broadcast 10.21.33.255 proto kernel scope link src 10.21.33.1')
self.assertRegex(output, 'local 10.21.44.1 proto kernel scope host src 10.21.44.1')
self.assertRegex(output, 'broadcast 10.21.55.0 proto kernel scope link src 10.21.55.1')
self.assertRegex(output, 'local 10.21.55.1 proto kernel scope host src 10.21.55.1')
self.assertRegex(output, 'broadcast 10.21.55.255 proto kernel scope link src 10.21.55.1')
output = check_output('ip -6 route show dev test1')

View File

@ -1,6 +1,9 @@
[Unit]
Requires=test10.socket
ConditionPathExistsGlob=/tmp/nonexistent
# Make sure we hit the socket trigger limit in the test and not the service start limit.
StartLimitInterval=1000
StartLimitBurst=1000
[Service]
ExecStart=true

View File

@ -0,0 +1,2 @@
[Path]
PathExists=/tmp/test63

View File

@ -0,0 +1,5 @@
[Unit]
ConditionPathExists=!/tmp/nonexistent
[Service]
ExecStart=true

View File

@ -27,6 +27,37 @@ test "$(systemctl show --value -p RestartKillSignal seven.service)" -eq 2
systemctl restart seven.service
systemctl stop seven.service
# For issue #20933
# Should work normally
busctl call \
org.freedesktop.systemd1 /org/freedesktop/systemd1 \
org.freedesktop.systemd1.Manager StartTransientUnit \
"ssa(sv)a(sa(sv))" test-20933-ok.service replace 1 \
ExecStart "a(sasb)" 1 \
/usr/bin/sleep 2 /usr/bin/sleep 1 true \
0
# DBus call should fail but not crash systemd
busctl call \
org.freedesktop.systemd1 /org/freedesktop/systemd1 \
org.freedesktop.systemd1.Manager StartTransientUnit \
"ssa(sv)a(sa(sv))" test-20933-bad.service replace 1 \
ExecStart "a(sasb)" 1 \
/usr/bin/sleep 0 true \
0 && { echo 'unexpected success'; exit 1; }
# Same but with the empty argv in the middle
busctl call \
org.freedesktop.systemd1 /org/freedesktop/systemd1 \
org.freedesktop.systemd1.Manager StartTransientUnit \
"ssa(sv)a(sa(sv))" test-20933-bad-middle.service replace 1 \
ExecStart "a(sasb)" 3 \
/usr/bin/sleep 2 /usr/bin/sleep 1 true \
/usr/bin/sleep 0 true \
/usr/bin/sleep 2 /usr/bin/sleep 1 true \
0 && { echo 'unexpected success'; exit 1; }
systemd-analyze log-level info
echo OK >/testok

View File

@ -0,0 +1,16 @@
[Unit]
Description=TEST-63-ISSUE-17433
[Service]
ExecStartPre=rm -f /failed /testok
Type=oneshot
ExecStart=rm -f /tmp/nonexistent
ExecStart=systemctl start test63.path
ExecStart=touch /tmp/test63
# Make sure systemd has sufficient time to hit the start limit for test63.service.
ExecStart=sleep 2
ExecStart=sh -x -c 'test "$(systemctl show test63.service -P ActiveState)" = failed'
ExecStart=sh -x -c 'test "$(systemctl show test63.service -P Result)" = start-limit-hit'
ExecStart=sh -x -c 'test "$(systemctl show test63.path -P ActiveState)" = failed'
ExecStart=sh -x -c 'test "$(systemctl show test63.path -P Result)" = unit-start-limit-hit'
ExecStart=sh -x -c 'echo OK >/testok'

View File

@ -16,19 +16,18 @@ After=home.mount
[Service]
BusName=org.freedesktop.home1
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER CAP_FSETID CAP_SETGID CAP_SETUID CAP_SYS_RESOURCE
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER CAP_FSETID CAP_SETGID CAP_SETUID CAP_SYS_RESOURCE CAP_SETPCAP CAP_DAC_READ_SEARCH
DeviceAllow=/dev/loop-control rw
DeviceAllow=/dev/mapper/control rw
DeviceAllow=block-* rw
DeviceAllow=char-hidraw rw
ExecStart={{ROOTLIBEXECDIR}}/systemd-homed
IPAddressDeny=any
KillMode=mixed
LimitNOFILE={{HIGH_RLIMIT_NOFILE}}
LockPersonality=yes
MemoryDenyWriteExecute=yes
NoNewPrivileges=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_ALG
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_ALG AF_INET AF_INET6
RestrictNamespaces=mnt
RestrictRealtime=yes
StateDirectory=systemd/home

View File

@ -14,6 +14,7 @@ DefaultDependencies=no
Before=multi-user.target shutdown.target
Conflicts=shutdown.target
ConditionControlGroupController=v2
ConditionControlGroupController=memory
ConditionPathExists=/proc/pressure/cpu
ConditionPathExists=/proc/pressure/io
ConditionPathExists=/proc/pressure/memory