mirror of
https://git.proxmox.com/git/systemd
synced 2025-10-04 19:54:47 +00:00
New upstream version 249.5
This commit is contained in:
parent
2c6f20efa6
commit
ce5f39bdc4
3
NEWS
3
NEWS
@ -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
|
||||
|
@ -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
|
||||
…
|
||||
|
@ -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
|
||||
|
||||
#########################################
|
||||
|
@ -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 = ['...', ...];
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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'],
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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(";");
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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(),
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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 = {};
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.");
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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':
|
||||
|
@ -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) */
|
||||
|
@ -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 */
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.");
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
1
test/TEST-63-ISSUE-17433/Makefile
Symbolic link
1
test/TEST-63-ISSUE-17433/Makefile
Symbolic link
@ -0,0 +1 @@
|
||||
../TEST-01-BASIC/Makefile
|
9
test/TEST-63-ISSUE-17433/test.sh
Executable file
9
test/TEST-63-ISSUE-17433/test.sh
Executable 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 "$@"
|
@ -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',
|
||||
|
@ -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'''
|
||||
|
9
test/test-execute/exec-systemcallfilter-failing3.service
Normal file
9
test/test-execute/exec-systemcallfilter-failing3.service
Normal 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
|
@ -0,0 +1,8 @@
|
||||
[Unit]
|
||||
Description=Test for SystemCallFilter
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -c 'echo "Foo bar"'
|
||||
Type=oneshot
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=
|
@ -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')
|
||||
|
@ -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
|
||||
|
2
test/testsuite-63.units/test63.path
Normal file
2
test/testsuite-63.units/test63.path
Normal file
@ -0,0 +1,2 @@
|
||||
[Path]
|
||||
PathExists=/tmp/test63
|
5
test/testsuite-63.units/test63.service
Normal file
5
test/testsuite-63.units/test63.service
Normal file
@ -0,0 +1,5 @@
|
||||
[Unit]
|
||||
ConditionPathExists=!/tmp/nonexistent
|
||||
|
||||
[Service]
|
||||
ExecStart=true
|
@ -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
|
||||
|
16
test/units/testsuite-63.service
Normal file
16
test/units/testsuite-63.service
Normal 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'
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user