import systemd-239-74.el8_8

c8 imports/c8/systemd-239-74.el8_8
CentOS Sources 2 years ago committed by MSVSphere Packaging Team
commit 3be363c57e

1
.gitignore vendored

@ -0,0 +1 @@
SOURCES/systemd-239.tar.gz

@ -0,0 +1 @@
8803baa484cbe36680463c8c5e6febeff074b8e7 SOURCES/systemd-239.tar.gz

@ -0,0 +1,105 @@
From 79df4db3fd122f5040bdf2225c3047375de3b0d2 Mon Sep 17 00:00:00 2001
From: Filipe Brandenburger <filbranden@google.com>
Date: Sun, 15 Jul 2018 22:43:35 -0700
Subject: [PATCH] build-sys: Detect whether struct statx is defined in
sys/stat.h
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Starting with glibc 2.27.9000-36.fc29, include file sys/stat.h will have a
definition for struct statx, in which case include file linux/stat.h should be
avoided, in order to prevent a duplicate definition.
In file included from ../src/basic/missing.h:18,
from ../src/basic/util.h:28,
from ../src/basic/hashmap.h:10,
from ../src/shared/bus-util.h:12,
from ../src/libsystemd/sd-bus/bus-creds.c:11:
/usr/include/linux/stat.h:99:8: error: redefinition of struct statx
struct statx {
^~~~~
In file included from /usr/include/sys/stat.h:446,
from ../src/basic/util.h:19,
from ../src/basic/hashmap.h:10,
from ../src/shared/bus-util.h:12,
from ../src/libsystemd/sd-bus/bus-creds.c:11:
/usr/include/bits/statx.h:36:8: note: originally defined here
struct statx
^~~~~
Extend our meson.build to look for struct statx when only sys/stat.h is
included and, in that case, do not include linux/stat.h anymore.
Tested that systemd builds correctly when using a glibc version that includes a
definition for struct statx.
glibc Fedora RPM update:
https://src.fedoraproject.org/rpms/glibc/c/28cb5d31fc1e5887912283c889689c47076278ae
glibc upstream commit:
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=fd70af45528d59a00eb3190ef6706cb299488fcd
---
meson.build | 5 +++++
src/basic/missing.h | 5 ++++-
src/basic/xattr-util.c | 1 -
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/meson.build b/meson.build
index 04331dd41a..a0e7240708 100644
--- a/meson.build
+++ b/meson.build
@@ -425,6 +425,7 @@ decl_headers = '''
#include <sys/stat.h>
'''
# FIXME: key_serial_t is only defined in keyutils.h, this is bound to fail
+# FIXME: these should use -D_GNU_SOURCE, since that is defined at build time
foreach decl : ['char16_t',
'char32_t',
@@ -439,6 +440,10 @@ foreach decl : ['char16_t',
conf.set10('HAVE_' + decl.underscorify().to_upper(), have)
endforeach
+conf.set10('HAVE_STRUCT_STATX_IN_SYS_STAT_H', cc.sizeof('struct statx', prefix : '''
+#include <sys/stat.h>
+''', args : '-D_GNU_SOURCE') > 0)
+
foreach decl : [['IFLA_INET6_ADDR_GEN_MODE', 'linux/if_link.h'],
['IN6_ADDR_GEN_MODE_STABLE_PRIVACY', 'linux/if_link.h'],
['IFLA_VRF_TABLE', 'linux/if_link.h'],
diff --git a/src/basic/missing.h b/src/basic/missing.h
index 71a07d0574..14ad3d4914 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -15,7 +15,6 @@
#include <linux/neighbour.h>
#include <linux/oom.h>
#include <linux/rtnetlink.h>
-#include <linux/stat.h>
#include <net/ethernet.h>
#include <stdlib.h>
#include <sys/resource.h>
@@ -25,6 +24,10 @@
#include <uchar.h>
#include <unistd.h>
+#if !HAVE_STRUCT_STATX_IN_SYS_STAT_H
+#include <linux/stat.h>
+#endif
+
#if HAVE_AUDIT
#include <libaudit.h>
#endif
diff --git a/src/basic/xattr-util.c b/src/basic/xattr-util.c
index c5c55ea846..0ee0979837 100644
--- a/src/basic/xattr-util.c
+++ b/src/basic/xattr-util.c
@@ -2,7 +2,6 @@
#include <errno.h>
#include <fcntl.h>
-#include <linux/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

@ -0,0 +1,50 @@
From 0b3833d6c3b751c6dfb40eeb2ef852984c58f546 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 1 Aug 2018 10:58:28 +0200
Subject: [PATCH] logind: set RemoveIPC to false by default
Resolves: #1523233
---
man/logind.conf.xml | 2 +-
src/login/logind-core.c | 2 +-
src/login/logind.conf.in | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
index 9e88764c6f..7d7e869a26 100644
--- a/man/logind.conf.xml
+++ b/man/logind.conf.xml
@@ -319,7 +319,7 @@
user fully logs out. Takes a boolean argument. If enabled, the user may not consume IPC resources after the
last of the user's sessions terminated. This covers System V semaphores, shared memory and message queues, as
well as POSIX shared memory and message queues. Note that IPC objects of the root user and other system users
- are excluded from the effect of this setting. Defaults to <literal>yes</literal>.</para></listitem>
+ are excluded from the effect of this setting. Defaults to <literal>no</literal>.</para></listitem>
</varlistentry>
</variablelist>
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index dbae4bf5af..511e3acf8f 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -25,7 +25,7 @@ void manager_reset_config(Manager *m) {
m->n_autovts = 6;
m->reserve_vt = 6;
- m->remove_ipc = true;
+ m->remove_ipc = false;
m->inhibit_delay_max = 5 * USEC_PER_SEC;
m->handle_power_key = HANDLE_POWEROFF;
m->handle_suspend_key = HANDLE_SUSPEND;
diff --git a/src/login/logind.conf.in b/src/login/logind.conf.in
index 1029e29bc7..c7346f9819 100644
--- a/src/login/logind.conf.in
+++ b/src/login/logind.conf.in
@@ -32,6 +32,6 @@
#IdleAction=ignore
#IdleActionSec=30min
#RuntimeDirectorySize=10%
-#RemoveIPC=yes
+#RemoveIPC=no
#InhibitorsMax=8192
#SessionsMax=8192

@ -0,0 +1,53 @@
From b924c79720cc2bf2edf75fa3ff43bb4954fccf1f Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 1 Aug 2018 13:19:39 +0200
Subject: [PATCH] pid1: bump DefaultTasksMax to 80% of the kernel pid.max value
This should be hopefully high enough even for the very big deployments.
Resolves: #1523236
---
man/systemd-system.conf.xml | 2 +-
src/basic/cgroup-util.h | 2 +-
src/core/system.conf.in | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
index a914ef2523..085086200a 100644
--- a/man/systemd-system.conf.xml
+++ b/man/systemd-system.conf.xml
@@ -339,7 +339,7 @@
<listitem><para>Configure the default value for the per-unit <varname>TasksMax=</varname> setting. See
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. This setting applies to all unit types that support resource control settings, with the exception
- of slice units. Defaults to 15%, which equals 4915 with the kernel's defaults on the host, but might be smaller
+ of slice units. Defaults to 80%, which equals 26214 with the kernel's defaults on the host, but might be smaller
in OS containers.</para></listitem>
</varlistentry>
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index 1a28a8163a..f10c26ad51 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -100,7 +100,7 @@ static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) {
}
/* Default resource limits */
-#define DEFAULT_TASKS_MAX_PERCENTAGE 15U /* 15% of PIDs, 4915 on default settings */
+#define DEFAULT_TASKS_MAX_PERCENTAGE 80U /* 80% of PIDs, 26214 on default settings */
#define DEFAULT_USER_TASKS_MAX_PERCENTAGE 33U /* 33% of PIDs, 10813 on default settings */
typedef enum CGroupUnified {
diff --git a/src/core/system.conf.in b/src/core/system.conf.in
index f0a59a79a5..653ec6b8c9 100644
--- a/src/core/system.conf.in
+++ b/src/core/system.conf.in
@@ -45,7 +45,7 @@
#DefaultBlockIOAccounting=no
#DefaultMemoryAccounting=@MEMORY_ACCOUNTING_DEFAULT@
#DefaultTasksAccounting=yes
-#DefaultTasksMax=15%
+#DefaultTasksMax=80%
#DefaultLimitCPU=
#DefaultLimitFSIZE=
#DefaultLimitDATA=

@ -0,0 +1,51 @@
From f58c5ced373c2532b5cc44ba2e0c3a28b41472f2 Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Tue, 15 May 2018 09:24:20 +0200
Subject: [PATCH] Avoid /tmp being mounted as tmpfs without the user's will
Ensure PrivateTmp doesn't require tmpfs through tmp.mount, but rather
adds an After relationship.
rhel-only
Resolves: #1578772
---
src/core/unit.c | 12 ++++++------
units/basic.target | 3 ++-
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/core/unit.c b/src/core/unit.c
index 113205bf25..c9f756c9c7 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -982,13 +982,13 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
return 0;
if (c->private_tmp) {
- const char *p;
+ r = unit_add_dependency_by_name(u, UNIT_AFTER, "tmp.mount", NULL, true, UNIT_DEPENDENCY_FILE);
+ if (r < 0)
+ return r;
- FOREACH_STRING(p, "/tmp", "/var/tmp") {
- r = unit_require_mounts_for(u, p, UNIT_DEPENDENCY_FILE);
- if (r < 0)
- return r;
- }
+ r = unit_require_mounts_for(u, "/var/tmp", UNIT_DEPENDENCY_FILE);
+ if (r < 0)
+ return r;
r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_TMPFILES_SETUP_SERVICE, NULL, true, UNIT_DEPENDENCY_FILE);
if (r < 0)
diff --git a/units/basic.target b/units/basic.target
index 4f44292249..8fc7c73ef2 100644
--- a/units/basic.target
+++ b/units/basic.target
@@ -19,4 +19,5 @@ After=sysinit.target sockets.target paths.target slices.target tmp.mount
# require /var and /var/tmp, but only add a Wants= type dependency on /tmp, as
# we support that unit being masked, and this should not be considered an error.
RequiresMountsFor=/var /var/tmp
-Wants=tmp.mount
+# RHEL-only: Disable /tmp on tmpfs.
+#Wants=tmp.mount

@ -0,0 +1,35 @@
From c7f77dfd2bfa593bfbbdf82eea8b600ca1b46f4c Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 1 Aug 2018 17:17:07 +0200
Subject: [PATCH] pid1: bump maximum number of process in user slice to 80% of
pid_max
Related: #1523236
---
src/basic/cgroup-util.h | 2 +-
units/user-.slice.d/10-defaults.conf | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
index f10c26ad51..26e3ae0404 100644
--- a/src/basic/cgroup-util.h
+++ b/src/basic/cgroup-util.h
@@ -101,7 +101,7 @@ static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) {
/* Default resource limits */
#define DEFAULT_TASKS_MAX_PERCENTAGE 80U /* 80% of PIDs, 26214 on default settings */
-#define DEFAULT_USER_TASKS_MAX_PERCENTAGE 33U /* 33% of PIDs, 10813 on default settings */
+#define DEFAULT_USER_TASKS_MAX_PERCENTAGE 80U /* 80% of PIDs, 26214 on default settings */
typedef enum CGroupUnified {
CGROUP_UNIFIED_UNKNOWN = -1,
diff --git a/units/user-.slice.d/10-defaults.conf b/units/user-.slice.d/10-defaults.conf
index 95ab11b30b..efc9d37c8e 100644
--- a/units/user-.slice.d/10-defaults.conf
+++ b/units/user-.slice.d/10-defaults.conf
@@ -12,4 +12,4 @@ Description=User Slice of UID %j
After=systemd-user-sessions.service
[Slice]
-TasksMax=33%
+TasksMax=80%

@ -0,0 +1,33 @@
From 787420ac2ba9c404e13db08601946bde263523f8 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 22 Sep 2014 07:41:06 +0200
Subject: [PATCH] rules: automatically online hot-plugged CPUs
Related: #1523227
---
rules/40-redhat.rules | 3 +++
rules/meson.build | 1 +
2 files changed, 4 insertions(+)
create mode 100644 rules/40-redhat.rules
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
new file mode 100644
index 0000000000..2b494e57cf
--- /dev/null
+++ b/rules/40-redhat.rules
@@ -0,0 +1,3 @@
+# do not edit this file, it will be overwritten on update
+
+SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
diff --git a/rules/meson.build b/rules/meson.build
index b6a32ba77e..e7e4362c0c 100644
--- a/rules/meson.build
+++ b/rules/meson.build
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: LGPL-2.1+
rules = files('''
+ 40-redhat.rules
60-block.rules
60-cdrom_id.rules
60-drm.rules

@ -0,0 +1,37 @@
From 2991b22f5f40a66ad1cc088e502e7f40ae1806c2 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 22 Sep 2014 07:53:52 +0200
Subject: [PATCH] rules: add rule for naming Dell iDRAC USB Virtual NIC as
'idrac'
Related: #1523227
---
rules/73-idrac.rules | 6 ++++++
rules/meson.build | 1 +
2 files changed, 7 insertions(+)
create mode 100644 rules/73-idrac.rules
diff --git a/rules/73-idrac.rules b/rules/73-idrac.rules
new file mode 100644
index 0000000000..d67fc425b1
--- /dev/null
+++ b/rules/73-idrac.rules
@@ -0,0 +1,6 @@
+# do not edit this file, it will be overwritten on update
+
+# On Dell PowerEdge systems, the iDRAC7 and later support a USB Virtual NIC
+# with terminates in the iDRAC. Help identify this with 'idrac'
+
+ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", ATTRS{idVendor}=="413c", ATTRS{idProduct}=="a102", NAME="idrac"
diff --git a/rules/meson.build b/rules/meson.build
index e7e4362c0c..e04a18aca6 100644
--- a/rules/meson.build
+++ b/rules/meson.build
@@ -17,6 +17,7 @@ rules = files('''
70-joystick.rules
70-mouse.rules
70-touchpad.rules
+ 73-idrac.rules
75-net-description.rules
75-probe_mtd.rules
78-sound-card.rules

@ -0,0 +1,22 @@
From d5215083fa1d10f1624ab2f0fb5ba420a2594938 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Wed, 13 May 2015 16:56:44 +0200
Subject: [PATCH] rules: enable memory hotplug
Related: #1523227
---
rules/40-redhat.rules | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 2b494e57cf..8231caae98 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -1,3 +1,7 @@
# do not edit this file, it will be overwritten on update
+# CPU hotadd request
SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
+
+# Memory hotadd request
+SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online"

@ -0,0 +1,22 @@
From 4a7602e27a50828ac8a0eb6b83a1c2c722af652d Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Wed, 13 May 2015 17:11:48 +0200
Subject: [PATCH] rules: reload sysctl settings when the bridge module is
loaded
Related: #1523227
---
rules/40-redhat.rules | 3 +++
1 file changed, 3 insertions(+)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 8231caae98..556a3a3a90 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -5,3 +5,6 @@ SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}
# Memory hotadd request
SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online"
+
+# reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
+ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"

@ -0,0 +1,21 @@
From a42b57dc8b265f183a8fb6fe9ae32a9d77cbb7c5 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Wed, 20 May 2015 12:34:18 +0200
Subject: [PATCH] rules: load sg module
Related: #1523227
---
rules/40-redhat.rules | 3 +++
1 file changed, 3 insertions(+)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 556a3a3a90..305e752285 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -8,3 +8,6 @@ SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online"
# reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"
+
+# load SCSI generic (sg) driver
+SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST!="[module/sg]", RUN+="/sbin/modprobe -bv sg"

@ -0,0 +1,21 @@
From 21c96c3781f473cdbfe7acdb1affba75b50081f1 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Tue, 22 Sep 2015 12:28:28 +0200
Subject: [PATCH] rules: prandom character device node permissions
Related: #1523227
---
rules/40-redhat.rules | 3 +++
1 file changed, 3 insertions(+)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 305e752285..9a48adde19 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -11,3 +11,6 @@ ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/sys
# load SCSI generic (sg) driver
SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST!="[module/sg]", RUN+="/sbin/modprobe -bv sg"
+
+# Rule for prandom character device node permissions
+KERNEL=="prandom", MODE="0644"

@ -0,0 +1,22 @@
From fab2dff96f59e0851884b4ef32dccab763f5eef1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Nykr=C3=BDn?= <lnykryn@redhat.com>
Date: Thu, 18 Aug 2016 14:51:19 +0200
Subject: [PATCH] rules: load sg driver also when scsi_target appears (#45)
Related: #1523227
---
rules/40-redhat.rules | 1 +
1 file changed, 1 insertion(+)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 9a48adde19..3335fe5075 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -11,6 +11,7 @@ ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/sys
# load SCSI generic (sg) driver
SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST!="[module/sg]", RUN+="/sbin/modprobe -bv sg"
+SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_target", TEST!="[module/sg]", RUN+="/sbin/modprobe -bv sg"
# Rule for prandom character device node permissions
KERNEL=="prandom", MODE="0644"

@ -0,0 +1,23 @@
From fd091394e52cd652ff5163735b2a91a8c0efe415 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Tue, 13 Sep 2016 13:18:38 +0200
Subject: [PATCH] rules: don't hoplug memory on s390x
Related: #1523227
---
rules/40-redhat.rules | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 3335fe5075..4c56950dab 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -4,7 +4,7 @@
SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
# Memory hotadd request
-SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online"
+SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/usr/bin/systemd-detect-virt", RESULT!="zvm", ATTR{state}=="offline", ATTR{state}="online"
# reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"

@ -0,0 +1,24 @@
From a0802638f02b964cb9d2d68bad009561b2bcc910 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Fri, 16 Sep 2016 14:45:01 +0200
Subject: [PATCH] rules: disable auto-online of hot-plugged memory on IBM z
Systems
Related: #1523227
---
rules/40-redhat.rules | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 4c56950dab..c3df320234 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -4,7 +4,7 @@
SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
# Memory hotadd request
-SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/usr/bin/systemd-detect-virt", RESULT!="zvm", ATTR{state}=="offline", ATTR{state}="online"
+SUBSYSTEM=="memory", ACTION=="add", PROGRAM=="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online"
# reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"

@ -0,0 +1,39 @@
From 0c5b8096cb23701f8048dba33a38e1b55249cab3 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Wed, 28 Mar 2018 17:22:30 +0200
Subject: [PATCH] rules: introduce old-style by-path symlinks for FCP based
SCSI devices
Related: #1523227
---
rules/40-redhat.rules | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index c3df320234..8ac96933c3 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -15,3 +15,23 @@ SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_target", TEST!="[module/sg]", RUN+="/sbin
# Rule for prandom character device node permissions
KERNEL=="prandom", MODE="0644"
+
+# Rules for creating the ID_PATH for SCSI devices based on the CCW bus
+# using the form: ccw-<BUS_ID>-zfcp-<WWPN>:<LUN>
+#
+ACTION=="remove", GOTO="zfcp_scsi_device_end"
+
+#
+# Set environment variable "ID_ZFCP_BUS" to "1" if the devices
+# (both disk and partition) are SCSI devices based on FCP devices
+#
+KERNEL=="sd*", SUBSYSTEMS=="ccw", DRIVERS=="zfcp", ENV{.ID_ZFCP_BUS}="1"
+
+# For SCSI disks
+KERNEL=="sd*[!0-9]", SUBSYSTEMS=="scsi", ENV{.ID_ZFCP_BUS}=="1", ENV{DEVTYPE}=="disk", SYMLINK+="disk/by-path/ccw-$attr{hba_id}-zfcp-$attr{wwpn}:$attr{fcp_lun}"
+
+
+# For partitions on a SCSI disk
+KERNEL=="sd*[0-9]", SUBSYSTEMS=="scsi", ENV{.ID_ZFCP_BUS}=="1", ENV{DEVTYPE}=="partition", SYMLINK+="disk/by-path/ccw-$attr{hba_id}-zfcp-$attr{wwpn}:$attr{fcp_lun}-part%n"
+
+LABEL="zfcp_scsi_device_end"

@ -0,0 +1,123 @@
From 1bb734a44952a51285057409ba7b1c3e7a162cea Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 2 Aug 2018 13:16:49 +0200
Subject: [PATCH] Revert "udev: remove WAIT_FOR key"
This reverts commit f2b8052fb648b788936dd3e85be6a9aca90fbb2f.
Resolves: #1523213
---
man/udev.xml | 9 +++++++
src/udev/udev-rules.c | 50 +++++++++++++++++++++++++++++++++++++++
test/rule-syntax-check.py | 2 +-
3 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/man/udev.xml b/man/udev.xml
index 15e6d8eae1..bdf901a8f0 100644
--- a/man/udev.xml
+++ b/man/udev.xml
@@ -515,6 +515,15 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>WAIT_FOR</varname></term>
+ <listitem>
+ <para>Wait for a file to become available or until a timeout of
+ 10 seconds expires. The path is relative to the sysfs device;
+ if no path is specified, this waits for an attribute to appear.</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>OPTIONS</varname></term>
<listitem>
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index f029395884..58af863f3d 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -676,6 +676,41 @@ static int import_parent_into_properties(struct udev_device *dev, const char *fi
return 0;
}
+#define WAIT_LOOP_PER_SECOND 50
+static int wait_for_file(struct udev_device *dev, const char *file, int timeout) {
+ char filepath[UTIL_PATH_SIZE];
+ char devicepath[UTIL_PATH_SIZE];
+ struct stat stats;
+ int loop = timeout * WAIT_LOOP_PER_SECOND;
+
+ /* a relative path is a device attribute */
+ devicepath[0] = '\0';
+ if (file[0] != '/') {
+ strscpyl(devicepath, sizeof(devicepath), udev_device_get_syspath(dev), NULL);
+ strscpyl(filepath, sizeof(filepath), devicepath, "/", file, NULL);
+ file = filepath;
+ }
+
+ while (--loop) {
+ const struct timespec duration = { 0, 1000 * 1000 * 1000 / WAIT_LOOP_PER_SECOND };
+
+ /* lookup file */
+ if (stat(file, &stats) == 0) {
+ log_debug("file '%s' appeared after %i loops", file, (timeout * WAIT_LOOP_PER_SECOND) - loop-1);
+ return 0;
+ }
+ /* make sure, the device did not disappear in the meantime */
+ if (devicepath[0] != '\0' && stat(devicepath, &stats) != 0) {
+ log_debug("device disappeared while waiting for '%s'", file);
+ return -2;
+ }
+ log_debug("wait for '%s' for %i mseconds", file, 1000 / WAIT_LOOP_PER_SECOND);
+ nanosleep(&duration, NULL);
+ }
+ log_debug("waiting for '%s' failed", file);
+ return -1;
+}
+
static void attr_subst_subdir(char *attr, size_t len) {
const char *pos, *tail, *path;
_cleanup_closedir_ DIR *dir = NULL;
@@ -1284,7 +1319,12 @@ static void add_rule(struct udev_rules *rules, char *line,
rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd);
} else
LOG_RULE_ERROR("ignoring unknown %s{} type '%s'", "RUN", attr);
+ } else if (streq(key, "WAIT_FOR") || streq(key, "WAIT_FOR_SYSFS")) {
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
+ rule_add_key(&rule_tmp, TK_M_WAITFOR, 0, value, NULL);
+ continue;
} else if (streq(key, "LABEL")) {
if (op == OP_REMOVE)
LOG_AND_RETURN("invalid %s operation", key);
@@ -1838,6 +1878,16 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
if (match_key(rules, cur, udev_device_get_driver(event->dev)) != 0)
goto nomatch;
break;
+ case TK_M_WAITFOR: {
+ char filename[UTIL_PATH_SIZE];
+ int found;
+
+ udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename), false);
+ found = (wait_for_file(event->dev, filename, 10) == 0);
+ if (!found && (cur->key.op != OP_NOMATCH))
+ goto nomatch;
+ break;
+ }
case TK_M_ATTR:
if (match_attr(rules, event->dev, event, cur) != 0)
goto nomatch;
diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py
index dfb06d9ed9..706d93632e 100755
--- a/test/rule-syntax-check.py
+++ b/test/rule-syntax-check.py
@@ -18,7 +18,7 @@ if not rules_files:
quoted_string_re = r'"(?:[^\\"]|\\.)*"'
no_args_tests = re.compile(r'(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|PROGRAM|RESULT|TEST)\s*(?:=|!)=\s*' + quoted_string_re + '$')
args_tests = re.compile(r'(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$')
-no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$')
+no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|WAIT_FOR|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$')
args_assign = re.compile(r'(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*' + quoted_string_re + '$')
# Find comma-separated groups, but allow commas that are inside quoted strings.
# Using quoted_string_re + '?' so that strings missing the last double quote

@ -0,0 +1,22 @@
From ab0228c3d6ceba20cf89ceb1b16b7e314aaaf989 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Tue, 7 Aug 2018 10:38:33 +0200
Subject: [PATCH] net_setup_link: allow renaming interfaces that were renamed
previously
---
src/udev/net/link-config.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index cec4f4f779..5113586457 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -306,7 +306,6 @@ static bool should_rename(struct udev_device *device, bool respect_predictable)
switch (type) {
case NET_NAME_USER:
- case NET_NAME_RENAMED:
/* these were already named by userspace, do not touch again */
return false;
case NET_NAME_PREDICTABLE:

@ -0,0 +1,23 @@
From b61e8046ebcb28225423fc0073183d68d4c577c4 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 9 Aug 2018 15:28:44 +0200
Subject: [PATCH] units: drop DynamicUser=yes from systemd-resolved.service
We don't really need DynamicUser since we add systemd-resolve user
from rpm script
---
units/systemd-resolved.service.in | 1 -
1 file changed, 1 deletion(-)
diff --git a/units/systemd-resolved.service.in b/units/systemd-resolved.service.in
index 9982ecebff..aaed406ab2 100644
--- a/units/systemd-resolved.service.in
+++ b/units/systemd-resolved.service.in
@@ -26,7 +26,6 @@ RestartSec=0
ExecStart=!!@rootlibexecdir@/systemd-resolved
WatchdogSec=3min
User=systemd-resolve
-DynamicUser=yes
CapabilityBoundingSet=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE
PrivateDevices=yes

@ -0,0 +1,73 @@
From 8618ef2fb30b4139c9bec4e45fb499cd8192a87f Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 9 Aug 2018 23:23:00 +0200
Subject: [PATCH] journal: remove journal audit socket
Resolves: #1614554
---
units/meson.build | 2 --
units/systemd-journald-audit.socket | 22 ----------------------
units/systemd-journald.service.in | 4 ++--
3 files changed, 2 insertions(+), 26 deletions(-)
delete mode 100644 units/systemd-journald-audit.socket
diff --git a/units/meson.build b/units/meson.build
index e4ac6ced64..e54a84ccbf 100644
--- a/units/meson.build
+++ b/units/meson.build
@@ -89,8 +89,6 @@ units = [
'sockets.target.wants/'],
['systemd-journal-gatewayd.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'],
['systemd-journal-remote.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'],
- ['systemd-journald-audit.socket', '',
- 'sockets.target.wants/'],
['systemd-journald-dev-log.socket', '',
'sockets.target.wants/'],
['systemd-journald.socket', '',
diff --git a/units/systemd-journald-audit.socket b/units/systemd-journald-audit.socket
deleted file mode 100644
index cb8b774963..0000000000
--- a/units/systemd-journald-audit.socket
+++ /dev/null
@@ -1,22 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1+
-#
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-
-[Unit]
-Description=Journal Audit Socket
-Documentation=man:systemd-journald.service(8) man:journald.conf(5)
-DefaultDependencies=no
-Before=sockets.target
-ConditionSecurity=audit
-ConditionCapability=CAP_AUDIT_READ
-
-[Socket]
-Service=systemd-journald.service
-ReceiveBuffer=128M
-ListenNetlink=audit 1
-PassCredentials=yes
diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in
index 52939e6820..8f5021d0de 100644
--- a/units/systemd-journald.service.in
+++ b/units/systemd-journald.service.in
@@ -12,12 +12,12 @@ Description=Journal Service
Documentation=man:systemd-journald.service(8) man:journald.conf(5)
DefaultDependencies=no
Requires=systemd-journald.socket
-After=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald-audit.socket syslog.socket
+After=systemd-journald.socket systemd-journald-dev-log.socket syslog.socket
Before=sysinit.target
[Service]
Type=notify
-Sockets=systemd-journald.socket systemd-journald-dev-log.socket systemd-journald-audit.socket
+Sockets=systemd-journald.socket systemd-journald-dev-log.socket
ExecStart=@rootlibexecdir@/systemd-journald
Restart=always
RestartSec=0

@ -0,0 +1,117 @@
From c6903d1b42d1773fda4df6676618489ad760a2a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 18 Jul 2018 12:16:33 +0200
Subject: [PATCH] bus: move BUS_DONT_DESTROY calls after asserts
It's not useful to bump the reference count before checking if the object is
NULL. Thanks to d40f5cc498 we can do this ;).
Related to https://bugzilla.redhat.com/show_bug.cgi?id=1576084,
https://bugzilla.redhat.com/show_bug.cgi?id=1575340,
https://bugzilla.redhat.com/show_bug.cgi?id=1575350. I'm not sure why those two
people hit this code path, while most people don't. At least we won't abort.
(cherry picked from commit 7ae8edcd03f74da123298330b76c3fc5425042ef)
Resolves: #1610397
---
src/libsystemd/sd-bus/bus-objects.c | 15 ++++++++-------
src/libsystemd/sd-bus/sd-bus.c | 3 ++-
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c
index 9609834fa9..a18ff88b07 100644
--- a/src/libsystemd/sd-bus/bus-objects.c
+++ b/src/libsystemd/sd-bus/bus-objects.c
@@ -2090,7 +2090,6 @@ _public_ int sd_bus_emit_properties_changed_strv(
const char *interface,
char **names) {
- BUS_DONT_DESTROY(bus);
bool found_interface = false;
char *prefix;
int r;
@@ -2111,6 +2110,8 @@ _public_ int sd_bus_emit_properties_changed_strv(
if (names && names[0] == NULL)
return 0;
+ BUS_DONT_DESTROY(bus);
+
do {
bus->nodes_modified = false;
@@ -2310,8 +2311,6 @@ static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *p
}
_public_ int sd_bus_emit_object_added(sd_bus *bus, const char *path) {
- BUS_DONT_DESTROY(bus);
-
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
struct node *object_manager;
int r;
@@ -2341,6 +2340,8 @@ _public_ int sd_bus_emit_object_added(sd_bus *bus, const char *path) {
if (r == 0)
return -ESRCH;
+ BUS_DONT_DESTROY(bus);
+
do {
bus->nodes_modified = false;
m = sd_bus_message_unref(m);
@@ -2481,8 +2482,6 @@ static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char
}
_public_ int sd_bus_emit_object_removed(sd_bus *bus, const char *path) {
- BUS_DONT_DESTROY(bus);
-
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
struct node *object_manager;
int r;
@@ -2512,6 +2511,8 @@ _public_ int sd_bus_emit_object_removed(sd_bus *bus, const char *path) {
if (r == 0)
return -ESRCH;
+ BUS_DONT_DESTROY(bus);
+
do {
bus->nodes_modified = false;
m = sd_bus_message_unref(m);
@@ -2645,8 +2646,6 @@ static int interfaces_added_append_one(
}
_public_ int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, char **interfaces) {
- BUS_DONT_DESTROY(bus);
-
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
struct node *object_manager;
char **i;
@@ -2669,6 +2668,8 @@ _public_ int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, ch
if (r == 0)
return -ESRCH;
+ BUS_DONT_DESTROY(bus);
+
do {
bus->nodes_modified = false;
m = sd_bus_message_unref(m);
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 089b51a6d9..7f03528b89 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -2883,7 +2883,6 @@ finish:
}
static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
- BUS_DONT_DESTROY(bus);
int r;
/* Returns 0 when we didn't do anything. This should cause the
@@ -2899,6 +2898,8 @@ static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priorit
assert_return(!bus->current_message, -EBUSY);
assert(!bus->current_slot);
+ BUS_DONT_DESTROY(bus);
+
switch (bus->state) {
case BUS_UNSET:

@ -0,0 +1,23 @@
From 56f614a5d6305dc1d304c30438db5b394d16e2da Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Fri, 12 Oct 2018 13:58:34 +0000
Subject: [PATCH] random-seed: raise POOL_SIZE_MIN constant to 1024
Resolves: #1619268
---
src/random-seed/random-seed.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c
index 223b56306c..adc9f298c1 100644
--- a/src/random-seed/random-seed.c
+++ b/src/random-seed/random-seed.c
@@ -14,7 +14,7 @@
#include "string-util.h"
#include "util.h"
-#define POOL_SIZE_MIN 512
+#define POOL_SIZE_MIN 1024
int main(int argc, char *argv[]) {
_cleanup_close_ int seed_fd = -1, random_fd = -1;

@ -0,0 +1,119 @@
From a046230cfb7e02938e3ad2ac85515636b319651e Mon Sep 17 00:00:00 2001
From: Dimitri John Ledkov <xnox@ubuntu.com>
Date: Wed, 29 Aug 2018 15:38:09 +0100
Subject: [PATCH] cryptsetup: add support for sector-size= option (#9936)
Bug-Ubuntu: https://launchpad.net/bugs/1776626
Closes #8881.
(cherry picked from commit a9fc640671ef60ac949f1ace6fa687ff242fc233)
Resolves: #1572563
---
man/crypttab.xml | 9 +++++++++
meson.build | 6 ++++++
src/cryptsetup/cryptsetup.c | 30 ++++++++++++++++++++++++++++++
3 files changed, 45 insertions(+)
diff --git a/man/crypttab.xml b/man/crypttab.xml
index dcaf03d2ca..3574ce00da 100644
--- a/man/crypttab.xml
+++ b/man/crypttab.xml
@@ -250,6 +250,15 @@
option.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>sector-size=</option></term>
+
+ <listitem><para>Specifies the sector size in bytes. See
+ <citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ for possible values and the default value of this
+ option.</para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>swap</option></term>
diff --git a/meson.build b/meson.build
index a0e7240708..f308db2631 100644
--- a/meson.build
+++ b/meson.build
@@ -927,11 +927,17 @@ if want_libcryptsetup != 'false' and not fuzzer_build
version : '>= 1.6.0',
required : want_libcryptsetup == 'true')
have = libcryptsetup.found()
+ have_sector = cc.has_member(
+ 'struct crypt_params_plain',
+ 'sector_size',
+ prefix : '#include <libcryptsetup.h>')
else
have = false
+ have_sector = false
libcryptsetup = []
endif
conf.set10('HAVE_LIBCRYPTSETUP', have)
+conf.set10('HAVE_LIBCRYPTSETUP_SECTOR_SIZE', have_sector)
want_libcurl = get_option('libcurl')
if want_libcurl != 'false' and not fuzzer_build
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index 832168184a..87008cb969 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -23,10 +23,14 @@
/* internal helper */
#define ANY_LUKS "LUKS"
+/* as in src/cryptsetup.h */
+#define CRYPT_SECTOR_SIZE 512
+#define CRYPT_MAX_SECTOR_SIZE 4096
static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT or CRYPT_PLAIN */
static char *arg_cipher = NULL;
static unsigned arg_key_size = 0;
+static unsigned arg_sector_size = CRYPT_SECTOR_SIZE;
static int arg_key_slot = CRYPT_ANY_SLOT;
static unsigned arg_keyfile_size = 0;
static uint64_t arg_keyfile_offset = 0;
@@ -86,6 +90,29 @@ static int parse_one_option(const char *option) {
arg_key_size /= 8;
+ } else if ((val = startswith(option, "sector-size="))) {
+
+#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE
+ r = safe_atou(val, &arg_sector_size);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
+ return 0;
+ }
+
+ if (arg_sector_size % 2) {
+ log_error("sector-size= not a multiple of 2, ignoring.");
+ return 0;
+ }
+
+ if (arg_sector_size < CRYPT_SECTOR_SIZE || arg_sector_size > CRYPT_MAX_SECTOR_SIZE) {
+ log_error("sector-size= is outside of %u and %u, ignoring.", CRYPT_SECTOR_SIZE, CRYPT_MAX_SECTOR_SIZE);
+ return 0;
+ }
+#else
+ log_error("sector-size= is not supported, compiled with old libcryptsetup.");
+ return 0;
+#endif
+
} else if ((val = startswith(option, "key-slot="))) {
arg_type = ANY_LUKS;
@@ -471,6 +498,9 @@ static int attach_luks_or_plain(struct crypt_device *cd,
struct crypt_params_plain params = {
.offset = arg_offset,
.skip = arg_skip,
+#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE
+ .sector_size = arg_sector_size,
+#endif
};
const char *cipher, *cipher_mode;
_cleanup_free_ char *truncated_cipher = NULL;

@ -0,0 +1,29 @@
From 96b6171376bfdb7417143a2026beda059fe3e22f Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sat, 1 Sep 2018 23:47:46 +0900
Subject: [PATCH] cryptsetup: do not define arg_sector_size if libgcrypt is
v1.x (#9990)
Follow-up for #9936.
(cherry picked from commit 645461f0cf6ec91e5b0b571559fb4cc4898192bc)
Related: #1572563
---
src/cryptsetup/cryptsetup.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index 87008cb969..abeba44ee8 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -30,7 +30,9 @@
static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT or CRYPT_PLAIN */
static char *arg_cipher = NULL;
static unsigned arg_key_size = 0;
+#if HAVE_LIBCRYPTSETUP_SECTOR_SIZE
static unsigned arg_sector_size = CRYPT_SECTOR_SIZE;
+#endif
static int arg_key_slot = CRYPT_ANY_SLOT;
static unsigned arg_keyfile_size = 0;
static uint64_t arg_keyfile_offset = 0;

@ -0,0 +1,112 @@
From e143339ac712f745727951973417ce93b5d06d78 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Fri, 12 Oct 2018 14:50:09 +0000
Subject: [PATCH] units: don't enable per-service IP firewall by default
Resolves: #1630219
---
units/systemd-coredump@.service.in | 1 -
units/systemd-hostnamed.service.in | 1 -
units/systemd-journald.service.in | 1 -
units/systemd-localed.service.in | 1 -
units/systemd-logind.service.in | 1 -
units/systemd-machined.service.in | 1 -
units/systemd-portabled.service.in | 1 -
units/systemd-timedated.service.in | 1 -
units/systemd-udevd.service.in | 1 -
9 files changed, 9 deletions(-)
diff --git a/units/systemd-coredump@.service.in b/units/systemd-coredump@.service.in
index 215696ecd1..68a68a5055 100644
--- a/units/systemd-coredump@.service.in
+++ b/units/systemd-coredump@.service.in
@@ -37,5 +37,4 @@ SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
StateDirectory=systemd/coredump
diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in
index da74b4fe8b..4e5470dd29 100644
--- a/units/systemd-hostnamed.service.in
+++ b/units/systemd-hostnamed.service.in
@@ -33,5 +33,4 @@ SystemCallFilter=@system-service sethostname
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
ReadWritePaths=/etc
diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in
index 8f5021d0de..2d5fd0120d 100644
--- a/units/systemd-journald.service.in
+++ b/units/systemd-journald.service.in
@@ -33,7 +33,6 @@ SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
# Increase the default a bit in order to allow many simultaneous
# services being run since we keep one fd open per service. Also, when
diff --git a/units/systemd-localed.service.in b/units/systemd-localed.service.in
index a24e61a0cd..ce043db154 100644
--- a/units/systemd-localed.service.in
+++ b/units/systemd-localed.service.in
@@ -33,5 +33,4 @@ SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
ReadWritePaths=/etc
diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
index 5e090bcf23..6953fac55b 100644
--- a/units/systemd-logind.service.in
+++ b/units/systemd-logind.service.in
@@ -34,7 +34,6 @@ SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
FileDescriptorStoreMax=512
# Increase the default a bit in order to allow many simultaneous
diff --git a/units/systemd-machined.service.in b/units/systemd-machined.service.in
index 1200a90a61..dec2c4b0dc 100644
--- a/units/systemd-machined.service.in
+++ b/units/systemd-machined.service.in
@@ -27,7 +27,6 @@ SystemCallFilter=@system-service @mount
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
# Note that machined cannot be placed in a mount namespace, since it
# needs access to the host's mount namespace in order to implement the
diff --git a/units/systemd-portabled.service.in b/units/systemd-portabled.service.in
index a868f61dba..64f14071e8 100644
--- a/units/systemd-portabled.service.in
+++ b/units/systemd-portabled.service.in
@@ -23,4 +23,3 @@ RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io @reboot @swap
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
diff --git a/units/systemd-timedated.service.in b/units/systemd-timedated.service.in
index 906bb4326c..662b39557a 100644
--- a/units/systemd-timedated.service.in
+++ b/units/systemd-timedated.service.in
@@ -31,5 +31,4 @@ SystemCallFilter=@system-service @clock
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any
ReadWritePaths=/etc
diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in
index 6a3814e5d9..fd9ead3bb8 100644
--- a/units/systemd-udevd.service.in
+++ b/units/systemd-udevd.service.in
@@ -33,4 +33,3 @@ SystemCallFilter=@system-service @module @raw-io
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
-IPAddressDeny=any

@ -0,0 +1,45 @@
From 87922b7adc47f311e89b21e37b26ee300a401e1d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 9 Jul 2018 13:21:44 +0200
Subject: [PATCH] bus-message: do not crash on message with a string of zero
length
We'd calculate the "real" length of the string as 'item_size - 1', which does
not work out well when item_size == 0.
(cherry picked from commit 81b6e63029eefcb0ec03a3a7c248490e38106073)
Resolves: #1635439
---
src/libsystemd/sd-bus/bus-message.c | 6 ++++++
.../crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e | Bin 0 -> 51 bytes
2 files changed, 6 insertions(+)
create mode 100644 test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 8d92bc2002..381034f5f8 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -3312,6 +3312,12 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
bool ok;
+ /* D-Bus spec: The marshalling formats for the string-like types all end
+ * with a single zero (NUL) byte, but that byte is not considered to be part
+ * of the text. */
+ if (c->item_size == 0)
+ return -EBADMSG;
+
r = message_peek_body(m, &rindex, 1, c->item_size, &q);
if (r < 0)
return r;
diff --git a/test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e b/test/fuzz/fuzz-bus-message/crash-29ed3c202e0ffade3cad42c8bbeb6cc68a21eb8e
new file mode 100644
index 0000000000000000000000000000000000000000..4488f0a6c685b5d43eddbe41a0c6a3b6be9b02e2
GIT binary patch
literal 51
fcmc~1WMC4sJpJnr13KV`0|t%6q+%$@&=ddw)CUPg
literal 0
HcmV?d00001

@ -0,0 +1,279 @@
From 26de3af817b0c5746cb61b798ae8e138e01ea17c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 9 Jul 2018 07:03:01 +0200
Subject: [PATCH] Introduce free_and_strndup and use it in bus-message.c
v2: fix error in free_and_strndup()
When the orignal and copied message were the same, but shorter than specified
length l, memory read past the end of the buffer would be performed. A test
case is included: a string that had an embedded NUL ("q\0") is used to replace
"q".
v3: Fix one more bug in free_and_strndup and add tests.
v4: Some style fixed based on review, one more use of free_and_replace, and
make the tests more comprehensive.
(cherry picked from commit 7f546026abbdc56c453a577e52d57159458c3e9c)
Resolves: #1635428
---
src/basic/string-util.c | 28 +++++++-
src/basic/string-util.h | 1 +
src/libsystemd/sd-bus/bus-message.c | 34 ++++------
src/test/test-string-util.c | 62 ++++++++++++++++++
...h-b88ad9ecf4aacf4a0caca5b5543953265367f084 | Bin 0 -> 32 bytes
5 files changed, 103 insertions(+), 22 deletions(-)
create mode 100644 test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084
diff --git a/src/basic/string-util.c b/src/basic/string-util.c
index 0a40683493..dfa739996f 100644
--- a/src/basic/string-util.c
+++ b/src/basic/string-util.c
@@ -1004,7 +1004,7 @@ int free_and_strdup(char **p, const char *s) {
assert(p);
- /* Replaces a string pointer with an strdup()ed new string,
+ /* Replaces a string pointer with a strdup()ed new string,
* possibly freeing the old one. */
if (streq_ptr(*p, s))
@@ -1023,6 +1023,32 @@ int free_and_strdup(char **p, const char *s) {
return 1;
}
+int free_and_strndup(char **p, const char *s, size_t l) {
+ char *t;
+
+ assert(p);
+ assert(s || l == 0);
+
+ /* Replaces a string pointer with a strndup()ed new string,
+ * freeing the old one. */
+
+ if (!*p && !s)
+ return 0;
+
+ if (*p && s && strneq(*p, s, l) && (l > strlen(*p) || (*p)[l] == '\0'))
+ return 0;
+
+ if (s) {
+ t = strndup(s, l);
+ if (!t)
+ return -ENOMEM;
+ } else
+ t = NULL;
+
+ free_and_replace(*p, t);
+ return 1;
+}
+
#if !HAVE_EXPLICIT_BZERO
/*
* Pointer to memset is volatile so that compiler must de-reference
diff --git a/src/basic/string-util.h b/src/basic/string-util.h
index c0cc4e78d7..96a9260f93 100644
--- a/src/basic/string-util.h
+++ b/src/basic/string-util.h
@@ -176,6 +176,7 @@ char *strrep(const char *s, unsigned n);
int split_pair(const char *s, const char *sep, char **l, char **r);
int free_and_strdup(char **p, const char *s);
+int free_and_strndup(char **p, const char *s, size_t l);
/* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */
static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 381034f5f8..7c8bad2bdd 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -4175,20 +4175,19 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (contents) {
size_t l;
- char *sig;
r = signature_element_length(c->signature+c->index+1, &l);
if (r < 0)
return r;
- assert(l >= 1);
+ /* signature_element_length does verification internally */
- sig = strndup(c->signature + c->index + 1, l);
- if (!sig)
+ assert(l >= 1);
+ if (free_and_strndup(&c->peeked_signature,
+ c->signature + c->index + 1, l) < 0)
return -ENOMEM;
- free(c->peeked_signature);
- *contents = c->peeked_signature = sig;
+ *contents = c->peeked_signature;
}
if (type)
@@ -4201,19 +4200,17 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (contents) {
size_t l;
- char *sig;
r = signature_element_length(c->signature+c->index, &l);
if (r < 0)
return r;
assert(l >= 2);
- sig = strndup(c->signature + c->index + 1, l - 2);
- if (!sig)
+ if (free_and_strndup(&c->peeked_signature,
+ c->signature + c->index + 1, l - 2) < 0)
return -ENOMEM;
- free(c->peeked_signature);
- *contents = c->peeked_signature = sig;
+ *contents = c->peeked_signature;
}
if (type)
@@ -4253,9 +4250,8 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (k > c->item_size)
return -EBADMSG;
- free(c->peeked_signature);
- c->peeked_signature = strndup((char*) q + 1, k - 1);
- if (!c->peeked_signature)
+ if (free_and_strndup(&c->peeked_signature,
+ (char*) q + 1, k - 1) < 0)
return -ENOMEM;
if (!signature_is_valid(c->peeked_signature, true))
@@ -5085,25 +5081,21 @@ int bus_message_parse_fields(sd_bus_message *m) {
if (*p == 0) {
size_t l;
- char *c;
/* We found the beginning of the signature
* string, yay! We require the body to be a
* structure, so verify it and then strip the
* opening/closing brackets. */
- l = ((char*) m->footer + m->footer_accessible) - p - (1 + sz);
+ l = (char*) m->footer + m->footer_accessible - p - (1 + sz);
if (l < 2 ||
p[1] != SD_BUS_TYPE_STRUCT_BEGIN ||
p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END)
return -EBADMSG;
- c = strndup(p + 1 + 1, l - 2);
- if (!c)
+ if (free_and_strndup(&m->root_container.signature,
+ p + 1 + 1, l - 2) < 0)
return -ENOMEM;
-
- free(m->root_container.signature);
- m->root_container.signature = c;
break;
}
diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c
index 3e72ce2c0a..43a6b14c34 100644
--- a/src/test/test-string-util.c
+++ b/src/test/test-string-util.c
@@ -5,6 +5,7 @@
#include "macro.h"
#include "string-util.h"
#include "strv.h"
+#include "tests.h"
#include "utf8.h"
static void test_string_erase(void) {
@@ -30,6 +31,64 @@ static void test_string_erase(void) {
assert_se(x[9] == '\0');
}
+static void test_free_and_strndup_one(char **t, const char *src, size_t l, const char *expected, bool change) {
+ int r;
+
+ log_debug("%s: \"%s\", \"%s\", %zd (expect \"%s\", %s)",
+ __func__, strnull(*t), strnull(src), l, strnull(expected), yes_no(change));
+
+ r = free_and_strndup(t, src, l);
+ assert_se(streq_ptr(*t, expected));
+ assert_se(r == change); /* check that change occurs only when necessary */
+}
+
+static void test_free_and_strndup(void) {
+ static const struct test_case {
+ const char *src;
+ size_t len;
+ const char *expected;
+ } cases[] = {
+ {"abc", 0, ""},
+ {"abc", 0, ""},
+ {"abc", 1, "a"},
+ {"abc", 2, "ab"},
+ {"abc", 3, "abc"},
+ {"abc", 4, "abc"},
+ {"abc", 5, "abc"},
+ {"abc", 5, "abc"},
+ {"abc", 4, "abc"},
+ {"abc", 3, "abc"},
+ {"abc", 2, "ab"},
+ {"abc", 1, "a"},
+ {"abc", 0, ""},
+
+ {"", 0, ""},
+ {"", 1, ""},
+ {"", 2, ""},
+ {"", 0, ""},
+ {"", 1, ""},
+ {"", 2, ""},
+ {"", 2, ""},
+ {"", 1, ""},
+ {"", 0, ""},
+
+ {NULL, 0, NULL},
+
+ {"foo", 3, "foo"},
+ {"foobar", 6, "foobar"},
+ };
+
+ _cleanup_free_ char *t = NULL;
+ const char *prev_expected = t;
+
+ for (unsigned i = 0; i < ELEMENTSOF(cases); i++) {
+ test_free_and_strndup_one(&t,
+ cases[i].src, cases[i].len, cases[i].expected,
+ !streq_ptr(cases[i].expected, prev_expected));
+ prev_expected = t;
+ }
+}
+
static void test_ascii_strcasecmp_n(void) {
assert_se(ascii_strcasecmp_n("", "", 0) == 0);
@@ -497,7 +556,10 @@ static void test_memory_startswith(void) {
}
int main(int argc, char *argv[]) {
+ test_setup_logging(LOG_DEBUG);
+
test_string_erase();
+ test_free_and_strndup();
test_ascii_strcasecmp_n();
test_ascii_strcasecmp_nn();
test_cellescape();
diff --git a/test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084 b/test/fuzz/fuzz-bus-message/crash-b88ad9ecf4aacf4a0caca5b5543953265367f084
new file mode 100644
index 0000000000000000000000000000000000000000..52469650b5498a45d5d95bd9d933c989cfb47ca7
GIT binary patch
literal 32
ccmd1#|DTBg0(2Mzp)7_%AVVXuuuM|`09r!?!~g&Q
literal 0
HcmV?d00001

@ -0,0 +1,34 @@
From ab6a1bdf3519d4344dee4e0225c74fc1198c8a60 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 15 Oct 2018 10:54:11 +0000
Subject: [PATCH] tests: backport test_setup_logging()
Related: #1635428
---
src/shared/tests.c | 6 ++++++
src/shared/tests.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/src/shared/tests.c b/src/shared/tests.c
index 6b3df0aa07..b10343650f 100644
--- a/src/shared/tests.c
+++ b/src/shared/tests.c
@@ -54,3 +54,9 @@ const char* get_testdata_dir(const char *suffix) {
strncpy(testdir + strlen(testdir), suffix, sizeof(testdir) - strlen(testdir) - 1);
return testdir;
}
+
+void test_setup_logging(int level) {
+ log_set_max_level(level);
+ log_parse_environment();
+ log_open();
+}
diff --git a/src/shared/tests.h b/src/shared/tests.h
index b88135ed93..cad21169f8 100644
--- a/src/shared/tests.h
+++ b/src/shared/tests.h
@@ -3,3 +3,4 @@
char* setup_fake_runtime_dir(void);
const char* get_testdata_dir(const char *suffix);
+void test_setup_logging(int level);

@ -0,0 +1,23 @@
From 80d5f0e2057717e9e5588edcabac95b8c238795c Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 15 Oct 2018 10:55:50 +0000
Subject: [PATCH] journal: change support URL shown in the catalog entries
Resolves: #1550548
---
meson_options.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/meson_options.txt b/meson_options.txt
index 16c1f2b2fa..ab2a658713 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -205,7 +205,7 @@ option('ntp-servers', type : 'string',
value : 'time1.google.com time2.google.com time3.google.com time4.google.com')
option('support-url', type : 'string',
description : 'the support URL to show in catalog entries included in systemd',
- value : 'https://lists.freedesktop.org/mailman/listinfo/systemd-devel')
+ value : 'https://access.redhat.com/support')
option('www-target', type : 'string',
description : 'the address and dir to upload docs too',
value : 'www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd')

@ -0,0 +1,48 @@
From e0f2dd42fb02aa5767d38714c95ac10fb683ad67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Fri, 11 Mar 2016 17:06:17 -0500
Subject: [PATCH] resolved: create /etc/resolv.conf symlink at runtime
If the symlink doesn't exists, and we are being started, let's
create it to provie name resolution.
If it exists, do nothing. In particular, if it is a broken symlink,
we cannot really know if the administator configured it to point to
a location used by some service that hasn't started yet, so we
don't touch it in that case either.
https://bugzilla.redhat.com/show_bug.cgi?id=1313085
---
src/resolve/resolved.c | 4 ++++
tmpfiles.d/etc.conf.m4 | 3 ---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c
index c01e53e9da..f3d96df458 100644
--- a/src/resolve/resolved.c
+++ b/src/resolve/resolved.c
@@ -53,6 +53,10 @@ int main(int argc, char *argv[]) {
/* Drop privileges, but only if we have been started as root. If we are not running as root we assume all
* privileges are already dropped. */
if (getuid() == 0) {
+ r = symlink("../run/systemd/resolve/resolv.conf", "/etc/resolv.conf");
+ if (r < 0 && errno != EEXIST)
+ log_warning_errno(errno,
+ "Could not create /etc/resolv.conf symlink: %m");
/* Drop privileges, but keep three caps. Note that we drop those too, later on (see below) */
r = drop_privileges(uid, gid,
diff --git a/tmpfiles.d/etc.conf.m4 b/tmpfiles.d/etc.conf.m4
index df8d42101c..928105ea8d 100644
--- a/tmpfiles.d/etc.conf.m4
+++ b/tmpfiles.d/etc.conf.m4
@@ -13,9 +13,6 @@ L+ /etc/mtab - - - - ../proc/self/mounts
m4_ifdef(`HAVE_SMACK_RUN_LABEL',
t /etc/mtab - - - - security.SMACK64=_
)m4_dnl
-m4_ifdef(`ENABLE_RESOLVE',
-L! /etc/resolv.conf - - - - ../run/systemd/resolve/stub-resolv.conf
-)m4_dnl
C /etc/nsswitch.conf - - - -
m4_ifdef(`HAVE_PAM',
C /etc/pam.d - - - -

@ -0,0 +1,27 @@
From e615b80f3fda82ac7fe628800a9ff2103788bd05 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Tue, 9 Oct 2018 13:50:55 +0200
Subject: [PATCH] dissect-image: use right comparison function
fstype can be NULL here.
(cherry picked from commit 4db1879acdc0b853e1a7e6e650b6feb917175fac)
Resolves: #1602706
---
src/shared/dissect-image.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index fa1cf26ee1..e076c8e7db 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -230,7 +230,7 @@ int dissect_image(
.node = TAKE_PTR(n),
};
- m->encrypted = streq(fstype, "crypto_LUKS");
+ m->encrypted = streq_ptr(fstype, "crypto_LUKS");
*ret = TAKE_PTR(m);

@ -0,0 +1,60 @@
From 8fdca31b41a6470ceda8e0a84f90a1e5ca28aa5c Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Tue, 9 Oct 2018 17:26:19 +0200
Subject: [PATCH] login: avoid leak of name returned by uid_to_name()
(cherry picked from commit e99742ef3e9d847da04e71fec0eb426063b25068)
Resolves: #1602706
---
src/login/logind-dbus.c | 4 +++-
src/login/logind-utmp.c | 6 +++---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 13298cc855..dca7f4a30f 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2155,6 +2155,7 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd
if (cancelled && m->enable_wall_messages) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+ _cleanup_free_ char *username = NULL;
const char *tty = NULL;
uid_t uid = 0;
int r;
@@ -2165,8 +2166,9 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd
(void) sd_bus_creds_get_tty(creds, &tty);
}
+ username = uid_to_name(uid);
utmp_wall("The system shutdown has been cancelled",
- uid_to_name(uid), tty, logind_wall_tty_filter, m);
+ username, tty, logind_wall_tty_filter, m);
}
return sd_bus_reply_method_return(message, "b", cancelled);
diff --git a/src/login/logind-utmp.c b/src/login/logind-utmp.c
index 71ebdfcfb1..8bdd4ab6bf 100644
--- a/src/login/logind-utmp.c
+++ b/src/login/logind-utmp.c
@@ -61,7 +61,7 @@ bool logind_wall_tty_filter(const char *tty, void *userdata) {
static int warn_wall(Manager *m, usec_t n) {
char date[FORMAT_TIMESTAMP_MAX] = {};
- _cleanup_free_ char *l = NULL;
+ _cleanup_free_ char *l = NULL, *username = NULL;
usec_t left;
int r;
@@ -83,8 +83,8 @@ static int warn_wall(Manager *m, usec_t n) {
return 0;
}
- utmp_wall(l, uid_to_name(m->scheduled_shutdown_uid),
- m->scheduled_shutdown_tty, logind_wall_tty_filter, m);
+ username = uid_to_name(m->scheduled_shutdown_uid);
+ utmp_wall(l, username, m->scheduled_shutdown_tty, logind_wall_tty_filter, m);
return 1;
}

@ -0,0 +1,36 @@
From fbe394e9166ddfe847dcac0eab0fcbd3c225dc33 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Wed, 10 Oct 2018 09:33:28 +0200
Subject: [PATCH] firewall-util: add an assert that we're not overwriting a
buffer
... like commit f28501279d2c28fdbb31d8273b723e9bf71d3b98 does for
out_interface.
(cherry picked from commit 0b777d20e9a3868b12372ffce8040d1be063cec7)
Resolves: #1602706
---
src/shared/firewall-util.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/shared/firewall-util.c b/src/shared/firewall-util.c
index eb4f5ff616..cba52fb419 100644
--- a/src/shared/firewall-util.c
+++ b/src/shared/firewall-util.c
@@ -50,8 +50,14 @@ static int entry_fill_basics(
entry->ip.proto = protocol;
if (in_interface) {
+ size_t l;
+
+ l = strlen(in_interface);
+ assert(l < sizeof entry->ip.iniface);
+ assert(l < sizeof entry->ip.iniface_mask);
+
strcpy(entry->ip.iniface, in_interface);
- memset(entry->ip.iniface_mask, 0xFF, strlen(in_interface)+1);
+ memset(entry->ip.iniface_mask, 0xFF, l + 1);
}
if (source) {
entry->ip.src = source->in;

@ -0,0 +1,29 @@
From ebdb96247433d920b391672e019da9402aabd351 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Wed, 10 Oct 2018 13:56:54 +0200
Subject: [PATCH] journal-file: avoid calling ftruncate with invalid fd
This can happen if journal_file_close is called from the failure
handling code of journal_file_open before f->fd was established.
(cherry picked from commit c52368509f48e556be5a4c7a171361b656a25e02)
Resolves: #1602706
---
src/journal/journal-file.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 62e7f68a13..efc3ee052b 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1846,6 +1846,9 @@ static int journal_file_append_entry_internal(
void journal_file_post_change(JournalFile *f) {
assert(f);
+ if (f->fd < 0)
+ return;
+
/* inotify() does not receive IN_MODIFY events from file
* accesses done via mmap(). After each access we hence
* trigger IN_MODIFY by truncating the journal file to its

@ -0,0 +1,33 @@
From c232bc1f346a6af9777c216d01f7940898ae1650 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 19 Oct 2018 12:12:33 +0200
Subject: [PATCH] dhcp6: make sure we have enough space for the DHCP6 option
header
Fixes a vulnerability originally discovered by Felix Wilhelm from
Google.
CVE-2018-15688
LP: #1795921
https://bugzilla.redhat.com/show_bug.cgi?id=1639067
(cherry-picked from commit 4dac5eaba4e419b29c97da38a8b1f82336c2c892)
Resolves: #1643363
---
src/libsystemd-network/dhcp6-option.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c
index 18196b1257..0979497299 100644
--- a/src/libsystemd-network/dhcp6-option.c
+++ b/src/libsystemd-network/dhcp6-option.c
@@ -103,7 +103,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
return -EINVAL;
}
- if (*buflen < len)
+ if (*buflen < offsetof(DHCP6Option, data) + len)
return -ENOBUFS;
ia_hdr = *buf;

@ -0,0 +1,133 @@
From 35a23324975ac6ee0bbd3408394f992007b7a439 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 13 Nov 2018 11:59:06 +0100
Subject: [PATCH] =?UTF-8?q?core:=20rename=20queued=5Fmessage=20=E2=86=92?=
=?UTF-8?q?=20pending=5Freload=5Fmessage?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This field is only used for pending Reload() replies, hence let's rename
it to be more descriptive and precise.
No change in behaviour.
(cherry picked from commit 209de5256b7ba8600c3e73a85a43b86708998d65)
Resolves: #1647359
---
src/core/dbus-manager.c | 4 ++--
src/core/dbus.c | 12 ++++++------
src/core/dbus.h | 2 +-
src/core/manager.c | 6 +++---
src/core/manager.h | 2 +-
5 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 4ed68af1e0..d39c9b28c4 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -1329,8 +1329,8 @@ static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *
* is finished. That way the caller knows when the reload
* finished. */
- assert(!m->queued_message);
- r = sd_bus_message_new_method_return(message, &m->queued_message);
+ assert(!m->pending_reload_message);
+ r = sd_bus_message_new_method_return(message, &m->pending_reload_message);
if (r < 0)
return r;
diff --git a/src/core/dbus.c b/src/core/dbus.c
index bf5917696e..256a410215 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -47,23 +47,23 @@
static void destroy_bus(Manager *m, sd_bus **bus);
-int bus_send_queued_message(Manager *m) {
+int bus_send_pending_reload_message(Manager *m) {
int r;
assert(m);
- if (!m->queued_message)
+ if (!m->pending_reload_message)
return 0;
/* If we cannot get rid of this message we won't dispatch any
* D-Bus messages, so that we won't end up wanting to queue
* another message. */
- r = sd_bus_send(NULL, m->queued_message, NULL);
+ r = sd_bus_send(NULL, m->pending_reload_message, NULL);
if (r < 0)
log_warning_errno(r, "Failed to send queued message: %m");
- m->queued_message = sd_bus_message_unref(m->queued_message);
+ m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message);
return 0;
}
@@ -1079,8 +1079,8 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
u->bus_track = sd_bus_track_unref(u->bus_track);
/* Get rid of queued message on this bus */
- if (m->queued_message && sd_bus_message_get_bus(m->queued_message) == *bus)
- m->queued_message = sd_bus_message_unref(m->queued_message);
+ if (m->pending_reload_message && sd_bus_message_get_bus(m->pending_reload_message) == *bus)
+ m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message);
/* Possibly flush unwritten data, but only if we are
* unprivileged, since we don't want to sync here */
diff --git a/src/core/dbus.h b/src/core/dbus.h
index 382a96da7d..f1c0fa86c0 100644
--- a/src/core/dbus.h
+++ b/src/core/dbus.h
@@ -5,7 +5,7 @@
#include "manager.h"
-int bus_send_queued_message(Manager *m);
+int bus_send_pending_reload_message(Manager *m);
int bus_init_private(Manager *m);
int bus_init_api(Manager *m);
diff --git a/src/core/manager.c b/src/core/manager.c
index 930df4e23a..a24bfcacdf 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -2078,7 +2078,7 @@ static unsigned manager_dispatch_dbus_queue(Manager *m) {
return 0;
/* Anything to do at all? */
- if (!m->dbus_unit_queue && !m->dbus_job_queue && !m->send_reloading_done && !m->queued_message)
+ if (!m->dbus_unit_queue && !m->dbus_job_queue && !m->send_reloading_done && !m->pending_reload_message)
return 0;
/* Do we have overly many messages queued at the moment? If so, let's not enqueue more on top, let's sit this
@@ -2123,8 +2123,8 @@ static unsigned manager_dispatch_dbus_queue(Manager *m) {
n++, budget--;
}
- if (budget > 0 && m->queued_message) {
- bus_send_queued_message(m);
+ if (budget > 0 && m->pending_reload_message) {
+ bus_send_pending_reload_message(m);
n++;
}
diff --git a/src/core/manager.h b/src/core/manager.h
index ea5d425030..c7f4d66ecd 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -215,7 +215,7 @@ struct Manager {
/* This is used during reloading: before the reload we queue
* the reply message here, and afterwards we send it */
- sd_bus_message *queued_message;
+ sd_bus_message *pending_reload_message;
Hashmap *watch_bus; /* D-Bus names => Unit object n:1 */

@ -0,0 +1,36 @@
From 52a474cf15bf2b0edb449750eb63eb8cdb9a3780 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 13 Nov 2018 12:00:42 +0100
Subject: [PATCH] core: when we can't send the pending reload message, say we
ignore it in the warning we log
No change in behaviour, just better wording.
(cherry picked from commit 4b66bccab004221b903b43b4c224442bfa3e9ac7)
Resolves: #1647359
---
src/core/dbus.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/core/dbus.c b/src/core/dbus.c
index 256a410215..346a440c5d 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -55,13 +55,12 @@ int bus_send_pending_reload_message(Manager *m) {
if (!m->pending_reload_message)
return 0;
- /* If we cannot get rid of this message we won't dispatch any
- * D-Bus messages, so that we won't end up wanting to queue
- * another message. */
+ /* If we cannot get rid of this message we won't dispatch any D-Bus messages, so that we won't end up wanting
+ * to queue another message. */
r = sd_bus_send(NULL, m->pending_reload_message, NULL);
if (r < 0)
- log_warning_errno(r, "Failed to send queued message: %m");
+ log_warning_errno(r, "Failed to send queued message, ignoring: %m");
m->pending_reload_message = sd_bus_message_unref(m->pending_reload_message);

@ -0,0 +1,114 @@
From 0412acb95ffac94d5916ee19991cc7194e55953c Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 13 Nov 2018 12:48:49 +0100
Subject: [PATCH] core: make sure we don't throttle change signal generator
when a reload is pending
Fixes: #10627
(cherry picked from commit b8d381c47776ea0440af175cbe0c02cb743bde08)
Resolves: #1647359
---
src/core/manager.c | 64 ++++++++++++++++++++++++++++------------------
1 file changed, 39 insertions(+), 25 deletions(-)
diff --git a/src/core/manager.c b/src/core/manager.c
index a24bfcacdf..3b2fe11e87 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -2074,56 +2074,70 @@ static unsigned manager_dispatch_dbus_queue(Manager *m) {
assert(m);
+ /* Avoid recursion */
if (m->dispatching_dbus_queue)
return 0;
- /* Anything to do at all? */
- if (!m->dbus_unit_queue && !m->dbus_job_queue && !m->send_reloading_done && !m->pending_reload_message)
- return 0;
+ /* When we are reloading, let's not wait with generating signals, since we need to exit the manager as quickly
+ * as we can. There's no point in throttling generation of signals in that case. */
+ if (MANAGER_IS_RELOADING(m) || m->send_reloading_done || m->pending_reload_message)
+ budget = (unsigned) -1; /* infinite budget in this case */
+ else {
+ /* Anything to do at all? */
+ if (!m->dbus_unit_queue && !m->dbus_job_queue)
+ return 0;
- /* Do we have overly many messages queued at the moment? If so, let's not enqueue more on top, let's sit this
- * cycle out, and process things in a later cycle when the queues got a bit emptier. */
- if (manager_bus_n_queued_write(m) > MANAGER_BUS_BUSY_THRESHOLD)
- return 0;
+ /* Do we have overly many messages queued at the moment? If so, let's not enqueue more on top, let's
+ * sit this cycle out, and process things in a later cycle when the queues got a bit emptier. */
+ if (manager_bus_n_queued_write(m) > MANAGER_BUS_BUSY_THRESHOLD)
+ return 0;
- /* Only process a certain number of units/jobs per event loop iteration. Even if the bus queue wasn't overly
- * full before this call we shouldn't increase it in size too wildly in one step, and we shouldn't monopolize
- * CPU time with generating these messages. Note the difference in counting of this "budget" and the
- * "threshold" above: the "budget" is decreased only once per generated message, regardless how many
- * busses/direct connections it is enqueued on, while the "threshold" is applied to each queued instance of bus
- * message, i.e. if the same message is enqueued to five busses/direct connections it will be counted five
- * times. This difference in counting ("references" vs. "instances") is primarily a result of the fact that
- * it's easier to implement it this way, however it also reflects the thinking that the "threshold" should put
- * a limit on used queue memory, i.e. space, while the "budget" should put a limit on time. Also note that
- * the "threshold" is currently chosen much higher than the "budget". */
- budget = MANAGER_BUS_MESSAGE_BUDGET;
+ /* Only process a certain number of units/jobs per event loop iteration. Even if the bus queue wasn't
+ * overly full before this call we shouldn't increase it in size too wildly in one step, and we
+ * shouldn't monopolize CPU time with generating these messages. Note the difference in counting of
+ * this "budget" and the "threshold" above: the "budget" is decreased only once per generated message,
+ * regardless how many busses/direct connections it is enqueued on, while the "threshold" is applied to
+ * each queued instance of bus message, i.e. if the same message is enqueued to five busses/direct
+ * connections it will be counted five times. This difference in counting ("references"
+ * vs. "instances") is primarily a result of the fact that it's easier to implement it this way,
+ * however it also reflects the thinking that the "threshold" should put a limit on used queue memory,
+ * i.e. space, while the "budget" should put a limit on time. Also note that the "threshold" is
+ * currently chosen much higher than the "budget". */
+ budget = MANAGER_BUS_MESSAGE_BUDGET;
+ }
m->dispatching_dbus_queue = true;
- while (budget > 0 && (u = m->dbus_unit_queue)) {
+ while (budget != 0 && (u = m->dbus_unit_queue)) {
assert(u->in_dbus_queue);
bus_unit_send_change_signal(u);
- n++, budget--;
+ n++;
+
+ if (budget != (unsigned) -1)
+ budget--;
}
- while (budget > 0 && (j = m->dbus_job_queue)) {
+ while (budget != 0 && (j = m->dbus_job_queue)) {
assert(j->in_dbus_queue);
bus_job_send_change_signal(j);
- n++, budget--;
+ n++;
+
+ if (budget != (unsigned) -1)
+ budget--;
}
m->dispatching_dbus_queue = false;
- if (budget > 0 && m->send_reloading_done) {
+ if (m->send_reloading_done) {
m->send_reloading_done = false;
bus_manager_send_reloading(m, false);
- n++, budget--;
+ n++;
}
- if (budget > 0 && m->pending_reload_message) {
+ if (m->pending_reload_message) {
bus_send_pending_reload_message(m);
n++;
}

@ -0,0 +1,45 @@
From 84b15a8a493424efa8c9eaa9a44a23c3c59742bd Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Thu, 25 Oct 2018 16:21:26 +0200
Subject: [PATCH] proc-cmdline: introduce PROC_CMDLINE_RD_STRICT
Our current set of flags allows an option to be either
use just in initrd or both in initrd and normal system.
This new flag is intended to be used in the case where
you want apply some settings just in initrd or just
in normal system.
(cherry picked from commit ed58820d7669971762dd887dc117d922c23f2543)
Related: #1643429
---
src/basic/proc-cmdline.c | 3 ++-
src/basic/proc-cmdline.h | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c
index add481c2ae..530ac37460 100644
--- a/src/basic/proc-cmdline.c
+++ b/src/basic/proc-cmdline.c
@@ -72,7 +72,8 @@ int proc_cmdline_parse(proc_cmdline_parse_t parse_item, void *data, unsigned fla
if (flags & PROC_CMDLINE_STRIP_RD_PREFIX)
key = q;
- }
+ } else if (in_initrd() && flags & PROC_CMDLINE_RD_STRICT)
+ continue;
value = strchr(key, '=');
if (value)
diff --git a/src/basic/proc-cmdline.h b/src/basic/proc-cmdline.h
index 4a9e6e0f62..140200dbf4 100644
--- a/src/basic/proc-cmdline.h
+++ b/src/basic/proc-cmdline.h
@@ -8,6 +8,7 @@
enum {
PROC_CMDLINE_STRIP_RD_PREFIX = 1,
PROC_CMDLINE_VALUE_OPTIONAL = 2,
+ PROC_CMDLINE_RD_STRICT = 4
};
typedef int (*proc_cmdline_parse_t)(const char *key, const char *value, void *data);

@ -0,0 +1,77 @@
From 55798355455b9255458d6a705f8766c4dbe3ef73 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Thu, 25 Oct 2018 16:34:00 +0200
Subject: [PATCH] debug-generator: introduce rd.* version of all options
(cherry picked from commit a7dd6d04b07f58df5c0294743d76df0be0b4b928)
Resolves: #1643429
---
man/systemd-debug-generator.xml | 27 +++++++++++++++++++--------
src/debug-generator/debug-generator.c | 2 +-
2 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/man/systemd-debug-generator.xml b/man/systemd-debug-generator.xml
index d5cf4109b0..fa88e8ac01 100644
--- a/man/systemd-debug-generator.xml
+++ b/man/systemd-debug-generator.xml
@@ -33,27 +33,38 @@
that reads the kernel command line and understands three
options:</para>
- <para>If the <option>systemd.mask=</option> option is specified
- and followed by a unit name, this unit is masked for the runtime,
- similar to the effect of
+ <para>If the <option>systemd.mask=</option> or <option>rd.systemd.mask=</option>
+ option is specified and followed by a unit name, this unit is
+ masked for the runtime, similar to the effect of
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
<command>mask</command> command. This is useful to boot with
certain units removed from the initial boot transaction for
- debugging system startup. May be specified more than once.</para>
+ debugging system startup. May be specified more than once.
+ <option>rd.systemd.mask=</option> is honored only by initial
+ RAM disk (initrd) while <option>systemd.mask=</option> is
+ honored only in the main system.</para>
- <para>If the <option>systemd.wants=</option> option is specified
+ <para>If the <option>systemd.wants=</option> or
+ <option>rd.systemd.wants=</option> option is specified
and followed by a unit name, a start job for this unit is added to
the initial transaction. This is useful to start one or more
- additional units at boot. May be specified more than once.</para>
+ additional units at boot. May be specified more than once.
+ <option>rd.systemd.wants=</option> is honored only by initial
+ RAM disk (initrd) while <option>systemd.wants=</option> is
+ honored only in the main system.</para>
- <para>If the <option>systemd.debug_shell</option> option is
+ <para>If the <option>systemd.debug_shell</option> or
+ <option>rd.systemd.debug_shell</option> option is
specified, the debug shell service
<literal>debug-shell.service</literal> is pulled into the boot
transaction. It will spawn a debug shell on tty9 during early
system startup. Note that the shell may also be turned on
persistently by enabling it with
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
- <command>enable</command> command.</para>
+ <command>enable</command> command.
+ <option>rd.systemd.debug_shell=</option> is honored only by initial
+ RAM disk (initrd) while <option>systemd.debug_shell</option> is
+ honored only in the main system.</para>
<para><filename>systemd-debug-generator</filename> implements
<citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c
index dd6ab94fa2..800d31cebe 100644
--- a/src/debug-generator/debug-generator.c
+++ b/src/debug-generator/debug-generator.c
@@ -154,7 +154,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
+ r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_RD_STRICT | PROC_CMDLINE_STRIP_RD_PREFIX);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");

@ -0,0 +1,213 @@
From 107d75ca9394481bd045385fc45f2ee65b30ad16 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 19 Oct 2018 11:26:59 +0200
Subject: [PATCH] chown-recursive: let's rework the recursive logic to use
O_PATH
That way we can pin a specific inode and analyze it and manipulate it
without it being swapped out beneath our hands.
Fixes a vulnerability originally found by Jann Horn from Google.
CVE-2018-15687
LP: #1796692
https://bugzilla.redhat.com/show_bug.cgi?id=1639076
(cherry-picked from commit 5de6cce58b3e8b79239b6e83653459d91af6e57c)
Resolves: #1643368
---
src/core/chown-recursive.c | 146 ++++++++++++++++++-------------------
1 file changed, 70 insertions(+), 76 deletions(-)
diff --git a/src/core/chown-recursive.c b/src/core/chown-recursive.c
index c4794501c2..27c64489b5 100644
--- a/src/core/chown-recursive.c
+++ b/src/core/chown-recursive.c
@@ -1,17 +1,19 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
-#include <sys/types.h>
-#include <sys/stat.h>
#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
-#include "user-util.h"
-#include "macro.h"
-#include "fd-util.h"
-#include "dirent-util.h"
#include "chown-recursive.h"
+#include "dirent-util.h"
+#include "fd-util.h"
+#include "macro.h"
+#include "stdio-util.h"
+#include "strv.h"
+#include "user-util.h"
-static int chown_one(int fd, const char *name, const struct stat *st, uid_t uid, gid_t gid) {
- int r;
+static int chown_one(int fd, const struct stat *st, uid_t uid, gid_t gid) {
+ char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
assert(fd >= 0);
assert(st);
@@ -20,90 +22,82 @@ static int chown_one(int fd, const char *name, const struct stat *st, uid_t uid,
(!gid_is_valid(gid) || st->st_gid == gid))
return 0;
- if (name)
- r = fchownat(fd, name, uid, gid, AT_SYMLINK_NOFOLLOW);
- else
- r = fchown(fd, uid, gid);
- if (r < 0)
- return -errno;
+ /* We change ownership through the /proc/self/fd/%i path, so that we have a stable reference that works with
+ * O_PATH. (Note: fchown() and fchmod() do not work with O_PATH, the kernel refuses that. */
+ xsprintf(procfs_path, "/proc/self/fd/%i", fd);
- /* The linux kernel alters the mode in some cases of chown(). Let's undo this. */
- if (name) {
- if (!S_ISLNK(st->st_mode))
- r = fchmodat(fd, name, st->st_mode, 0);
- else /* There's currently no AT_SYMLINK_NOFOLLOW for fchmodat() */
- r = 0;
- } else
- r = fchmod(fd, st->st_mode);
- if (r < 0)
+ if (chown(procfs_path, uid, gid) < 0)
return -errno;
+ /* The linux kernel alters the mode in some cases of chown(). Let's undo this. We do this only for non-symlinks
+ * however. That's because for symlinks the access mode is ignored anyway and because on some kernels/file
+ * systems trying to change the access mode will succeed but has no effect while on others it actively
+ * fails. */
+ if (!S_ISLNK(st->st_mode))
+ if (chmod(procfs_path, st->st_mode & 07777) < 0)
+ return -errno;
+
return 1;
}
static int chown_recursive_internal(int fd, const struct stat *st, uid_t uid, gid_t gid) {
+ _cleanup_closedir_ DIR *d = NULL;
bool changed = false;
+ struct dirent *de;
int r;
assert(fd >= 0);
assert(st);
- if (S_ISDIR(st->st_mode)) {
- _cleanup_closedir_ DIR *d = NULL;
- struct dirent *de;
-
- d = fdopendir(fd);
- if (!d) {
- r = -errno;
- goto finish;
- }
- fd = -1;
-
- FOREACH_DIRENT_ALL(de, d, r = -errno; goto finish) {
- struct stat fst;
-
- if (dot_or_dot_dot(de->d_name))
- continue;
-
- if (fstatat(dirfd(d), de->d_name, &fst, AT_SYMLINK_NOFOLLOW) < 0) {
- r = -errno;
- goto finish;
- }
-
- if (S_ISDIR(fst.st_mode)) {
- int subdir_fd;
-
- subdir_fd = openat(dirfd(d), de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
- if (subdir_fd < 0) {
- r = -errno;
- goto finish;
- }
-
- r = chown_recursive_internal(subdir_fd, &fst, uid, gid);
- if (r < 0)
- goto finish;
- if (r > 0)
- changed = true;
- } else {
- r = chown_one(dirfd(d), de->d_name, &fst, uid, gid);
- if (r < 0)
- goto finish;
- if (r > 0)
- changed = true;
- }
+ d = fdopendir(fd);
+ if (!d) {
+ safe_close(fd);
+ return -errno;
+ }
+
+ FOREACH_DIRENT_ALL(de, d, return -errno) {
+ _cleanup_close_ int path_fd = -1;
+ struct stat fst;
+
+ if (dot_or_dot_dot(de->d_name))
+ continue;
+
+ /* Let's pin the child inode we want to fix now with an O_PATH fd, so that it cannot be swapped out
+ * while we manipulate it. */
+ path_fd = openat(dirfd(d), de->d_name, O_PATH|O_CLOEXEC|O_NOFOLLOW);
+ if (path_fd < 0)
+ return -errno;
+
+ if (fstat(path_fd, &fst) < 0)
+ return -errno;
+
+ if (S_ISDIR(fst.st_mode)) {
+ int subdir_fd;
+
+ /* Convert it to a "real" (i.e. non-O_PATH) fd now */
+ subdir_fd = fd_reopen(path_fd, O_RDONLY|O_CLOEXEC|O_NOATIME);
+ if (subdir_fd < 0)
+ return subdir_fd;
+
+ r = chown_recursive_internal(subdir_fd, &fst, uid, gid); /* takes possession of subdir_fd even on failure */
+ if (r < 0)
+ return r;
+ if (r > 0)
+ changed = true;
+ } else {
+ r = chown_one(path_fd, &fst, uid, gid);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ changed = true;
}
+ }
- r = chown_one(dirfd(d), NULL, st, uid, gid);
- } else
- r = chown_one(fd, NULL, st, uid, gid);
+ r = chown_one(dirfd(d), st, uid, gid);
if (r < 0)
- goto finish;
+ return r;
- r = r > 0 || changed;
-
-finish:
- safe_close(fd);
- return r;
+ return r > 0 || changed;
}
int path_chown_recursive(const char *path, uid_t uid, gid_t gid) {
@@ -111,7 +105,7 @@ int path_chown_recursive(const char *path, uid_t uid, gid_t gid) {
struct stat st;
int r;
- fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
+ fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
if (fd < 0)
return -errno;

@ -0,0 +1,58 @@
From bbe9ac11d8d4a8511214605509a593fb9f04ffaa Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 19 Oct 2018 11:28:40 +0200
Subject: [PATCH] chown-recursive: also drop ACLs when recursively chown()ing
Let's better be safe than sorry and also drop ACLs.
(cherry-picked from commit f89bc84f3242449cbc308892c87573b131f121df)
Related: #1643368
---
src/core/chown-recursive.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/src/core/chown-recursive.c b/src/core/chown-recursive.c
index 27c64489b5..447b771267 100644
--- a/src/core/chown-recursive.c
+++ b/src/core/chown-recursive.c
@@ -3,6 +3,7 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/xattr.h>
#include "chown-recursive.h"
#include "dirent-util.h"
@@ -14,6 +15,7 @@
static int chown_one(int fd, const struct stat *st, uid_t uid, gid_t gid) {
char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
+ const char *n;
assert(fd >= 0);
assert(st);
@@ -26,13 +28,19 @@ static int chown_one(int fd, const struct stat *st, uid_t uid, gid_t gid) {
* O_PATH. (Note: fchown() and fchmod() do not work with O_PATH, the kernel refuses that. */
xsprintf(procfs_path, "/proc/self/fd/%i", fd);
+ /* Drop any ACL if there is one */
+ FOREACH_STRING(n, "system.posix_acl_access", "system.posix_acl_default")
+ if (removexattr(procfs_path, n) < 0)
+ if (!IN_SET(errno, ENODATA, EOPNOTSUPP, ENOSYS, ENOTTY))
+ return -errno;
+
if (chown(procfs_path, uid, gid) < 0)
return -errno;
- /* The linux kernel alters the mode in some cases of chown(). Let's undo this. We do this only for non-symlinks
- * however. That's because for symlinks the access mode is ignored anyway and because on some kernels/file
- * systems trying to change the access mode will succeed but has no effect while on others it actively
- * fails. */
+ /* The linux kernel alters the mode in some cases of chown(), as well when we change ACLs. Let's undo this. We
+ * do this only for non-symlinks however. That's because for symlinks the access mode is ignored anyway and
+ * because on some kernels/file systems trying to change the access mode will succeed but has no effect while
+ * on others it actively fails. */
if (!S_ISLNK(st->st_mode))
if (chmod(procfs_path, st->st_mode & 07777) < 0)
return -errno;

@ -0,0 +1,34 @@
From c9630164b869e109bf2960968fc583449ccf0875 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 19 Oct 2018 11:42:11 +0200
Subject: [PATCH] chown-recursive: TAKE_FD() is your friend
(cherry-picked from commit cd6b7d50c337b3676a3d5fc2188ff298dcbdb939)
Related: #1643368
---
src/core/chown-recursive.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/src/core/chown-recursive.c b/src/core/chown-recursive.c
index 447b771267..7767301f7d 100644
--- a/src/core/chown-recursive.c
+++ b/src/core/chown-recursive.c
@@ -111,7 +111,6 @@ static int chown_recursive_internal(int fd, const struct stat *st, uid_t uid, gi
int path_chown_recursive(const char *path, uid_t uid, gid_t gid) {
_cleanup_close_ int fd = -1;
struct stat st;
- int r;
fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
if (fd < 0)
@@ -130,8 +129,5 @@ int path_chown_recursive(const char *path, uid_t uid, gid_t gid) {
(!gid_is_valid(gid) || st.st_gid == gid))
return 0;
- r = chown_recursive_internal(fd, &st, uid, gid);
- fd = -1; /* we donated the fd to the call, regardless if it succeeded or failed */
-
- return r;
+ return chown_recursive_internal(TAKE_FD(fd), &st, uid, gid); /* we donate the fd to the call, regardless if it succeeded or failed */
}

@ -0,0 +1,200 @@
From b53f89d56a5b7528735ddf335f8b47ab3e1a947a Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 19 Oct 2018 11:31:37 +0200
Subject: [PATCH] test: add test case for recursive chown()ing
[msekleta: I removed call to log_test_skipped() and replaced it with older construct log_info() + return EXIT_TEST_SKIP]
(cherry-picked from commit cb9e44db36caefcbb8ee7a12e14217305ed69ff2)
Related: #1643368
---
src/test/meson.build | 5 ++
src/test/test-chown-rec.c | 162 ++++++++++++++++++++++++++++++++++++++
2 files changed, 167 insertions(+)
create mode 100644 src/test/test-chown-rec.c
diff --git a/src/test/meson.build b/src/test/meson.build
index 7da7e3a22c..b982251b1f 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -60,6 +60,11 @@ tests += [
libmount,
libblkid]],
+ [['src/test/test-chown-rec.c'],
+ [libcore,
+ libshared],
+ []],
+
[['src/test/test-job-type.c'],
[libcore,
libshared],
diff --git a/src/test/test-chown-rec.c b/src/test/test-chown-rec.c
new file mode 100644
index 0000000000..f16d4d4ba2
--- /dev/null
+++ b/src/test/test-chown-rec.c
@@ -0,0 +1,162 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <sys/xattr.h>
+
+#include "alloc-util.h"
+#include "chown-recursive.h"
+#include "fileio.h"
+#include "log.h"
+#include "rm-rf.h"
+#include "string-util.h"
+#include "tests.h"
+
+static const uint8_t acl[] = {
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x07, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x07, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x10, 0x00, 0x07, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x05, 0x00,
+ 0xff, 0xff, 0xff, 0xff,
+};
+
+static const uint8_t default_acl[] = {
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x04, 0x00, 0x07, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x07, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x05, 0x00,
+ 0xff, 0xff, 0xff, 0xff,
+};
+
+static bool has_xattr(const char *p) {
+ char buffer[sizeof(acl) * 4];
+
+ if (lgetxattr(p, "system.posix_acl_access", buffer, sizeof(buffer)) < 0) {
+ if (IN_SET(errno, EOPNOTSUPP, ENOTTY, ENODATA, ENOSYS))
+ return false;
+ }
+
+ return true;
+}
+
+static void test_chown_recursive(void) {
+ _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
+ struct stat st;
+ const char *p;
+
+ umask(022);
+ assert_se(mkdtemp_malloc(NULL, &t) >= 0);
+
+ p = strjoina(t, "/dir");
+ assert_se(mkdir(p, 0777) >= 0);
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISDIR(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 0);
+ assert_se(st.st_gid == 0);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/symlink");
+ assert_se(symlink("../../", p) >= 0);
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISLNK(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0777);
+ assert_se(st.st_uid == 0);
+ assert_se(st.st_gid == 0);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/reg");
+ assert_se(mknod(p, S_IFREG|0777, 0) >= 0);
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISREG(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 0);
+ assert_se(st.st_gid == 0);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/sock");
+ assert_se(mknod(p, S_IFSOCK|0777, 0) >= 0);
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISSOCK(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 0);
+ assert_se(st.st_gid == 0);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/fifo");
+ assert_se(mknod(p, S_IFIFO|0777, 0) >= 0);
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISFIFO(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 0);
+ assert_se(st.st_gid == 0);
+ assert_se(!has_xattr(p));
+
+ /* We now apply an xattr to the dir, and check it again */
+ p = strjoina(t, "/dir");
+ assert_se(setxattr(p, "system.posix_acl_access", acl, sizeof(acl), 0) >= 0);
+ assert_se(setxattr(p, "system.posix_acl_default", default_acl, sizeof(default_acl), 0) >= 0);
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISDIR(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0775); /* acl change changed the mode too */
+ assert_se(st.st_uid == 0);
+ assert_se(st.st_gid == 0);
+ assert_se(has_xattr(p));
+
+ assert_se(path_chown_recursive(t, 1, 2) >= 0);
+
+ p = strjoina(t, "/dir");
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISDIR(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0775);
+ assert_se(st.st_uid == 1);
+ assert_se(st.st_gid == 2);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/symlink");
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISLNK(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0777);
+ assert_se(st.st_uid == 1);
+ assert_se(st.st_gid == 2);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/reg");
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISREG(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 1);
+ assert_se(st.st_gid == 2);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/sock");
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISSOCK(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 1);
+ assert_se(st.st_gid == 2);
+ assert_se(!has_xattr(p));
+
+ p = strjoina(t, "/dir/fifo");
+ assert_se(lstat(p, &st) >= 0);
+ assert_se(S_ISFIFO(st.st_mode));
+ assert_se((st.st_mode & 07777) == 0755);
+ assert_se(st.st_uid == 1);
+ assert_se(st.st_gid == 2);
+ assert_se(!has_xattr(p));
+}
+
+int main(int argc, char *argv[]) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
+ if (geteuid() != 0) {
+ log_info("not running as root");
+ return EXIT_TEST_SKIP;
+ }
+
+ test_chown_recursive();
+
+ return EXIT_SUCCESS;
+}

@ -0,0 +1,32 @@
From 730ce6562f8a5f4a61d1ed3ffb4d65fa27b728fc Mon Sep 17 00:00:00 2001
From: Thomas Hindoe Paaboel Andersen <phomes@gmail.com>
Date: Fri, 17 Aug 2018 21:31:05 +0200
Subject: [PATCH] Revert "sysctl.d: request ECN on both in and outgoing
connections"
Turning on ECN still causes slow or broken network on linux. Our tcp
is not yet ready for wide spread use of ECN.
This reverts commit 919472741dba6ad0a3f6c2b76d390a02d0e2fdc3.
(cherry picked from commit 1e190dfd5bb95036f937ef1dc46f43eb0a146612)
Resolves: #1619790
---
sysctl.d/50-default.conf | 3 ---
1 file changed, 3 deletions(-)
diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf
index b67ae87ca6..e263cf0628 100644
--- a/sysctl.d/50-default.conf
+++ b/sysctl.d/50-default.conf
@@ -33,9 +33,6 @@ net.ipv4.conf.all.promote_secondaries = 1
# Fair Queue CoDel packet scheduler to fight bufferbloat
net.core.default_qdisc = fq_codel
-# Request Explicit Congestion Notification (ECN) on both in and outgoing connections
-net.ipv4.tcp_ecn = 1
-
# Enable hard and soft link protection
fs.protected_hardlinks = 1
fs.protected_symlinks = 1

@ -0,0 +1,84 @@
From 886e5b028953404f2d924b561c0689d3e50dbbf4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 13 Sep 2018 09:24:36 +0200
Subject: [PATCH] detect-virt: do not try to read all of /proc/cpuinfo
Quoting https://github.com/systemd/systemd/issues/10074:
> detect_vm_uml() reads /proc/cpuinfo with read_full_file()
> read_full_file() has a file max limit size of READ_FULL_BYTES_MAX=(4U*1024U*1024U)
> Unfortunately, the size of my /proc/cpuinfo is bigger, approximately:
> echo $(( 4* $(cat /proc/cpuinfo | wc -c)))
> 9918072
> This causes read_full_file() to fail and the Condition test fallout.
Let's just read line by line until we find an intersting line. This also
helps if not running under UML, because we avoid reading as much data.
(cherry picked from commit 6058516a14ada1748313af6783f5b4e7e3006654)
Resolves: #1631532
---
src/basic/virt.c | 38 ++++++++++++++++++++++++++++----------
1 file changed, 28 insertions(+), 10 deletions(-)
diff --git a/src/basic/virt.c b/src/basic/virt.c
index d347732bb3..e05b3e6d99 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -11,6 +11,7 @@
#include "alloc-util.h"
#include "dirent-util.h"
+#include "def.h"
#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
@@ -259,21 +260,38 @@ static int detect_vm_hypervisor(void) {
}
static int detect_vm_uml(void) {
- _cleanup_free_ char *cpuinfo_contents = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
int r;
/* Detect User-Mode Linux by reading /proc/cpuinfo */
- r = read_full_file("/proc/cpuinfo", &cpuinfo_contents, NULL);
- if (r == -ENOENT) {
- log_debug("/proc/cpuinfo not found, assuming no UML virtualization.");
- return VIRTUALIZATION_NONE;
+ f = fopen("/proc/cpuinfo", "re");
+ if (!f) {
+ if (errno == ENOENT) {
+ log_debug("/proc/cpuinfo not found, assuming no UML virtualization.");
+ return VIRTUALIZATION_NONE;
+ }
+ return -errno;
}
- if (r < 0)
- return r;
- if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n")) {
- log_debug("UML virtualization found in /proc/cpuinfo");
- return VIRTUALIZATION_UML;
+ for (;;) {
+ _cleanup_free_ char *line = NULL;
+ const char *t;
+
+ r = read_line(f, LONG_LINE_MAX, &line);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ t = startswith(line, "vendor_id\t: ");
+ if (t) {
+ if (startswith(t, "User Mode Linux")) {
+ log_debug("UML virtualization found in /proc/cpuinfo");
+ return VIRTUALIZATION_UML;
+ }
+
+ break;
+ }
}
log_debug("UML virtualization not found in /proc/cpuinfo.");

@ -0,0 +1,166 @@
From eb141ba81158feb74118da4e7a3f2266b11ffe10 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 9 Jul 2018 08:06:28 +0200
Subject: [PATCH] sd-bus: unify three code-paths which free struct
bus_container
We didn't free one of the fields in two of the places.
$ valgrind --show-leak-kinds=all --leak-check=full \
build/fuzz-bus-message \
test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20
...
==14457== HEAP SUMMARY:
==14457== in use at exit: 3 bytes in 1 blocks
==14457== total heap usage: 509 allocs, 508 frees, 51,016 bytes allocated
==14457==
==14457== 3 bytes in 1 blocks are definitely lost in loss record 1 of 1
==14457== at 0x4C2EBAB: malloc (vg_replace_malloc.c:299)
==14457== by 0x53AFE79: strndup (in /usr/lib64/libc-2.27.so)
==14457== by 0x4F52EB8: free_and_strndup (string-util.c:1039)
==14457== by 0x4F8E1AB: sd_bus_message_peek_type (bus-message.c:4193)
==14457== by 0x4F76CB5: bus_message_dump (bus-dump.c:144)
==14457== by 0x108F12: LLVMFuzzerTestOneInput (fuzz-bus-message.c:24)
==14457== by 0x1090F7: main (fuzz-main.c:34)
==14457==
==14457== LEAK SUMMARY:
==14457== definitely lost: 3 bytes in 1 blocks
(cherry picked from commit 6d1e0f4fcba8d6f425da3dc91805db95399b3c8b)
Resolves: #1635435
---
src/libsystemd/sd-bus/bus-message.c | 64 +++++++++---------
...k-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20 | Bin 0 -> 534 bytes
2 files changed, 32 insertions(+), 32 deletions(-)
create mode 100644 test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 7c8bad2bdd..d55cb14843 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -77,19 +77,38 @@ static void message_reset_parts(sd_bus_message *m) {
m->cached_rindex_part_begin = 0;
}
-static void message_reset_containers(sd_bus_message *m) {
- unsigned i;
+static struct bus_container *message_get_container(sd_bus_message *m) {
+ assert(m);
+
+ if (m->n_containers == 0)
+ return &m->root_container;
+
+ assert(m->containers);
+ return m->containers + m->n_containers - 1;
+}
+
+static void message_free_last_container(sd_bus_message *m) {
+ struct bus_container *c;
+
+ c = message_get_container(m);
+
+ free(c->signature);
+ free(c->peeked_signature);
+ free(c->offsets);
+
+ /* Move to previous container, but not if we are on root container */
+ if (m->n_containers > 0)
+ m->n_containers--;
+}
+static void message_reset_containers(sd_bus_message *m) {
assert(m);
- for (i = 0; i < m->n_containers; i++) {
- free(m->containers[i].signature);
- free(m->containers[i].offsets);
- }
+ while (m->n_containers > 0)
+ message_free_last_container(m);
m->containers = mfree(m->containers);
-
- m->n_containers = m->containers_allocated = 0;
+ m->containers_allocated = 0;
m->root_container.index = 0;
}
@@ -112,10 +131,8 @@ static sd_bus_message* message_free(sd_bus_message *m) {
free(m->iovec);
message_reset_containers(m);
- free(m->root_container.signature);
- free(m->root_container.offsets);
-
- free(m->root_container.peeked_signature);
+ assert(m->n_containers == 0);
+ message_free_last_container(m);
bus_creds_done(&m->creds);
return mfree(m);
@@ -1113,16 +1130,6 @@ _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *
return 0;
}
-static struct bus_container *message_get_container(sd_bus_message *m) {
- assert(m);
-
- if (m->n_containers == 0)
- return &m->root_container;
-
- assert(m->containers);
- return m->containers + m->n_containers - 1;
-}
-
struct bus_body_part *message_append_part(sd_bus_message *m) {
struct bus_body_part *part;
@@ -4108,13 +4115,9 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
return -EBUSY;
}
- free(c->signature);
- free(c->peeked_signature);
- free(c->offsets);
- m->n_containers--;
+ message_free_last_container(m);
c = message_get_container(m);
-
saved = c->index;
c->index = c->saved_index;
r = container_next_item(m, c, &m->rindex);
@@ -4132,16 +4135,13 @@ static void message_quit_container(sd_bus_message *m) {
assert(m->sealed);
assert(m->n_containers > 0);
- c = message_get_container(m);
-
/* Undo seeks */
+ c = message_get_container(m);
assert(m->rindex >= c->before);
m->rindex = c->before;
/* Free container */
- free(c->signature);
- free(c->offsets);
- m->n_containers--;
+ message_free_last_container(m);
/* Correct index of new top-level container */
c = message_get_container(m);
diff --git a/test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20 b/test/fuzz/fuzz-bus-message/leak-c09c0e2256d43bc5e2d02748c8d8760e7bc25d20
new file mode 100644
index 0000000000000000000000000000000000000000..c371824ffb604708619fd0713e8fca609bac18f7
GIT binary patch
literal 534
zcmZ{h!A`?442GSJP20o?A&zJgm*%p<cmZx)c?GB2N~MZabq0zMhzqX`{7ze`LYk$&
z_LnqH{-ic!J`GWMLG(>T#&`l!4rxq{&>8YmwQrOs;B(}I_m11m8`nFp<MR{a3sX`q
z!cs!Q@A35`W+B>`#ek1>oQYVSs`!XH?7Y=}3y9Ye+UliL9^x9s66$8wH+TPdOG`n|
z5Uhx<nM2)KiEdF(J5Ct}Xa*iksL!VNssA<Hq<KDseGAsT^*)9kK$?O39;dyGT&#2v
zLhpD3X)k6@tX`CzbBVV-7e$fy9()CjJ&n(=^)uJCKFB5Xi}-<1ru7po5XlEJ?uByQ
MaEPzRhwknF02{PjtN;K2
literal 0
HcmV?d00001

@ -0,0 +1,27 @@
From 220a60a61a91153fd8e49e58884b9b0b904888f6 Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Wed, 31 Oct 2018 12:50:19 +0100
Subject: [PATCH] sd-bus: properly initialize containers
Fixes a SIGSEGV introduced by commit 38a5315a3a6fab745d8c86ff9e486faaf50b28d1.
The same problem doesn't exist upstream, as the container structure
there is initialized using a compound literal, which is zeroed out by
default.
Related: #1635435
---
src/libsystemd/sd-bus/bus-message.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index d55cb14843..780c8c6185 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -2004,6 +2004,7 @@ _public_ int sd_bus_message_open_container(
w = m->containers + m->n_containers++;
w->enclosing = type;
w->signature = TAKE_PTR(signature);
+ w->peeked_signature = NULL;
w->index = 0;
w->array_size = array_size;
w->before = before;

@ -0,0 +1,240 @@
From 0977e6b34fb5f28fc94f1df32261742881fa9bbe Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 30 Aug 2018 08:45:11 +0000
Subject: [PATCH] cryptsetup-generator: introduce basic keydev support
Dracut has a support for unlocking encrypted drives with keyfile stored
on the external drive. This support is included in the generated initrd
only if systemd module is not included.
When systemd is used in initrd then attachment of encrypted drives is
handled by systemd-cryptsetup tools. Our generator has support for
keyfile, however, it didn't support keyfile on the external block
device (keydev).
This commit introduces basic keydev support. Keydev can be specified per
luks.uuid on the kernel command line. Keydev is automatically mounted
during boot and we look for keyfile in the keydev
mountpoint (i.e. keyfile path is prefixed with the keydev mount point
path). After crypt device is attached we automatically unmount
where keyfile resides.
Example:
rd.luks.key=70bc876b-f627-4038-9049-3080d79d2165=/key:LABEL=KEYDEV
(cherry-picked from commit 70f5f48eb891b12e969577b464de61e15a2593da)
Resolves: #1656869
---
man/systemd-cryptsetup-generator.xml | 14 ++++
src/cryptsetup/cryptsetup-generator.c | 105 +++++++++++++++++++++++++-
2 files changed, 115 insertions(+), 4 deletions(-)
diff --git a/man/systemd-cryptsetup-generator.xml b/man/systemd-cryptsetup-generator.xml
index c37ee76b87..e30d69bfe7 100644
--- a/man/systemd-cryptsetup-generator.xml
+++ b/man/systemd-cryptsetup-generator.xml
@@ -144,6 +144,20 @@
to the one specified by <varname>rd.luks.key=</varname> or
<varname>luks.key=</varname> of the corresponding UUID, or the
password file that was specified without a UUID.</para>
+
+ <para>It is also possible to specify an external device which
+ should be mounted before we attempt to unlock the LUKS device.
+ systemd-cryptsetup will use password file stored on that
+ device. Device containing password file is specified by
+ appending colon and a device identifier to the password file
+ path. For example,
+ <varname>rd.luks.uuid=</varname>b40f1abf-2a53-400a-889a-2eccc27eaa40
+ <varname>rd.luks.key=</varname>b40f1abf-2a53-400a-889a-2eccc27eaa40=/keyfile:LABEL=keydev.
+ Hence, in this case, we will attempt to mount file system
+ residing on the block device with label <literal>keydev</literal>.
+ This syntax is for now only supported on a per-device basis,
+ i.e. you have to specify LUKS device UUID.</para>
+
<para><varname>rd.luks.key=</varname>
is honored only by initial RAM disk
(initrd) while
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index f5a81829b9..8c7a76e789 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -24,6 +24,7 @@
typedef struct crypto_device {
char *uuid;
char *keyfile;
+ char *keydev;
char *name;
char *options;
bool create;
@@ -37,14 +38,71 @@ static Hashmap *arg_disks = NULL;
static char *arg_default_options = NULL;
static char *arg_default_keyfile = NULL;
+static int generate_keydev_mount(const char *name, const char *keydev, char **unit, char **mount) {
+ _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ int r;
+
+ assert(name);
+ assert(keydev);
+ assert(unit);
+ assert(mount);
+
+ r = mkdir_parents("/run/systemd/cryptsetup", 0755);
+ if (r < 0)
+ return r;
+
+ r = mkdir("/run/systemd/cryptsetup", 0700);
+ if (r < 0)
+ return r;
+
+ where = strjoin("/run/systemd/cryptsetup/keydev-", name);
+ if (!where)
+ return -ENOMEM;
+
+ r = mkdir(where, 0700);
+ if (r < 0)
+ return r;
+
+ r = unit_name_from_path(where, ".mount", &u);
+ if (r < 0)
+ return r;
+
+ r = generator_open_unit_file(arg_dest, NULL, u, &f);
+ if (r < 0)
+ return r;
+
+ what = fstab_node_to_udev_node(keydev);
+ if (!what)
+ return -ENOMEM;
+
+ fprintf(f,
+ "[Unit]\n"
+ "DefaultDependencies=no\n\n"
+ "[Mount]\n"
+ "What=%s\n"
+ "Where=%s\n"
+ "Options=ro\n", what, where);
+
+ r = fflush_and_check(f);
+ if (r < 0)
+ return r;
+
+ *unit = TAKE_PTR(u);
+ *mount = TAKE_PTR(where);
+
+ return 0;
+}
+
static int create_disk(
const char *name,
const char *device,
+ const char *keydev,
const char *password,
const char *options) {
_cleanup_free_ char *n = NULL, *d = NULL, *u = NULL, *e = NULL,
- *filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL;
+ *filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL, *keydev_mount = NULL;
_cleanup_fclose_ FILE *f = NULL;
const char *dmname;
bool noauto, nofail, tmp, swap, netdev;
@@ -94,6 +152,9 @@ static int create_disk(
return log_oom();
}
+ if (keydev && !password)
+ return log_error_errno(-EINVAL, "Keydev is specified, but path to the password file is missing: %m");
+
r = generator_open_unit_file(arg_dest, NULL, n, &f);
if (r < 0)
return r;
@@ -109,6 +170,20 @@ static int create_disk(
"After=%s\n",
netdev ? "remote-fs-pre.target" : "cryptsetup-pre.target");
+ if (keydev) {
+ _cleanup_free_ char *unit = NULL, *p = NULL;
+
+ r = generate_keydev_mount(name, keydev, &unit, &keydev_mount);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate keydev mount unit: %m");
+
+ p = prefix_root(keydev_mount, password_escaped);
+ if (!p)
+ return log_oom();
+
+ free_and_replace(password_escaped, p);
+ }
+
if (!nofail)
fprintf(f,
"Before=%s\n",
@@ -186,6 +261,11 @@ static int create_disk(
"ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
name_escaped);
+ if (keydev)
+ fprintf(f,
+ "ExecStartPost=" UMOUNT_PATH " %s\n\n",
+ keydev_mount);
+
r = fflush_and_check(f);
if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", n);
@@ -221,6 +301,7 @@ static int create_disk(
static void crypt_device_free(crypto_device *d) {
free(d->uuid);
free(d->keyfile);
+ free(d->keydev);
free(d->name);
free(d->options);
free(d);
@@ -309,11 +390,27 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value);
if (r == 2) {
+ char *c;
+ _cleanup_free_ char *keyfile = NULL, *keydev = NULL;
+
d = get_crypto_device(uuid);
if (!d)
return log_oom();
- free_and_replace(d->keyfile, uuid_value);
+ c = strrchr(uuid_value, ':');
+ if (!c)
+ /* No keydev specified */
+ return free_and_replace(d->keyfile, uuid_value);
+
+ *c = '\0';
+ keyfile = strdup(uuid_value);
+ keydev = strdup(++c);
+
+ if (!keyfile || !keydev)
+ return log_oom();
+
+ free_and_replace(d->keyfile, keyfile);
+ free_and_replace(d->keydev, keydev);
} else if (free_and_strdup(&arg_default_keyfile, value) < 0)
return log_oom();
@@ -394,7 +491,7 @@ static int add_crypttab_devices(void) {
continue;
}
- r = create_disk(name, device, keyfile, (d && d->options) ? d->options : options);
+ r = create_disk(name, device, NULL, keyfile, (d && d->options) ? d->options : options);
if (r < 0)
return r;
@@ -434,7 +531,7 @@ static int add_proc_cmdline_devices(void) {
else
options = "timeout=0";
- r = create_disk(d->name, device, d->keyfile ?: arg_default_keyfile, options);
+ r = create_disk(d->name, device, d->keydev, d->keyfile ?: arg_default_keyfile, options);
if (r < 0)
return r;
}

@ -0,0 +1,33 @@
From 95bfd1d2f52698604e44c17dba2082f61b5f8eab Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 5 Oct 2018 22:37:37 +0200
Subject: [PATCH] cryptsetup: don't use %m if there's no error to show
We are not the ones receiving an error here, but the ones generating it,
hence we shouldn't show it with %m, that's just confusing, as it
suggests we received an error from some other call.
(cherry-picked from commit 2abe64666e544be6499f870618185f8819b4c152)
Related: #1656869
---
src/cryptsetup/cryptsetup-generator.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index 8c7a76e789..52391bd185 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -152,8 +152,10 @@ static int create_disk(
return log_oom();
}
- if (keydev && !password)
- return log_error_errno(-EINVAL, "Keydev is specified, but path to the password file is missing: %m");
+ if (keydev && !password) {
+ log_error("Key device is specified, but path to the password file is missing.");
+ return -EINVAL;
+ }
r = generator_open_unit_file(arg_dest, NULL, n, &f);
if (r < 0)

@ -0,0 +1,38 @@
From 81df5f597257bd2579246de6182c4949b27396eb Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Tue, 4 Sep 2018 19:51:14 +0200
Subject: [PATCH] cryptsetup-generator: don't return error if target directory
already exists
(cherry-picked from commit 579875bc4a59b917fa32519e3d96d56dc591ad1e)
Related: #1656869
---
src/cryptsetup/cryptsetup-generator.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index 52391bd185..03c513c26e 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -53,16 +53,16 @@ static int generate_keydev_mount(const char *name, const char *keydev, char **un
return r;
r = mkdir("/run/systemd/cryptsetup", 0700);
- if (r < 0)
- return r;
+ if (r < 0 && errno != EEXIST)
+ return -errno;
where = strjoin("/run/systemd/cryptsetup/keydev-", name);
if (!where)
return -ENOMEM;
r = mkdir(where, 0700);
- if (r < 0)
- return r;
+ if (r < 0 && errno != EEXIST)
+ return -errno;
r = unit_name_from_path(where, ".mount", &u);
if (r < 0)

@ -0,0 +1,129 @@
From 2a4d58bb2ab9ba5487785cc167932440a4f0c13d Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Tue, 4 Sep 2018 20:03:34 +0200
Subject: [PATCH] cryptsetup-generator: allow whitespace characters in keydev
specification
For example, <luks.uuid>=/keyfile:LABEL="KEYFILE FS" previously wouldn't
work, because we truncated label at the first whitespace character,
i.e. LABEL="KEYFILE".
(cherry-picked from commit 7949dfa73a44ae6524779689483d12243dfbcfdf)
Related: #1656869
---
src/cryptsetup/cryptsetup-generator.c | 64 ++++++++++++++++++---------
1 file changed, 43 insertions(+), 21 deletions(-)
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index 03c513c26e..52c1262728 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -5,11 +5,13 @@
#include "alloc-util.h"
#include "dropin.h"
+#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
#include "fstab-util.h"
#include "generator.h"
#include "hashmap.h"
+#include "id128-util.h"
#include "log.h"
#include "mkdir.h"
#include "parse-util.h"
@@ -39,7 +41,7 @@ static char *arg_default_options = NULL;
static char *arg_default_keyfile = NULL;
static int generate_keydev_mount(const char *name, const char *keydev, char **unit, char **mount) {
- _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL;
+ _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL, *name_escaped = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
@@ -56,7 +58,11 @@ static int generate_keydev_mount(const char *name, const char *keydev, char **un
if (r < 0 && errno != EEXIST)
return -errno;
- where = strjoin("/run/systemd/cryptsetup/keydev-", name);
+ name_escaped = cescape(name);
+ if (!name_escaped)
+ return -ENOMEM;
+
+ where = strjoin("/run/systemd/cryptsetup/keydev-", name_escaped);
if (!where)
return -ENOMEM;
@@ -386,36 +392,52 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
return log_oom();
} else if (streq(key, "luks.key")) {
+ size_t n;
+ _cleanup_free_ char *keyfile = NULL, *keydev = NULL;
+ char *c;
+ const char *keyspec;
if (proc_cmdline_value_missing(key, value))
return 0;
- r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value);
- if (r == 2) {
- char *c;
- _cleanup_free_ char *keyfile = NULL, *keydev = NULL;
+ n = strspn(value, LETTERS DIGITS "-");
+ if (value[n] != '=') {
+ if (free_and_strdup(&arg_default_keyfile, value) < 0)
+ return log_oom();
+ return 0;
+ }
- d = get_crypto_device(uuid);
- if (!d)
- return log_oom();
+ uuid = strndup(value, n);
+ if (!uuid)
+ return log_oom();
- c = strrchr(uuid_value, ':');
- if (!c)
- /* No keydev specified */
- return free_and_replace(d->keyfile, uuid_value);
+ if (!id128_is_valid(uuid)) {
+ log_warning("Failed to parse luks.key= kernel command line switch. UUID is invalid, ignoring.");
+ return 0;
+ }
+
+ d = get_crypto_device(uuid);
+ if (!d)
+ return log_oom();
- *c = '\0';
- keyfile = strdup(uuid_value);
- keydev = strdup(++c);
+ keyspec = value + n + 1;
+ c = strrchr(keyspec, ':');
+ if (c) {
+ *c = '\0';
+ keyfile = strdup(keyspec);
+ keydev = strdup(c + 1);
if (!keyfile || !keydev)
return log_oom();
+ } else {
+ /* No keydev specified */
+ keyfile = strdup(keyspec);
+ if (!keyfile)
+ return log_oom();
+ }
- free_and_replace(d->keyfile, keyfile);
- free_and_replace(d->keydev, keydev);
- } else if (free_and_strdup(&arg_default_keyfile, value) < 0)
- return log_oom();
-
+ free_and_replace(d->keyfile, keyfile);
+ free_and_replace(d->keydev, keydev);
} else if (streq(key, "luks.name")) {
if (proc_cmdline_value_missing(key, value))

@ -0,0 +1,25 @@
From c16785e970b83590fc9de4ea0f7e410470d88db5 Mon Sep 17 00:00:00 2001
From: Vojtech Trefny <vtrefny@redhat.com>
Date: Tue, 4 Dec 2018 16:47:36 +0100
Subject: [PATCH] rules: watch metadata changes on DASD devices
To make sure the change event is emitted and udev db is updated
after metadata changes.
(cherry picked from commit 38397c8ce044fdc0138c9919168a856c0e16f720)
Resolves: #1638676
---
rules/60-block.rules | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rules/60-block.rules b/rules/60-block.rules
index 343fc06f85..a1458e9188 100644
--- a/rules/60-block.rules
+++ b/rules/60-block.rules
@@ -8,4 +8,4 @@ ACTION=="add", SUBSYSTEM=="module", KERNEL=="block", ATTR{parameters/events_dfl_
ACTION=="change", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST=="block", ATTR{block/*/uevent}="change"
# watch metadata changes, caused by tools closing the device node which was opened for writing
-ACTION!="remove", SUBSYSTEM=="block", KERNEL=="loop*|nvme*|sd*|vd*|xvd*|pmem*|mmcblk*", OPTIONS+="watch"
+ACTION!="remove", SUBSYSTEM=="block", KERNEL=="loop*|nvme*|sd*|vd*|xvd*|pmem*|mmcblk*|dasd*", OPTIONS+="watch"

@ -0,0 +1,41 @@
From 75c9af80cf3529c76988451e63f98010c86f48f1 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Wed, 28 Nov 2018 11:44:20 +0100
Subject: [PATCH] sysctl.d: switch net.ipv4.conf.all.rp_filter from 1 to 2
This switches the RFC3704 Reverse Path filtering from Strict mode to Loose
mode. The Strict mode breaks some pretty common and reasonable use cases,
such as keeping connections via one default route alive after another one
appears (e.g. plugging an Ethernet cable when connected via Wi-Fi).
The strict filter also makes it impossible for NetworkManager to do
connectivity check on a newly arriving default route (it starts with a
higher metric and is bumped lower if there's connectivity).
Kernel's default is 0 (no filter), but a Loose filter is good enough. The
few use cases where a Strict mode could make sense can easily override
this.
The distributions that don't care about the client use cases and prefer a
strict filter could just ship a custom configuration in
/usr/lib/sysctl.d/ to override this.
Cherry-picked from: 230450d4e4f1f5fc9fa4295ed9185eea5b6ea16e
Resolves: #1653824
---
sysctl.d/50-default.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf
index e263cf0628..b0645f33e7 100644
--- a/sysctl.d/50-default.conf
+++ b/sysctl.d/50-default.conf
@@ -22,7 +22,7 @@ kernel.sysrq = 16
kernel.core_uses_pid = 1
# Source route verification
-net.ipv4.conf.all.rp_filter = 1
+net.ipv4.conf.all.rp_filter = 2
# Do not accept source routing
net.ipv4.conf.all.accept_source_route = 0

@ -0,0 +1,36 @@
From e8ead61e1c0a919a97df64b14dbd572ef7c830d2 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Sat, 15 Dec 2018 20:22:31 +0100
Subject: [PATCH] tests: explicitly enable user namespaces for
TEST-13-NSPAWN-SMOKE
Cherry-picked from: 67f5c0c776ce9449ad21e9854665573a05141fd4
---
test/TEST-13-NSPAWN-SMOKE/test.sh | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/test/TEST-13-NSPAWN-SMOKE/test.sh b/test/TEST-13-NSPAWN-SMOKE/test.sh
index 6a0cb42eaf..c0789b5d20 100755
--- a/test/TEST-13-NSPAWN-SMOKE/test.sh
+++ b/test/TEST-13-NSPAWN-SMOKE/test.sh
@@ -18,7 +18,7 @@ test_setup() {
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
- dracut_install busybox chmod rmdir unshare ip
+ dracut_install busybox chmod rmdir unshare ip sysctl
cp create-busybox-container $initdir/
@@ -63,6 +63,11 @@ if [[ -f /proc/1/ns/cgroup ]]; then
fi
is_user_ns_supported=no
+# On some systems (e.g. CentOS 7) the default limit for user namespaces
+# is set to 0, which causes the following unshare syscall to fail, even
+# with enabled user namespaces support. By setting this value explicitly
+# we can ensure the user namespaces support to be detected correctly.
+sysctl -w user.max_user_namespaces=10000
if unshare -U sh -c :; then
is_user_ns_supported=yes
fi

@ -0,0 +1,122 @@
From 2115fcc1e673079fe76e949ac0904267075c25a4 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 31 Oct 2018 13:04:20 +0100
Subject: [PATCH] nspawn: beef up netns checking a bit, for compat with old
kernels
Fixes: #10544
Cherry-picked from: 6619ad889da260cf83079cc74a85d571acd1df5a
---
src/basic/stat-util.c | 40 +++++++++++++++++++++++++++++++++++----
src/nspawn/nspawn.c | 8 +++++---
src/test/test-stat-util.c | 15 +++++++++++++++
3 files changed, 56 insertions(+), 7 deletions(-)
diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c
index 07154e25bb..26aee9bad6 100644
--- a/src/basic/stat-util.c
+++ b/src/basic/stat-util.c
@@ -204,15 +204,47 @@ int fd_is_network_fs(int fd) {
}
int fd_is_network_ns(int fd) {
+ struct statfs s;
int r;
- r = fd_is_fs_type(fd, NSFS_MAGIC);
- if (r <= 0)
- return r;
+ /* Checks whether the specified file descriptor refers to a network namespace. On old kernels there's no nice
+ * way to detect that, hence on those we'll return a recognizable error (EUCLEAN), so that callers can handle
+ * this somewhat nicely.
+ *
+ * This function returns > 0 if the fd definitely refers to a network namespace, 0 if it definitely does not
+ * refer to a network namespace, -EUCLEAN if we can't determine, and other negative error codes on error. */
+
+ if (fstatfs(fd, &s) < 0)
+ return -errno;
+
+ if (!is_fs_type(&s, NSFS_MAGIC)) {
+ /* On really old kernels, there was no "nsfs", and network namespace sockets belonged to procfs
+ * instead. Handle that in a somewhat smart way. */
+
+ if (is_fs_type(&s, PROC_SUPER_MAGIC)) {
+ struct statfs t;
+
+ /* OK, so it is procfs. Let's see if our own network namespace is procfs, too. If so, then the
+ * passed fd might refer to a network namespace, but we can't know for sure. In that case,
+ * return a recognizable error. */
+
+ if (statfs("/proc/self/ns/net", &t) < 0)
+ return -errno;
+
+ if (s.f_type == t.f_type)
+ return -EUCLEAN; /* It's possible, we simply don't know */
+ }
+
+ return 0; /* No! */
+ }
r = ioctl(fd, NS_GET_NSTYPE);
- if (r < 0)
+ if (r < 0) {
+ if (errno == ENOTTY) /* Old kernels didn't know this ioctl, let's also return a recognizable error in that case */
+ return -EUCLEAN;
+
return -errno;
+ }
return r == CLONE_NEWNET;
}
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 56877bd932..8aec893a69 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -3701,10 +3701,12 @@ static int run(int master,
return log_error_errno(errno, "Cannot open file %s: %m", arg_network_namespace_path);
r = fd_is_network_ns(netns_fd);
- if (r < 0 && r != -ENOTTY)
+ if (r == -EUCLEAN)
+ log_debug_errno(r, "Cannot determine if passed network namespace path '%s' really refers to a network namespace, assuming it does.", arg_network_namespace_path);
+ else if (r < 0)
return log_error_errno(r, "Failed to check %s fs type: %m", arg_network_namespace_path);
- if (r == 0) {
- log_error("Path %s doesn't refer to a network namespace", arg_network_namespace_path);
+ else if (r == 0) {
+ log_error("Path %s doesn't refer to a network namespace, refusing.", arg_network_namespace_path);
return -EINVAL;
}
}
diff --git a/src/test/test-stat-util.c b/src/test/test-stat-util.c
index 43f56a6c20..2b0564d8a0 100644
--- a/src/test/test-stat-util.c
+++ b/src/test/test-stat-util.c
@@ -67,11 +67,26 @@ static void test_path_is_temporary_fs(void) {
assert_se(path_is_temporary_fs("/i-dont-exist") == -ENOENT);
}
+static void test_fd_is_network_ns(void) {
+ _cleanup_close_ int fd = -1;
+ assert_se(fd_is_network_ns(STDIN_FILENO) == 0);
+ assert_se(fd_is_network_ns(STDERR_FILENO) == 0);
+ assert_se(fd_is_network_ns(STDOUT_FILENO) == 0);
+
+ assert_se((fd = open("/proc/self/ns/mnt", O_CLOEXEC|O_RDONLY)) >= 0);
+ assert_se(IN_SET(fd_is_network_ns(fd), 0, -EUCLEAN));
+ fd = safe_close(fd);
+
+ assert_se((fd = open("/proc/self/ns/net", O_CLOEXEC|O_RDONLY)) >= 0);
+ assert_se(IN_SET(fd_is_network_ns(fd), 1, -EUCLEAN));
+}
+
int main(int argc, char *argv[]) {
test_files_same();
test_is_symlink();
test_path_is_fs_type();
test_path_is_temporary_fs();
+ test_fd_is_network_ns();
return 0;
}

@ -0,0 +1,93 @@
From 13d819cc795d8c3695ce7288436ad569366073f6 Mon Sep 17 00:00:00 2001
From: Michael Biebl <biebl@debian.org>
Date: Mon, 16 Jul 2018 11:27:44 +0200
Subject: [PATCH] test: Drop SKIP_INITRD for QEMU-based tests
Not all distros support booting without an initrd. E.g. the Debian
kernel builds ext4 as a module and so relies on an initrd to
successfully start the QEMU-based images.
Cherry-picked from: c2d4da002095fe6f86f89a508a81e48fb6d3196f
---
test/TEST-08-ISSUE-2730/test.sh | 1 -
test/TEST-09-ISSUE-2691/test.sh | 1 -
test/TEST-10-ISSUE-2467/test.sh | 1 -
test/TEST-11-ISSUE-3166/test.sh | 1 -
test/TEST-13-NSPAWN-SMOKE/test.sh | 2 +-
test/TEST-14-MACHINE-ID/test.sh | 2 +-
6 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/test/TEST-08-ISSUE-2730/test.sh b/test/TEST-08-ISSUE-2730/test.sh
index 68159c331f..90bf133c6a 100755
--- a/test/TEST-08-ISSUE-2730/test.sh
+++ b/test/TEST-08-ISSUE-2730/test.sh
@@ -6,7 +6,6 @@ TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2730"
TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions
-SKIP_INITRD=yes
QEMU_TIMEOUT=180
FSTYPE=ext4
diff --git a/test/TEST-09-ISSUE-2691/test.sh b/test/TEST-09-ISSUE-2691/test.sh
index 4c3e9496b4..9b5990bc60 100755
--- a/test/TEST-09-ISSUE-2691/test.sh
+++ b/test/TEST-09-ISSUE-2691/test.sh
@@ -6,7 +6,6 @@ TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2691"
TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions
-SKIP_INITRD=yes
QEMU_TIMEOUT=90
test_setup() {
diff --git a/test/TEST-10-ISSUE-2467/test.sh b/test/TEST-10-ISSUE-2467/test.sh
index 2f95e9062d..e61f5acd3c 100755
--- a/test/TEST-10-ISSUE-2467/test.sh
+++ b/test/TEST-10-ISSUE-2467/test.sh
@@ -5,7 +5,6 @@ set -e
TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2467"
. $TEST_BASE_DIR/test-functions
-SKIP_INITRD=yes
test_setup() {
create_empty_image
diff --git a/test/TEST-11-ISSUE-3166/test.sh b/test/TEST-11-ISSUE-3166/test.sh
index 4602bdfc98..8aae4d5ed9 100755
--- a/test/TEST-11-ISSUE-3166/test.sh
+++ b/test/TEST-11-ISSUE-3166/test.sh
@@ -6,7 +6,6 @@ TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/3166"
TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions
-SKIP_INITRD=yes
test_setup() {
create_empty_image
diff --git a/test/TEST-13-NSPAWN-SMOKE/test.sh b/test/TEST-13-NSPAWN-SMOKE/test.sh
index c0789b5d20..a676384bfc 100755
--- a/test/TEST-13-NSPAWN-SMOKE/test.sh
+++ b/test/TEST-13-NSPAWN-SMOKE/test.sh
@@ -4,7 +4,7 @@
set -e
TEST_DESCRIPTION="systemd-nspawn smoke test"
TEST_NO_NSPAWN=1
-SKIP_INITRD=yes
+
. $TEST_BASE_DIR/test-functions
test_setup() {
diff --git a/test/TEST-14-MACHINE-ID/test.sh b/test/TEST-14-MACHINE-ID/test.sh
index 7342645bc5..62003b91b6 100755
--- a/test/TEST-14-MACHINE-ID/test.sh
+++ b/test/TEST-14-MACHINE-ID/test.sh
@@ -4,7 +4,7 @@
set -e
TEST_DESCRIPTION="/etc/machine-id testing"
TEST_NO_NSPAWN=1
-SKIP_INITRD=yes
+
. $TEST_BASE_DIR/test-functions
test_setup() {

@ -0,0 +1,42 @@
From 9c1b72de44e68ad80be7c0b98df110e7b127072d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sun, 19 Aug 2018 19:11:30 +0200
Subject: [PATCH] meson: rename -Ddebug to -Ddebug-extra
Meson added -Doptimization and -Ddebug options, which obviously causes
a conflict with our -Ddebug options. Let's rename it.
Fixes #9883.
Cherry-picked from: 8f6b442a78d0b485f044742ad90b2e8271b4e68e
---
meson.build | 2 +-
meson_options.txt | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/meson.build b/meson.build
index f308db2631..ebc55872c9 100644
--- a/meson.build
+++ b/meson.build
@@ -769,7 +769,7 @@ substs.set('DEBUGTTY', get_option('debug-tty'))
enable_debug_hashmap = false
enable_debug_mmap_cache = false
-foreach name : get_option('debug')
+foreach name : get_option('debug-extra')
if name == 'hashmap'
enable_debug_hashmap = true
elif name == 'mmap-cache'
diff --git a/meson_options.txt b/meson_options.txt
index ab2a658713..5716f45ccf 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -46,7 +46,7 @@ option('debug-shell', type : 'string', value : '/bin/sh',
description : 'path to debug shell binary')
option('debug-tty', type : 'string', value : '/dev/tty9',
description : 'specify the tty device for debug shell')
-option('debug', type : 'array', choices : ['hashmap', 'mmap-cache'], value : [],
+option('debug-extra', type : 'array', choices : ['hashmap', 'mmap-cache'], value : [],
description : 'enable extra debugging')
option('memory-accounting-default', type : 'boolean',
description : 'enable MemoryAccounting= by default')

@ -0,0 +1,38 @@
From b6943446f8ffde53ce059b5e869c22bed8926827 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 25 Jun 2018 22:40:40 +0900
Subject: [PATCH] meson: check whether gnutls supports TCP fast open
Fixes #9403
Cherry-picked from: f02582f69fe1e7663a87ba80bd4f90d5d23ee75f
---
README | 1 +
meson.build | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/README b/README
index 2cde08c37e..7d06e04800 100644
--- a/README
+++ b/README
@@ -154,6 +154,7 @@ REQUIREMENTS:
libmicrohttpd (optional)
libpython (optional)
libidn2 or libidn (optional)
+ gnutls >= 3.1.4 (optional, >= 3.5.3 is necessary to support DNS-over-TLS)
elfutils >= 158 (optional)
polkit (optional)
pkg-config
diff --git a/meson.build b/meson.build
index ebc55872c9..d58926c981 100644
--- a/meson.build
+++ b/meson.build
@@ -1148,7 +1148,7 @@ substs.set('DEFAULT_DNSSEC_MODE', default_dnssec)
dns_over_tls = get_option('dns-over-tls')
if dns_over_tls != 'false'
- have = conf.get('HAVE_GNUTLS') == 1
+ have = libgnutls != [] and libgnutls.version().version_compare('>=3.5.3')
if dns_over_tls == 'true' and not have
error('DNS-over-TLS support was requested, but dependencies are not available')
endif

@ -0,0 +1,24 @@
From 03e52d33bbdea731eaa79545bb1d30c5b21abe3d Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Mon, 5 Sep 2016 12:47:09 +0200
Subject: [PATCH] unit: don't add Requires for tmp.mount
rhel-only
Resolves: #1619292
---
src/core/unit.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/unit.c b/src/core/unit.c
index c9f756c9c7..721d8d60a3 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1421,7 +1421,7 @@ static int unit_add_mount_dependencies(Unit *u) {
if (r < 0)
return r;
- if (m->fragment_path) {
+ if (m->fragment_path && !streq(m->id, "tmp.mount")) {
r = unit_add_dependency(u, UNIT_REQUIRES, m, true, di.origin_mask);
if (r < 0)
return r;

@ -0,0 +1,42 @@
From 1d43806017a0df257fef8ed6f79e12ee69c5bc20 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Thu, 8 Nov 2018 09:40:13 +0100
Subject: [PATCH] tests: drop the precondition check for inherited flag
Docker's default capability set has the inherited flag already
set - that breaks tests which expect otherwise. Let's just
drop the check and run the test anyway.
Fixes #10663
Cherry-picked from: c446b8486d9ed18d1bc780948ae9ee8a53fa4c3f
---
src/test/test-capability.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/src/test/test-capability.c b/src/test/test-capability.c
index af6d808b6d..72975cef94 100644
--- a/src/test/test-capability.c
+++ b/src/test/test-capability.c
@@ -180,8 +180,6 @@ static void test_update_inherited_set(void) {
caps = cap_get_proc();
assert_se(caps);
- assert_se(!cap_get_flag(caps, CAP_CHOWN, CAP_INHERITABLE, &fv));
- assert(fv == CAP_CLEAR);
set = (UINT64_C(1) << CAP_CHOWN);
@@ -197,12 +195,6 @@ static void test_set_ambient_caps(void) {
uint64_t set = 0;
cap_flag_value_t fv;
- caps = cap_get_proc();
- assert_se(caps);
- assert_se(!cap_get_flag(caps, CAP_CHOWN, CAP_INHERITABLE, &fv));
- assert(fv == CAP_CLEAR);
- cap_free(caps);
-
assert_se(prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0) == 0);
set = (UINT64_C(1) << CAP_CHOWN);

@ -0,0 +1,234 @@
From 55a1c766445750aaefe28bd7bea454f5f1cff9bb Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 17 Oct 2018 18:36:24 +0200
Subject: [PATCH] =?UTF-8?q?core:=20when=20deserializing=20state=20always?=
=?UTF-8?q?=20use=20read=5Fline(=E2=80=A6,=20LONG=5FLINE=5FMAX,=20?=
=?UTF-8?q?=E2=80=A6)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This should be much better than fgets(), as we can read substantially
longer lines and overly long lines result in proper errors.
Fixes a vulnerability discovered by Jann Horn at Google.
CVE-2018-15686
LP: #1796402
https://bugzilla.redhat.com/show_bug.cgi?id=1639071
(cherry picked from commit 8948b3415d762245ebf5e19d80b97d4d8cc208c1)
Resolves: CVE-2018-15686
---
src/core/job.c | 19 +++++++++++--------
src/core/manager.c | 47 ++++++++++++++++++++--------------------------
src/core/unit.c | 34 +++++++++++++++++----------------
src/core/unit.h | 2 +-
4 files changed, 50 insertions(+), 52 deletions(-)
diff --git a/src/core/job.c b/src/core/job.c
index 734756b666..8552ffb704 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -10,6 +10,7 @@
#include "dbus-job.h"
#include "dbus.h"
#include "escape.h"
+#include "fileio.h"
#include "job.h"
#include "log.h"
#include "macro.h"
@@ -1091,24 +1092,26 @@ int job_serialize(Job *j, FILE *f) {
}
int job_deserialize(Job *j, FILE *f) {
+ int r;
+
assert(j);
assert(f);
for (;;) {
- char line[LINE_MAX], *l, *v;
+ _cleanup_free_ char *line = NULL;
+ char *l, *v;
size_t k;
- if (!fgets(line, sizeof(line), f)) {
- if (feof(f))
- return 0;
- return -errno;
- }
+ r = read_line(f, LONG_LINE_MAX, &line);
+ if (r < 0)
+ return log_error_errno(r, "Failed to read serialization line: %m");
+ if (r == 0)
+ return 0;
- char_array_0(line);
l = strstrip(line);
/* End marker */
- if (l[0] == 0)
+ if (isempty(l))
return 0;
k = strcspn(l, "=");
diff --git a/src/core/manager.c b/src/core/manager.c
index 3b2fe11e87..c83e296cf3 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -3144,22 +3144,17 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
m->n_reloading++;
for (;;) {
- char line[LINE_MAX];
+ _cleanup_free_ char *line = NULL;
const char *val, *l;
- if (!fgets(line, sizeof(line), f)) {
- if (feof(f))
- r = 0;
- else
- r = -errno;
-
- goto finish;
- }
+ r = read_line(f, LONG_LINE_MAX, &line);
+ if (r < 0)
+ return log_error_errno(r, "Failed to read serialization line: %m");
+ if (r == 0)
+ break;
- char_array_0(line);
l = strstrip(line);
-
- if (l[0] == 0)
+ if (isempty(l)) /* end marker */
break;
if ((val = startswith(l, "current-job-id="))) {
@@ -3326,29 +3321,27 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
}
for (;;) {
- Unit *u;
- char name[UNIT_NAME_MAX+2];
+ _cleanup_free_ char *line = NULL;
const char* unit_name;
+ Unit *u;
/* Start marker */
- if (!fgets(name, sizeof(name), f)) {
- if (feof(f))
- r = 0;
- else
- r = -errno;
-
- goto finish;
- }
+ r = read_line(f, LONG_LINE_MAX, &line);
+ if (r < 0)
+ return log_error_errno(r, "Failed to read serialization line: %m");
+ if (r == 0)
+ break;
- char_array_0(name);
- unit_name = strstrip(name);
+ unit_name = strstrip(line);
r = manager_load_unit(m, unit_name, NULL, NULL, &u);
if (r < 0) {
log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", unit_name);
- if (r == -ENOMEM)
- goto finish;
- unit_deserialize_skip(f);
+
+ r = unit_deserialize_skip(f);
+ if (r < 0)
+ return r;
+
continue;
}
diff --git a/src/core/unit.c b/src/core/unit.c
index 721d8d60a3..cc43ddc4f1 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -3368,21 +3368,19 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
assert(fds);
for (;;) {
- char line[LINE_MAX], *l, *v;
+ _cleanup_free_ char *line = NULL;
CGroupIPAccountingMetric m;
+ char *l, *v;
size_t k;
- if (!fgets(line, sizeof(line), f)) {
- if (feof(f))
- return 0;
- return -errno;
- }
+ r = read_line(f, LONG_LINE_MAX, &line);
+ if (r < 0)
+ return log_error_errno(r, "Failed to read serialization line: %m");
+ if (r == 0) /* eof */
+ break;
- char_array_0(line);
l = strstrip(line);
-
- /* End marker */
- if (isempty(l))
+ if (isempty(l)) /* End marker */
break;
k = strcspn(l, "=");
@@ -3657,23 +3655,27 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
return 0;
}
-void unit_deserialize_skip(FILE *f) {
+int unit_deserialize_skip(FILE *f) {
+ int r;
assert(f);
/* Skip serialized data for this unit. We don't know what it is. */
for (;;) {
- char line[LINE_MAX], *l;
+ _cleanup_free_ char *line = NULL;
+ char *l;
- if (!fgets(line, sizeof line, f))
- return;
+ r = read_line(f, LONG_LINE_MAX, &line);
+ if (r < 0)
+ return log_error_errno(r, "Failed to read serialization line: %m");
+ if (r == 0)
+ return 0;
- char_array_0(line);
l = strstrip(line);
/* End marker */
if (isempty(l))
- return;
+ return 1;
}
}
diff --git a/src/core/unit.h b/src/core/unit.h
index b3131eba1b..e1a60da244 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -679,7 +679,7 @@ bool unit_can_serialize(Unit *u) _pure_;
int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs);
int unit_deserialize(Unit *u, FILE *f, FDSet *fds);
-void unit_deserialize_skip(FILE *f);
+int unit_deserialize_skip(FILE *f);
int unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value);
int unit_serialize_item_escaped(Unit *u, FILE *f, const char *key, const char *value);

@ -0,0 +1,44 @@
From 6abfec31acae53943896b309db4a09a1cecac9a3 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 17 Oct 2018 18:37:48 +0200
Subject: [PATCH] core: enforce a limit on STATUS= texts recvd from services
Let's better be safe than sorry, and put a limit on what we receive.
(cherry picked from commit 3eac1bcae9284fb8b18f4b82156c0e85ddb004e5)
Related: CVE-2018-15686
---
src/core/service.c | 8 ++++++--
src/core/service.h | 2 ++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/core/service.c b/src/core/service.c
index db1356c417..db17221888 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -3549,8 +3549,12 @@ static void service_notify_message(
_cleanup_free_ char *t = NULL;
if (!isempty(e)) {
- if (!utf8_is_valid(e))
- log_unit_warning(u, "Status message in notification message is not UTF-8 clean.");
+ /* Note that this size limit check is mostly paranoia: since the datagram size we are willing
+ * to process is already limited to NOTIFY_BUFFER_MAX, this limit here should never be hit. */
+ if (strlen(e) > STATUS_TEXT_MAX)
+ log_unit_warning(u, "Status message overly long (%zu > %u), ignoring.", strlen(e), STATUS_TEXT_MAX);
+ else if (!utf8_is_valid(e))
+ log_unit_warning(u, "Status message in notification message is not UTF-8 clean, ignoring.");
else {
t = strdup(e);
if (!t)
diff --git a/src/core/service.h b/src/core/service.h
index 9c06e91883..a142b09f0d 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -202,3 +202,5 @@ const char* service_result_to_string(ServiceResult i) _const_;
ServiceResult service_result_from_string(const char *s) _pure_;
DEFINE_CAST(SERVICE, Service);
+
+#define STATUS_TEXT_MAX (16U*1024U)

@ -0,0 +1,257 @@
From 5638e18196be1fabd9e78d4c506402bf700fe569 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <fsumsal@redhat.com>
Date: Mon, 7 Jan 2019 15:49:45 +0100
Subject: [PATCH] travis: enable Travis CI on CentOS 7
(cherry picked from commit 2014cb51b6dfe1f7f0b98e62311398c2bf801c2b)
---
.travis.yml | 86 ++++++++++-----------------------------------
ci/travis-centos.sh | 69 ++++++++++++++++++++++++++++++++++++
ci/travis_wait.bash | 61 ++++++++++++++++++++++++++++++++
3 files changed, 149 insertions(+), 67 deletions(-)
create mode 100755 ci/travis-centos.sh
create mode 100644 ci/travis_wait.bash
diff --git a/.travis.yml b/.travis.yml
index d980038181..fc63887324 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,77 +1,29 @@
sudo: required
-
services:
- docker
-language: c
+env:
+ global:
+ - CI_ROOT="$TRAVIS_BUILD_DIR/ci/"
jobs:
include:
- - stage: coverity scan
- before_script:
- - sudo apt-get update
+ - stage: Build & test
+ name: CentOS 7
+ language: bash
+ env:
+ - CENTOS_RELEASE="centos7"
+ - CONT_NAME="systemd-centos-$CENTOS_RELEASE"
+ - DOCKER_EXEC="docker exec -ti $CONT_NAME"
+ before_install:
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- docker --version
- - env > .env
- env:
- - COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG"
- - COVERITY_SCAN_NOTIFICATION_EMAIL="${AUTHOR_EMAIL}"
- - COVERITY_SCAN_BRANCH_PATTERN="$TRAVIS_BRANCH"
- # Encrypted token for systemd/systemd Coverity Scan Analysis,
- # generated by "travis encrypt -r systemd/systemd COVERITY_SCAN_TOKEN=<TOKEN>"
- - secure: "lM0IVP2zOG5Ywk3YCbDCQL4WioyzzwtdtpZ+hKDy4BWCZDBJ/FVwIeBsXdMDvlTa3xi+GQ1b7kS2OmTfmG4aSlhU7isuH8SMq1Y4GR5AxfhkR+irUA1A1fntlvhbjIumDGW5wjs0Dt8KogMWS+ZD4eGE59lrVO/TrhMzIe1eHENVLFQJdNq+ZJXU8wxMfHf8lXk0xA8SJTid0XvZBNc4JN6pjJRA8LaOrMNhQYfygFmVQ598kwlu7gf5vbCKFPnIgJAxdIhz12XS9utGohV28IYj9d1DdUGUT+ar3OfADj3X8KFBP4Ymc02pcln3wVgdPtrDbFZh1R9jbmfdXGAH/6tTOJVn8aFySS2Vq9QiBiprWdPsAOLcWMNhnp0lMkASxs9/W26nU7Czo8VbAVWXM1w35plDpnDGR6lk/06dmOZpqu5p3AYr5xIKACIAdPDn0rNpnSWqC750WZ8ZWbHnKuZC5TWML7scVaPiEi7D7rbwqML2rdwx4ZoTZmCHiGByXCIWTfhf0JNQAix5WW3znl+BmDesumPgPj2mX+y6J1WYJrIz12m7qh7KhV/a1ODKM+I91A9rkOA/bPnmhmSSUR7CwgvZt1fC/VwBnaFFtAz9/70kN9Q8tDBXtXidExZwh1e3t5vDG72k3lXwNqpKRvdW3LOxK6lFvqEdMWVUJls="
+ install:
+ - $CI_ROOT/travis-centos.sh SETUP
script:
- # Copy content of CI_DIR into WORKDIR
- - find $CI_DIR -maxdepth 1 -type f -exec cp -t . {} +
- # Build container for current user
- - $CI_SCRIPT_DIR/build-docker-image.sh
-
- # For kernel version 4.8+
- - sudo sysctl vsyscall=emulate || true
- # Prepare environment for Coverity tool
- - |
- PLATFORM=`uname`
- export TOOL_BASE="/tmp/coverity-scan-analysis"
- export SCAN_URL="https://scan.coverity.com"
- export UPLOAD_URL="https://scan.coverity.com/builds"
- export TOOL_ARCHIVE="/tmp/cov-analysis-${PLATFORM}.tgz"
-
- # Get Coverity tool
- - $CI_TOOL_DIR/get-coverity.sh
- - TOOL_DIR="$(find $TOOL_BASE -type d -name 'cov-analysis*')"
-
- # Export env variables for Coverity scan
- - env | grep -E "TRAVIS|COV|TOOL|URL" > .cov-env
- - |
- docker run -dit --env-file .cov-env \
- -v ${TOOL_BASE}:${TOOL_BASE}:ro \
- --name travis_coverity_scan coverity-${TRAVIS_COMMIT}:latest bash
- # Make sure Coverity script is executable
- - docker cp tools/coverity.sh travis_coverity_scan:/usr/local/bin
- # Preconfigure with meson to prevent Coverity from capturing meson metadata
- # Set compiler flag to prevent emit failure
- - docker exec -it travis_coverity_scan sh -c "CFLAGS='-D_Float128=long\ double -D_Float64=double -D_Float64x=long\ double -D_Float32=float -D_Float32x=double' meson cov-build -Dman=false"
- # Run Coverity Analysis
- - docker exec -it travis_coverity_scan coverity.sh build
- - docker exec -it travis_coverity_scan coverity.sh upload
-
-# Specify the order of stages and conditions
-stages:
- - name: coverity scan
- if: type = cron
-
-env:
- global:
- - ADMIN_EMAIL=macermak@redhat.com
-
- - AUTHOR_NAME="$(git log -1 $TRAVIS_COMMIT --pretty=\"%aN\")"
- - AUTHOR_EMAIL="$(git log -1 $TRAVIS_COMMIT --pretty=\"%aE\")"
-
- - CI_DIR="$TRAVIS_BUILD_DIR/travis-ci"
- - CI_TOOL_DIR="$CI_DIR/tools"
- - CI_SCRIPT_DIR="$CI_DIR/scripts"
-
-notifications:
- email:
- recipients:
- - ${ADMIN_EMAIL}
+ - set -e
+ # Build systemd
+ - $CI_ROOT/travis-centos.sh RUN
+ - set +e
+ after_script:
+ - $CI_ROOT/travis-centos.sh CLEANUP
diff --git a/ci/travis-centos.sh b/ci/travis-centos.sh
new file mode 100755
index 0000000000..60bbdf14c2
--- /dev/null
+++ b/ci/travis-centos.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+# Run this script from the root of the systemd's git repository
+# or set REPO_ROOT to a correct path.
+#
+# Example execution on Fedora:
+# dnf install docker
+# systemctl start docker
+# export CONT_NAME="my-fancy-container"
+# ci/travis-centos.sh SETUP RUN CLEANUP
+
+PHASES=(${@:-SETUP RUN CLEANUP})
+CENTOS_RELEASE="${CENTOS_RELEASE:-latest}"
+CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}"
+DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}"
+DOCKER_RUN="${DOCKER_RUN:-docker run}"
+REPO_ROOT="${REPO_ROOT:-$PWD}"
+ADDITIONAL_DEPS=(yum-utils iputils hostname libasan libubsan clang llvm)
+
+function info() {
+ echo -e "\033[33;1m$1\033[0m"
+}
+
+set -e
+
+source "$(dirname $0)/travis_wait.bash"
+
+for phase in "${PHASES[@]}"; do
+ case $phase in
+ SETUP)
+ info "Setup phase"
+ info "Using Travis $CENTOS_RELEASE"
+ # Pull a Docker image and start a new container
+ docker pull centos:$CENTOS_RELEASE
+ info "Starting container $CONT_NAME"
+ $DOCKER_RUN -v $REPO_ROOT:/build:rw \
+ -w /build --privileged=true --name $CONT_NAME \
+ -dit --net=host centos:$CENTOS_RELEASE /sbin/init
+ # Beautiful workaround for Fedora's version of Docker
+ sleep 1
+ $DOCKER_EXEC yum makecache
+ # Install necessary build/test requirements
+ $DOCKER_EXEC yum -y --exclude selinux-policy\* upgrade
+ $DOCKER_EXEC yum -y install "${ADDITIONAL_DEPS[@]}"
+ $DOCKER_EXEC yum-builddep -y systemd
+ ;;
+ RUN)
+ info "Run phase"
+ # Build systemd
+ $DOCKER_EXEC ./autogen.sh
+ $DOCKER_EXEC ./configure --disable-timesyncd --disable-kdbus --disable-terminal \
+ --enable-gtk-doc --enable-compat-libs --disable-sysusers \
+ --disable-ldconfig --enable-lz4 --with-sysvinit-path=/etc/rc.d/init.d
+ $DOCKER_EXEC make
+ if ! $DOCKER_EXEC make check; then
+ $DOCKER_EXEC cat test-suite.log
+ exit 1
+ fi
+ ;;
+ CLEANUP)
+ info "Cleanup phase"
+ docker stop $CONT_NAME
+ docker rm -f $CONT_NAME
+ ;;
+ *)
+ echo >&2 "Unknown phase '$phase'"
+ exit 1
+ esac
+done
diff --git a/ci/travis_wait.bash b/ci/travis_wait.bash
new file mode 100644
index 0000000000..acf6ad15e4
--- /dev/null
+++ b/ci/travis_wait.bash
@@ -0,0 +1,61 @@
+# This was borrowed from https://github.com/travis-ci/travis-build/tree/master/lib/travis/build/bash
+# to get around https://github.com/travis-ci/travis-ci/issues/9979. It should probably be removed
+# as soon as Travis CI has started to provide an easy way to export the functions to bash scripts.
+
+travis_jigger() {
+ local cmd_pid="${1}"
+ shift
+ local timeout="${1}"
+ shift
+ local count=0
+
+ echo -e "\\n"
+
+ while [[ "${count}" -lt "${timeout}" ]]; do
+ count="$((count + 1))"
+ echo -ne "Still running (${count} of ${timeout}): ${*}\\r"
+ sleep 60
+ done
+
+ echo -e "\\n${ANSI_RED}Timeout (${timeout} minutes) reached. Terminating \"${*}\"${ANSI_RESET}\\n"
+ kill -9 "${cmd_pid}"
+}
+
+travis_wait() {
+ local timeout="${1}"
+
+ if [[ "${timeout}" =~ ^[0-9]+$ ]]; then
+ shift
+ else
+ timeout=20
+ fi
+
+ local cmd=("${@}")
+ local log_file="travis_wait_${$}.log"
+
+ "${cmd[@]}" &>"${log_file}" &
+ local cmd_pid="${!}"
+
+ travis_jigger "${!}" "${timeout}" "${cmd[@]}" &
+ local jigger_pid="${!}"
+ local result
+
+ {
+ set +e
+ wait "${cmd_pid}" 2>/dev/null
+ result="${?}"
+ ps -p"${jigger_pid}" &>/dev/null && kill "${jigger_pid}"
+ set -e
+ }
+
+ if [[ "${result}" -eq 0 ]]; then
+ echo -e "\\n${ANSI_GREEN}The command ${cmd[*]} exited with ${result}.${ANSI_RESET}"
+ else
+ echo -e "\\n${ANSI_RED}The command ${cmd[*]} exited with ${result}.${ANSI_RESET}"
+ fi
+
+ echo -e "\\n${ANSI_GREEN}Log:${ANSI_RESET}\\n"
+ cat "${log_file}"
+
+ return "${result}"
+}

@ -0,0 +1,175 @@
From 45b0a38b47e07186dfe35095c7d8b1e4c2524d80 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <fsumsal@redhat.com>
Date: Mon, 14 Jan 2019 14:49:32 +0100
Subject: [PATCH] travis: RHEL8 support
(cherry picked from commit e5c78840b2b124400f56cb5fbaf2357cd8901218)
---
.travis.yml | 8 +-
...ravis-centos.sh => travis-centos-rhel7.sh} | 0
ci/travis-centos-rhel8.sh | 130 ++++++++++++++++++
3 files changed, 135 insertions(+), 3 deletions(-)
rename ci/{travis-centos.sh => travis-centos-rhel7.sh} (100%)
create mode 100755 ci/travis-centos-rhel8.sh
diff --git a/.travis.yml b/.travis.yml
index fc63887324..1c4e6f9728 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,11 +19,13 @@ jobs:
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- docker --version
install:
- - $CI_ROOT/travis-centos.sh SETUP
+ - RHEL_VERSION="rhel7"
+ - [ -f meson.build ] && RHEL_VERSION="rhel8"
+ - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh SETUP
script:
- set -e
# Build systemd
- - $CI_ROOT/travis-centos.sh RUN
+ - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh RUN
- set +e
after_script:
- - $CI_ROOT/travis-centos.sh CLEANUP
+ - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh CLEANUP
diff --git a/ci/travis-centos.sh b/ci/travis-centos-rhel7.sh
similarity index 100%
rename from ci/travis-centos.sh
rename to ci/travis-centos-rhel7.sh
diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh
new file mode 100755
index 0000000000..968603f949
--- /dev/null
+++ b/ci/travis-centos-rhel8.sh
@@ -0,0 +1,130 @@
+#!/bin/bash
+
+# Run this script from the root of the systemd's git repository
+# or set REPO_ROOT to a correct path.
+#
+# Example execution on Fedora:
+# dnf install docker
+# systemctl start docker
+# export CONT_NAME="my-fancy-container"
+# ci/travis-centos.sh SETUP RUN CLEANUP
+
+PHASES=(${@:-SETUP RUN CLEANUP})
+CENTOS_RELEASE="${CENTOS_RELEASE:-latest}"
+CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}"
+DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}"
+DOCKER_RUN="${DOCKER_RUN:-docker run}"
+REPO_ROOT="${REPO_ROOT:-$PWD}"
+ADDITIONAL_DEPS=(systemd-ci-environment libidn2-devel python-lxml python36 ninja-build libasan net-tools strace nc busybox e2fsprogs quota dnsmasq)
+# Repo with additional depencencies to compile newer systemd on CentOS 7
+COPR_REPO="https://copr.fedorainfracloud.org/coprs/mrc0mmand/systemd-centos-ci/repo/epel-7/mrc0mmand-systemd-centos-ci-epel-7.repo"
+COPR_REPO_PATH="/etc/yum.repos.d/${COPR_REPO##*/}"
+
+function info() {
+ echo -e "\033[33;1m$1\033[0m"
+}
+
+set -e
+
+source "$(dirname $0)/travis_wait.bash"
+
+for phase in "${PHASES[@]}"; do
+ case $phase in
+ SETUP)
+ info "Setup phase"
+ info "Using Travis $CENTOS_RELEASE"
+ # Pull a Docker image and start a new container
+ docker pull centos:$CENTOS_RELEASE
+ info "Starting container $CONT_NAME"
+ $DOCKER_RUN -v $REPO_ROOT:/build:rw \
+ -w /build --privileged=true --name $CONT_NAME \
+ -dit --net=host centos:$CENTOS_RELEASE /sbin/init
+ # Beautiful workaround for Fedora's version of Docker
+ sleep 1
+ $DOCKER_EXEC yum makecache
+ $DOCKER_EXEC curl "$COPR_REPO" -o "$COPR_REPO_PATH"
+ $DOCKER_EXEC yum -q -y install epel-release yum-utils
+ $DOCKER_EXEC yum-config-manager -q --enable epel
+ $DOCKER_EXEC yum -y --exclude selinux-policy\* upgrade
+ # Install necessary build/test requirements
+ $DOCKER_EXEC yum -y install "${ADDITIONAL_DEPS[@]}"
+ $DOCKER_EXEC python3.6 -m ensurepip
+ $DOCKER_EXEC python3.6 -m pip install meson
+ # Create necessary symlinks
+ $DOCKER_EXEC ln --force -s /usr/bin/python3.6 /usr/bin/python3
+ $DOCKER_EXEC ln --force -s /usr/bin/ninja-build /usr/bin/ninja
+ ;;
+ RUN)
+ info "Run phase"
+ # Build systemd
+ CONFIGURE_OPTS=(
+ # RHEL8 options
+ -Dsysvinit-path=/etc/rc.d/init.d
+ -Drc-local=/etc/rc.d/rc.local
+ -Ddns-servers=''
+ -Ddev-kvm-mode=0666
+ -Dkmod=true
+ -Dxkbcommon=true
+ -Dblkid=true
+ -Dseccomp=true
+ -Dima=true
+ -Dselinux=true
+ -Dapparmor=false
+ -Dpolkit=true
+ -Dxz=true
+ -Dzlib=true
+ -Dbzip2=true
+ -Dlz4=true
+ -Dpam=true
+ -Dacl=true
+ -Dsmack=true
+ -Dgcrypt=true
+ -Daudit=true
+ -Delfutils=true
+ -Dlibcryptsetup=true
+ -Delfutils=true
+ -Dqrencode=false
+ -Dgnutls=true
+ -Dmicrohttpd=true
+ -Dlibidn2=true
+ -Dlibiptc=true
+ -Dlibcurl=true
+ -Defi=true
+ -Dtpm=true
+ -Dhwdb=true
+ -Dsysusers=true
+ -Ddefault-kill-user-processes=false
+ -Dtests=unsafe
+ -Dinstall-tests=true
+ -Dtty-gid=5
+ -Dusers-gid=100
+ -Dnobody-user=nobody
+ -Dnobody-group=nobody
+ -Dsplit-usr=false
+ -Dsplit-bin=true
+ -Db_lto=false
+ -Dnetworkd=false
+ -Dtimesyncd=false
+ -Ddefault-hierarchy=legacy
+ # Custom options
+ -Dslow-tests=true
+ -Dtests=unsafe
+ -Dinstall-tests=true
+ )
+ docker exec -it -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build "${CONFIGURE_OPTS[@]}"
+ $DOCKER_EXEC ninja -v -C build
+ # "Mask" the udev-test.pl, as it requires newer version of systemd-detect-virt
+ # and it's pointless to run it on a VM in a Docker container...
+ echo -ne "#!/usr/bin/perl\nexit(0);\n" > "test/udev-test.pl"
+ $DOCKER_EXEC ninja -C build test
+ ;;
+ CLEANUP)
+ info "Cleanup phase"
+ docker stop $CONT_NAME
+ docker rm -f $CONT_NAME
+ ;;
+ *)
+ echo >&2 "Unknown phase '$phase'"
+ exit 1
+ esac
+done

@ -0,0 +1,37 @@
From 2d674d48e9ca48e3bb126f20b59334100d926a23 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <fsumsal@redhat.com>
Date: Tue, 15 Jan 2019 11:03:45 +0100
Subject: [PATCH] travis: drop the SELinux Fedora workaround
(cherry picked from commit 90399c456fe8cf726fc04fb7be9e2a01f9ca0eae)
---
ci/travis-centos-rhel7.sh | 2 +-
ci/travis-centos-rhel8.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ci/travis-centos-rhel7.sh b/ci/travis-centos-rhel7.sh
index 60bbdf14c2..b1b3de1cc2 100755
--- a/ci/travis-centos-rhel7.sh
+++ b/ci/travis-centos-rhel7.sh
@@ -40,7 +40,7 @@ for phase in "${PHASES[@]}"; do
sleep 1
$DOCKER_EXEC yum makecache
# Install necessary build/test requirements
- $DOCKER_EXEC yum -y --exclude selinux-policy\* upgrade
+ $DOCKER_EXEC yum -y upgrade
$DOCKER_EXEC yum -y install "${ADDITIONAL_DEPS[@]}"
$DOCKER_EXEC yum-builddep -y systemd
;;
diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh
index 968603f949..8eda5e982f 100755
--- a/ci/travis-centos-rhel8.sh
+++ b/ci/travis-centos-rhel8.sh
@@ -45,7 +45,7 @@ for phase in "${PHASES[@]}"; do
$DOCKER_EXEC curl "$COPR_REPO" -o "$COPR_REPO_PATH"
$DOCKER_EXEC yum -q -y install epel-release yum-utils
$DOCKER_EXEC yum-config-manager -q --enable epel
- $DOCKER_EXEC yum -y --exclude selinux-policy\* upgrade
+ $DOCKER_EXEC yum -y upgrade
# Install necessary build/test requirements
$DOCKER_EXEC yum -y install "${ADDITIONAL_DEPS[@]}"
$DOCKER_EXEC python3.6 -m ensurepip

@ -0,0 +1,24 @@
From a7f87d13f6f7dd92e1f1f7617df531fa34c70b6d Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <fsumsal@redhat.com>
Date: Tue, 15 Jan 2019 14:35:27 +0100
Subject: [PATCH] travis: fix syntax error in .travis.yml
(cherry picked from commit 7f9d44f527ea214347f7d3b3b067f84df53feed7)
---
.travis.yml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 1c4e6f9728..c5c9c345a9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,8 +19,7 @@ jobs:
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- docker --version
install:
- - RHEL_VERSION="rhel7"
- - [ -f meson.build ] && RHEL_VERSION="rhel8"
+ - if [ -f meson.build ]; then RHEL_VERSION=rhel8; else RHEL_VERSION=rhel7; fi
- $CI_ROOT/travis-centos-${RHEL_VERSION}.sh SETUP
script:
- set -e

@ -0,0 +1,40 @@
From 63e71bda5a00c04c16f330cfc0e6f91e7dcead59 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <fsumsal@redhat.com>
Date: Thu, 17 Jan 2019 12:03:10 +0100
Subject: [PATCH] travis: reboot the container before running tests
---
ci/travis-centos-rhel7.sh | 4 ++++
ci/travis-centos-rhel8.sh | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/ci/travis-centos-rhel7.sh b/ci/travis-centos-rhel7.sh
index b1b3de1cc2..73416798ed 100755
--- a/ci/travis-centos-rhel7.sh
+++ b/ci/travis-centos-rhel7.sh
@@ -52,6 +52,10 @@ for phase in "${PHASES[@]}"; do
--enable-gtk-doc --enable-compat-libs --disable-sysusers \
--disable-ldconfig --enable-lz4 --with-sysvinit-path=/etc/rc.d/init.d
$DOCKER_EXEC make
+ # Let's install the new systemd and "reboot" the container to avoid
+ # unexpected fails due to incompatibilities with older systemd
+ $DOCKER_EXEC make install
+ docker restart $CONT_NAME
if ! $DOCKER_EXEC make check; then
$DOCKER_EXEC cat test-suite.log
exit 1
diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh
index 8eda5e982f..1f72d984e0 100755
--- a/ci/travis-centos-rhel8.sh
+++ b/ci/travis-centos-rhel8.sh
@@ -113,6 +113,10 @@ for phase in "${PHASES[@]}"; do
)
docker exec -it -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build "${CONFIGURE_OPTS[@]}"
$DOCKER_EXEC ninja -v -C build
+ # Let's install the new systemd and "reboot" the container to avoid
+ # unexpected fails due to incompatibilities with older systemd
+ $DOCKER_EXEC ninja -C build install
+ docker restart $CONT_NAME
# "Mask" the udev-test.pl, as it requires newer version of systemd-detect-virt
# and it's pointless to run it on a VM in a Docker container...
echo -ne "#!/usr/bin/perl\nexit(0);\n" > "test/udev-test.pl"

@ -0,0 +1,35 @@
From af43906bb0c8f2bb3b135d68d56ea2fa58fa9e60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 5 Dec 2018 17:33:15 +0100
Subject: [PATCH] coredump: remove duplicate MESSAGE= prefix from message
systemd-coredump[9982]: MESSAGE=Process 771 (systemd-journal) of user 0 dumped core.
systemd-coredump[9982]: Coredump diverted to /var/lib/systemd/coredump/core...
log_dispatch() calls log_dispatch_internal() which calls write_to_journal()
which appends MESSAGE= on its own.
(cherry-picked from commit 4f62556d71206ac814a020a954b397d4940e14c3)
Related: #1664976
---
src/coredump/coredump.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index 20a1cbdd45..d7dd81c1b4 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -789,9 +789,10 @@ log:
return log_oom();
if (journald_crash) {
- /* We cannot log to the journal, so just print the MESSAGE.
+ /* We cannot log to the journal, so just print the message.
* The target was set previously to something safe. */
- log_dispatch(LOG_ERR, 0, core_message);
+ assert(startswith(core_message, "MESSAGE="));
+ log_dispatch(LOG_ERR, 0, core_message + strlen("MESSAGE="));
return 0;
}

@ -0,0 +1,34 @@
From 285e4d2ce6a8836ce7bf2e889d43b7272f7ccc1b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 5 Dec 2018 17:53:50 +0100
Subject: [PATCH] journald: remove unnecessary {}
(cherry-picked from commit bc2762a309132a34db1797d8b5792d5747a94484)
Related: #1664976
---
src/journal/journald-server.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 4f1550ec5b..ce2446a2f1 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -1124,8 +1124,7 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void
return log_error_errno(errno, "recvmsg() failed: %m");
}
- CMSG_FOREACH(cmsg, &msghdr) {
-
+ CMSG_FOREACH(cmsg, &msghdr)
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
@@ -1143,7 +1142,6 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void
fds = (int*) CMSG_DATA(cmsg);
n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
}
- }
/* And a trailing NUL, just in case */
s->buffer[n] = 0;

@ -0,0 +1,202 @@
From b6c10945e68949edc6418f48ca7b1b748fefabe1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 5 Dec 2018 18:38:39 +0100
Subject: [PATCH] journald: do not store the iovec entry for process
commandline on stack
This fixes a crash where we would read the commandline, whose length is under
control of the sending program, and then crash when trying to create a stack
allocation for it.
CVE-2018-16864
https://bugzilla.redhat.com/show_bug.cgi?id=1653855
The message actually doesn't get written to disk, because
journal_file_append_entry() returns -E2BIG.
(cherry-picked from commit 084eeb865ca63887098e0945fb4e93c852b91b0f)
Resolves: #1664976
---
src/basic/io-util.c | 10 ++++++++++
src/basic/io-util.h | 2 ++
src/coredump/coredump.c | 31 +++++++++++--------------------
src/journal/journald-server.c | 25 +++++++++++++++----------
4 files changed, 38 insertions(+), 30 deletions(-)
diff --git a/src/basic/io-util.c b/src/basic/io-util.c
index 1f64cc933b..575398fbe6 100644
--- a/src/basic/io-util.c
+++ b/src/basic/io-util.c
@@ -8,6 +8,7 @@
#include <unistd.h>
#include "io-util.h"
+#include "string-util.h"
#include "time-util.h"
int flush_fd(int fd) {
@@ -252,3 +253,12 @@ ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
return q - (const uint8_t*) p;
}
+
+char* set_iovec_string_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value) {
+ char *x;
+
+ x = strappend(field, value);
+ if (x)
+ iovec[(*n_iovec)++] = IOVEC_MAKE_STRING(x);
+ return x;
+}
diff --git a/src/basic/io-util.h b/src/basic/io-util.h
index ed189b5820..792a64ad5e 100644
--- a/src/basic/io-util.h
+++ b/src/basic/io-util.h
@@ -71,3 +71,5 @@ static inline bool FILE_SIZE_VALID_OR_INFINITY(uint64_t l) {
#define IOVEC_MAKE(base, len) (struct iovec) IOVEC_INIT(base, len)
#define IOVEC_INIT_STRING(string) IOVEC_INIT((char*) string, strlen(string))
#define IOVEC_MAKE_STRING(string) (struct iovec) IOVEC_INIT_STRING(string)
+
+char* set_iovec_string_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value);
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index d7dd81c1b4..ffa88f612d 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -1054,19 +1054,10 @@ static int send_iovec(const struct iovec iovec[], size_t n_iovec, int input_fd)
return 0;
}
-static char* set_iovec_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value) {
- char *x;
-
- x = strappend(field, value);
- if (x)
- iovec[(*n_iovec)++] = IOVEC_MAKE_STRING(x);
- return x;
-}
-
static char* set_iovec_field_free(struct iovec *iovec, size_t *n_iovec, const char *field, char *value) {
char *x;
- x = set_iovec_field(iovec, n_iovec, field, value);
+ x = set_iovec_string_field(iovec, n_iovec, field, value);
free(value);
return x;
}
@@ -1116,36 +1107,36 @@ static int gather_pid_metadata(
disable_coredumps();
}
- set_iovec_field(iovec, n_iovec, "COREDUMP_UNIT=", context[CONTEXT_UNIT]);
+ set_iovec_string_field(iovec, n_iovec, "COREDUMP_UNIT=", context[CONTEXT_UNIT]);
}
if (cg_pid_get_user_unit(pid, &t) >= 0)
set_iovec_field_free(iovec, n_iovec, "COREDUMP_USER_UNIT=", t);
/* The next few are mandatory */
- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_PID=", context[CONTEXT_PID]))
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_PID=", context[CONTEXT_PID]))
return log_oom();
- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_UID=", context[CONTEXT_UID]))
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_UID=", context[CONTEXT_UID]))
return log_oom();
- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_GID=", context[CONTEXT_GID]))
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_GID=", context[CONTEXT_GID]))
return log_oom();
- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_SIGNAL=", context[CONTEXT_SIGNAL]))
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_SIGNAL=", context[CONTEXT_SIGNAL]))
return log_oom();
- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_RLIMIT=", context[CONTEXT_RLIMIT]))
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_RLIMIT=", context[CONTEXT_RLIMIT]))
return log_oom();
- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_HOSTNAME=", context[CONTEXT_HOSTNAME]))
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_HOSTNAME=", context[CONTEXT_HOSTNAME]))
return log_oom();
- if (!set_iovec_field(iovec, n_iovec, "COREDUMP_COMM=", context[CONTEXT_COMM]))
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_COMM=", context[CONTEXT_COMM]))
return log_oom();
if (context[CONTEXT_EXE] &&
- !set_iovec_field(iovec, n_iovec, "COREDUMP_EXE=", context[CONTEXT_EXE]))
+ !set_iovec_string_field(iovec, n_iovec, "COREDUMP_EXE=", context[CONTEXT_EXE]))
return log_oom();
if (sd_pid_get_session(pid, &t) >= 0)
@@ -1213,7 +1204,7 @@ static int gather_pid_metadata(
iovec[(*n_iovec)++] = IOVEC_MAKE_STRING(t);
if (safe_atoi(context[CONTEXT_SIGNAL], &signo) >= 0 && SIGNAL_VALID(signo))
- set_iovec_field(iovec, n_iovec, "COREDUMP_SIGNAL_NAME=SIG", signal_to_string(signo));
+ set_iovec_string_field(iovec, n_iovec, "COREDUMP_SIGNAL_NAME=SIG", signal_to_string(signo));
return 0; /* we successfully acquired all metadata */
}
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index ce2446a2f1..8de45552f6 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -753,6 +753,7 @@ static void dispatch_message_real(
pid_t object_pid) {
char source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)];
+ _cleanup_free_ char *cmdline1 = NULL, *cmdline2 = NULL;
uid_t journal_uid;
ClientContext *o;
@@ -769,20 +770,23 @@ static void dispatch_message_real(
IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->uid, uid_t, uid_is_valid, UID_FMT, "_UID");
IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->gid, gid_t, gid_is_valid, GID_FMT, "_GID");
- IOVEC_ADD_STRING_FIELD(iovec, n, c->comm, "_COMM");
- IOVEC_ADD_STRING_FIELD(iovec, n, c->exe, "_EXE");
- IOVEC_ADD_STRING_FIELD(iovec, n, c->cmdline, "_CMDLINE");
- IOVEC_ADD_STRING_FIELD(iovec, n, c->capeff, "_CAP_EFFECTIVE");
+ IOVEC_ADD_STRING_FIELD(iovec, n, c->comm, "_COMM"); /* At most TASK_COMM_LENGTH (16 bytes) */
+ IOVEC_ADD_STRING_FIELD(iovec, n, c->exe, "_EXE"); /* A path, so at most PATH_MAX (4096 bytes) */
- IOVEC_ADD_SIZED_FIELD(iovec, n, c->label, c->label_size, "_SELINUX_CONTEXT");
+ if (c->cmdline)
+ /* At most _SC_ARG_MAX (2MB usually), which is too much to put on stack.
+ * Let's use a heap allocation for this one. */
+ cmdline1 = set_iovec_string_field(iovec, &n, "_CMDLINE=", c->cmdline);
+ IOVEC_ADD_STRING_FIELD(iovec, n, c->capeff, "_CAP_EFFECTIVE"); /* Read from /proc/.../status */
+ IOVEC_ADD_SIZED_FIELD(iovec, n, c->label, c->label_size, "_SELINUX_CONTEXT");
IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->auditid, uint32_t, audit_session_is_valid, "%" PRIu32, "_AUDIT_SESSION");
IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->loginuid, uid_t, uid_is_valid, UID_FMT, "_AUDIT_LOGINUID");
- IOVEC_ADD_STRING_FIELD(iovec, n, c->cgroup, "_SYSTEMD_CGROUP");
+ IOVEC_ADD_STRING_FIELD(iovec, n, c->cgroup, "_SYSTEMD_CGROUP"); /* A path */
IOVEC_ADD_STRING_FIELD(iovec, n, c->session, "_SYSTEMD_SESSION");
IOVEC_ADD_NUMERIC_FIELD(iovec, n, c->owner_uid, uid_t, uid_is_valid, UID_FMT, "_SYSTEMD_OWNER_UID");
- IOVEC_ADD_STRING_FIELD(iovec, n, c->unit, "_SYSTEMD_UNIT");
+ IOVEC_ADD_STRING_FIELD(iovec, n, c->unit, "_SYSTEMD_UNIT"); /* Unit names are bounded by UNIT_NAME_MAX */
IOVEC_ADD_STRING_FIELD(iovec, n, c->user_unit, "_SYSTEMD_USER_UNIT");
IOVEC_ADD_STRING_FIELD(iovec, n, c->slice, "_SYSTEMD_SLICE");
IOVEC_ADD_STRING_FIELD(iovec, n, c->user_slice, "_SYSTEMD_USER_SLICE");
@@ -803,13 +807,14 @@ static void dispatch_message_real(
IOVEC_ADD_NUMERIC_FIELD(iovec, n, o->uid, uid_t, uid_is_valid, UID_FMT, "OBJECT_UID");
IOVEC_ADD_NUMERIC_FIELD(iovec, n, o->gid, gid_t, gid_is_valid, GID_FMT, "OBJECT_GID");
+ /* See above for size limits, only ->cmdline may be large, so use a heap allocation for it. */
IOVEC_ADD_STRING_FIELD(iovec, n, o->comm, "OBJECT_COMM");
IOVEC_ADD_STRING_FIELD(iovec, n, o->exe, "OBJECT_EXE");
- IOVEC_ADD_STRING_FIELD(iovec, n, o->cmdline, "OBJECT_CMDLINE");
- IOVEC_ADD_STRING_FIELD(iovec, n, o->capeff, "OBJECT_CAP_EFFECTIVE");
+ if (o->cmdline)
+ cmdline2 = set_iovec_string_field(iovec, &n, "OBJECT_CMDLINE=", o->cmdline);
+ IOVEC_ADD_STRING_FIELD(iovec, n, o->capeff, "OBJECT_CAP_EFFECTIVE");
IOVEC_ADD_SIZED_FIELD(iovec, n, o->label, o->label_size, "OBJECT_SELINUX_CONTEXT");
-
IOVEC_ADD_NUMERIC_FIELD(iovec, n, o->auditid, uint32_t, audit_session_is_valid, "%" PRIu32, "OBJECT_AUDIT_SESSION");
IOVEC_ADD_NUMERIC_FIELD(iovec, n, o->loginuid, uid_t, uid_is_valid, UID_FMT, "OBJECT_AUDIT_LOGINUID");

@ -0,0 +1,159 @@
From 6298317e2d0dffb1ff4ecebedb8709645de36b6a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 5 Dec 2018 18:48:23 +0100
Subject: [PATCH] basic/process-util: limit command line lengths to _SC_ARG_MAX
This affects systemd-journald and systemd-coredump.
Example entry:
$ journalctl -o export -n1 'MESSAGE=Something logged'
__CURSOR=s=976542d120c649f494471be317829ef9;i=34e;b=4871e4c474574ce4a462dfe3f1c37f06;m=c7d0c37dd2;t=57c4ac58f3b98;x=67598e942bd23dc0
__REALTIME_TIMESTAMP=1544035467475864
__MONOTONIC_TIMESTAMP=858200964562
_BOOT_ID=4871e4c474574ce4a462dfe3f1c37f06
PRIORITY=6
_UID=1000
_GID=1000
_CAP_EFFECTIVE=0
_SELINUX_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
_AUDIT_SESSION=1
_AUDIT_LOGINUID=1000
_SYSTEMD_OWNER_UID=1000
_SYSTEMD_UNIT=user@1000.service
_SYSTEMD_SLICE=user-1000.slice
_SYSTEMD_USER_SLICE=-.slice
_SYSTEMD_INVOCATION_ID=1c4a469986d448719cb0f9141a10810e
_MACHINE_ID=08a5690a2eed47cf92ac0a5d2e3cf6b0
_HOSTNAME=krowka
_TRANSPORT=syslog
SYSLOG_FACILITY=17
SYSLOG_IDENTIFIER=syslog-caller
MESSAGE=Something logged
_COMM=poc
_EXE=/home/zbyszek/src/systemd-work3/poc
_SYSTEMD_CGROUP=/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service
_SYSTEMD_USER_UNIT=gnome-terminal-server.service
SYSLOG_PID=4108
SYSLOG_TIMESTAMP=Dec 5 19:44:27
_PID=4108
_CMDLINE=./poc AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>
_SOURCE_REALTIME_TIMESTAMP=1544035467475848
$ journalctl -o export -n1 'MESSAGE=Something logged' --output-fields=_CMDLINE|wc
6 2053 2097410
2MB might be hard for some clients to use meaningfully, but OTOH, it is
important to log the full commandline sometimes. For example, when the program
is crashing, the exact argument list is useful.
(cherry-picked from commit 2d5d2e0cc5171c6795d2a485841474345d9e30ab)
Related: #1664976
---
src/basic/process-util.c | 73 ++++++++++++++--------------------------
1 file changed, 25 insertions(+), 48 deletions(-)
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 0a4f917cbd..a20f1e3ccf 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -128,6 +128,13 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
(void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+ if (max_length == 0) {
+ /* This is supposed to be a safety guard against runaway command lines. */
+ long l = sysconf(_SC_ARG_MAX);
+ assert(l > 0);
+ max_length = l;
+ }
+
if (max_length == 1) {
/* If there's only room for one byte, return the empty string */
@@ -138,32 +145,6 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
*line = ans;
return 0;
- } else if (max_length == 0) {
- size_t len = 0, allocated = 0;
-
- while ((c = getc(f)) != EOF) {
-
- if (!GREEDY_REALLOC(ans, allocated, len+3)) {
- free(ans);
- return -ENOMEM;
- }
-
- if (isprint(c)) {
- if (space) {
- ans[len++] = ' ';
- space = false;
- }
-
- ans[len++] = c;
- } else if (len > 0)
- space = true;
- }
-
- if (len > 0)
- ans[len] = '\0';
- else
- ans = mfree(ans);
-
} else {
bool dotdotdot = false;
size_t left;
@@ -235,34 +216,30 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
if (h < 0)
return h;
- if (max_length == 0)
- ans = strjoin("[", t, "]");
- else {
- size_t l;
-
- l = strlen(t);
+ size_t l = strlen(t);
- if (l + 3 <= max_length)
- ans = strjoin("[", t, "]");
- else if (max_length <= 6) {
+ if (l + 3 <= max_length) {
+ ans = strjoin("[", t, "]");
+ if (!ans)
+ return -ENOMEM;
- ans = new(char, max_length);
- if (!ans)
- return -ENOMEM;
+ } else if (max_length <= 6) {
+ ans = new(char, max_length);
+ if (!ans)
+ return -ENOMEM;
- memcpy(ans, "[...]", max_length-1);
- ans[max_length-1] = 0;
- } else {
- t[max_length - 6] = 0;
+ memcpy(ans, "[...]", max_length-1);
+ ans[max_length-1] = 0;
+ } else {
+ t[max_length - 6] = 0;
- /* Chop off final spaces */
- delete_trailing_chars(t, WHITESPACE);
+ /* Chop off final spaces */
+ delete_trailing_chars(t, WHITESPACE);
- ans = strjoin("[", t, "...]");
- }
+ ans = strjoin("[", t, "...]");
+ if (!ans)
+ return -ENOMEM;
}
- if (!ans)
- return -ENOMEM;
}
*line = ans;

@ -0,0 +1,33 @@
From 04326c02ca80666e66a5da8e6a46c2fc4476000c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 5 Dec 2018 21:34:24 +0100
Subject: [PATCH] coredump: fix message when we fail to save a journald
coredump
If creation of the message failed, we'd write a bogus entry:
systemd-coredump[1400]: Cannot store coredump of 416 (systemd-journal): No space left on device
systemd-coredump[1400]: MESSAGE=Process 416 (systemd-journal) of user 0 dumped core.
systemd-coredump[1400]: Coredump diverted to
(cherry-picked from commit f0136e09221364f931c3a3b715da4e4d3ee9f2ac)
Related: #1664976
---
src/coredump/coredump.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index ffa88f612d..2a130e8838 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -783,8 +783,8 @@ log:
core_message = strjoin("MESSAGE=Process ", context[CONTEXT_PID],
" (", context[CONTEXT_COMM], ") of user ",
context[CONTEXT_UID], " dumped core.",
- journald_crash ? "\nCoredump diverted to " : NULL,
- journald_crash ? filename : NULL);
+ journald_crash && filename ? "\nCoredump diverted to " : NULL,
+ journald_crash && filename ? filename : NULL);
if (!core_message)
return log_oom();

@ -0,0 +1,104 @@
From 60b831ef50e435b66ddd99e635a5112e121c7cb3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Tue, 22 Jan 2019 15:43:07 +0100
Subject: [PATCH] procfs-util: expose functionality to query total memory
procfs_memory_get_current is renamed to procfs_memory_get_used, because
"current" can mean anything, including total memory, used memory, and free
memory, as long as the value is up to date.
No functional change.
(cherry-picked from commit c482724aa5c5d0b1391fcf958a9a3ea6ce73a085)
Related: #1664976
---
src/basic/procfs-util.c | 9 +++++----
src/basic/procfs-util.h | 5 ++++-
src/cgtop/cgtop.c | 2 +-
src/core/cgroup.c | 2 +-
src/test/test-procfs-util.c | 2 +-
5 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/basic/procfs-util.c b/src/basic/procfs-util.c
index a159e344b3..7aaf95bfce 100644
--- a/src/basic/procfs-util.c
+++ b/src/basic/procfs-util.c
@@ -201,13 +201,11 @@ int procfs_cpu_get_usage(nsec_t *ret) {
return 0;
}
-int procfs_memory_get_current(uint64_t *ret) {
+int procfs_memory_get(uint64_t *ret_total, uint64_t *ret_used) {
uint64_t mem_total = UINT64_MAX, mem_free = UINT64_MAX;
_cleanup_fclose_ FILE *f = NULL;
int r;
- assert(ret);
-
f = fopen("/proc/meminfo", "re");
if (!f)
return -errno;
@@ -262,6 +260,9 @@ int procfs_memory_get_current(uint64_t *ret) {
if (mem_free > mem_total)
return -EINVAL;
- *ret = (mem_total - mem_free) * 1024U;
+ if (ret_total)
+ *ret_total = mem_total * 1024U;
+ if (ret_used)
+ *ret_used = (mem_total - mem_free) * 1024U;
return 0;
}
diff --git a/src/basic/procfs-util.h b/src/basic/procfs-util.h
index f697ed92bc..5a44e9eff7 100644
--- a/src/basic/procfs-util.h
+++ b/src/basic/procfs-util.h
@@ -11,4 +11,7 @@ int procfs_tasks_get_current(uint64_t *ret);
int procfs_cpu_get_usage(nsec_t *ret);
-int procfs_memory_get_current(uint64_t *ret);
+int procfs_memory_get(uint64_t *ret_total, uint64_t *ret_used);
+static inline int procfs_memory_get_used(uint64_t *ret) {
+ return procfs_memory_get(NULL, ret);
+}
diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c
index 8dda08ab4c..792b13a43d 100644
--- a/src/cgtop/cgtop.c
+++ b/src/cgtop/cgtop.c
@@ -297,7 +297,7 @@ static int process(
} else if (streq(controller, "memory")) {
if (is_root_cgroup(path)) {
- r = procfs_memory_get_current(&g->memory);
+ r = procfs_memory_get_used(&g->memory);
if (r < 0)
return r;
} else {
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index bb02436203..62ab41a288 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -2402,7 +2402,7 @@ int unit_get_memory_current(Unit *u, uint64_t *ret) {
/* The root cgroup doesn't expose this information, let's get it from /proc instead */
if (unit_has_root_cgroup(u))
- return procfs_memory_get_current(ret);
+ return procfs_memory_get_used(ret);
if ((u->cgroup_realized_mask & CGROUP_MASK_MEMORY) == 0)
return -ENODATA;
diff --git a/src/test/test-procfs-util.c b/src/test/test-procfs-util.c
index 08af380cc7..1d0612985b 100644
--- a/src/test/test-procfs-util.c
+++ b/src/test/test-procfs-util.c
@@ -18,7 +18,7 @@ int main(int argc, char *argv[]) {
assert_se(procfs_cpu_get_usage(&nsec) >= 0);
log_info("Current system CPU time: %s", format_timespan(buf, sizeof(buf), nsec/NSEC_PER_USEC, 1));
- assert_se(procfs_memory_get_current(&v) >= 0);
+ assert_se(procfs_memory_get_used(&v) >= 0);
log_info("Current memory usage: %s", format_bytes(buf, sizeof(buf), v));
assert_se(procfs_tasks_get_current(&v) >= 0);

@ -0,0 +1,114 @@
From ee14a2bd3d95b5d15e4d72ee2582b366e5009a86 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sat, 26 Jan 2019 11:27:18 +0100
Subject: [PATCH] basic/prioq: add prioq_peek_item()
(cherry-picked from commit ef21b3b5bf824e652addf850bcfd9374c7b33ce8)
Related: #1664976
---
src/basic/prioq.c | 7 +++----
src/basic/prioq.h | 8 +++++++-
src/test/test-prioq.c | 23 +++++++++++++++++------
3 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/src/basic/prioq.c b/src/basic/prioq.c
index ef28a086d1..0bf58c1f16 100644
--- a/src/basic/prioq.c
+++ b/src/basic/prioq.c
@@ -259,15 +259,14 @@ int prioq_reshuffle(Prioq *q, void *data, unsigned *idx) {
return 1;
}
-void *prioq_peek(Prioq *q) {
-
+void *prioq_peek_by_index(Prioq *q, unsigned idx) {
if (!q)
return NULL;
- if (q->n_items <= 0)
+ if (idx >= q->n_items)
return NULL;
- return q->items[0].data;
+ return q->items[idx].data;
}
void *prioq_pop(Prioq *q) {
diff --git a/src/basic/prioq.h b/src/basic/prioq.h
index e036175260..c381523525 100644
--- a/src/basic/prioq.h
+++ b/src/basic/prioq.h
@@ -18,8 +18,14 @@ int prioq_put(Prioq *q, void *data, unsigned *idx);
int prioq_remove(Prioq *q, void *data, unsigned *idx);
int prioq_reshuffle(Prioq *q, void *data, unsigned *idx);
-void *prioq_peek(Prioq *q) _pure_;
+void *prioq_peek_by_index(Prioq *q, unsigned idx) _pure_;
+static inline void *prioq_peek(Prioq *q) {
+ return prioq_peek_by_index(q, 0);
+}
void *prioq_pop(Prioq *q);
+#define PRIOQ_FOREACH_ITEM(q, p) \
+ for (unsigned _i = 0; (p = prioq_peek_by_index(q, _i)); _i++)
+
unsigned prioq_size(Prioq *q) _pure_;
bool prioq_isempty(Prioq *q) _pure_;
diff --git a/src/test/test-prioq.c b/src/test/test-prioq.c
index 89c41d8ce7..ece13808ed 100644
--- a/src/test/test-prioq.c
+++ b/src/test/test-prioq.c
@@ -87,6 +87,7 @@ static void test_struct(void) {
Set *s;
unsigned previous = 0, i;
int r;
+ struct test *t;
srand(0);
@@ -96,9 +97,12 @@ static void test_struct(void) {
s = set_new(&test_hash_ops);
assert_se(s);
- for (i = 0; i < SET_SIZE; i++) {
- struct test *t;
+ assert_se(prioq_peek(q) == NULL);
+ assert_se(prioq_peek_by_index(q, 0) == NULL);
+ assert_se(prioq_peek_by_index(q, 1) == NULL);
+ assert_se(prioq_peek_by_index(q, (unsigned) -1) == NULL);
+ for (i = 0; i < SET_SIZE; i++) {
t = new0(struct test, 1);
assert_se(t);
t->value = (unsigned) rand();
@@ -112,9 +116,18 @@ static void test_struct(void) {
}
}
- for (;;) {
- struct test *t;
+ for (i = 0; i < SET_SIZE; i++)
+ assert_se(prioq_peek_by_index(q, i));
+ assert_se(prioq_peek_by_index(q, SET_SIZE) == NULL);
+
+ unsigned count = 0;
+ PRIOQ_FOREACH_ITEM(q, t) {
+ assert_se(t);
+ count++;
+ }
+ assert_se(count == SET_SIZE);
+ for (;;) {
t = set_steal_first(s);
if (!t)
break;
@@ -126,8 +139,6 @@ static void test_struct(void) {
}
for (i = 0; i < SET_SIZE * 3 / 4; i++) {
- struct test *t;
-
assert_se(prioq_size(q) == (SET_SIZE * 3 / 4) - i);
t = prioq_pop(q);

@ -0,0 +1,81 @@
From de72fa6b0582b95216215cc1400412fe91bc8ba3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Tue, 22 Jan 2019 16:12:52 +0100
Subject: [PATCH] journal: limit the number of entries in the cache based on
available memory
This is far from perfect, but should give mostly reasonable values. My
assumption is that if somebody has a few hundred MB of memory, they are
unlikely to have thousands of processes logging. A hundred would already be a
lot. So let's scale the cache size propritionally to the total memory size,
with clamping on both ends.
The formula gives 64 cache entries for each GB of RAM.
(cherry-picked from commit b12a480829c5ca8f4d4fa9cde8716b5f2f12a3ad)
Related: #1664976
---
src/journal/journald-context.c | 35 ++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c
index ce07de1bfb..0f0dc1de4d 100644
--- a/src/journal/journald-context.c
+++ b/src/journal/journald-context.c
@@ -14,6 +14,7 @@
#include "journal-util.h"
#include "journald-context.h"
#include "process-util.h"
+#include "procfs-util.h"
#include "string-util.h"
#include "syslog-util.h"
#include "unaligned.h"
@@ -58,7 +59,37 @@
/* Keep at most 16K entries in the cache. (Note though that this limit may be violated if enough streams pin entries in
* the cache, in which case we *do* permit this limit to be breached. That's safe however, as the number of stream
* clients itself is limited.) */
-#define CACHE_MAX (16*1024)
+#define CACHE_MAX_FALLBACK 128U
+#define CACHE_MAX_MAX (16*1024U)
+#define CACHE_MAX_MIN 64U
+
+static size_t cache_max(void) {
+ static size_t cached = -1;
+
+ if (cached == (size_t) -1) {
+ uint64_t mem_total;
+ int r;
+
+ r = procfs_memory_get(&mem_total, NULL);
+ if (r < 0) {
+ log_warning_errno(r, "Cannot query /proc/meminfo for MemTotal: %m");
+ cached = CACHE_MAX_FALLBACK;
+ } else {
+ /* Cache entries are usually a few kB, but the process cmdline is controlled by the
+ * user and can be up to _SC_ARG_MAX, usually 2MB. Let's say that approximately up to
+ * 1/8th of memory may be used by the cache.
+ *
+ * In the common case, this formula gives 64 cache entries for each GB of RAM.
+ */
+ long l = sysconf(_SC_ARG_MAX);
+ assert(l > 0);
+
+ cached = CLAMP(mem_total / 8 / (uint64_t) l, CACHE_MAX_MIN, CACHE_MAX_MAX);
+ }
+ }
+
+ return cached;
+}
static int client_context_compare(const void *a, const void *b) {
const ClientContext *x = a, *y = b;
@@ -587,7 +618,7 @@ static int client_context_get_internal(
return 0;
}
- client_context_try_shrink_to(s, CACHE_MAX-1);
+ client_context_try_shrink_to(s, cache_max()-1);
r = client_context_new(s, pid, &c);
if (r < 0)

@ -0,0 +1,77 @@
From 8da81d2aba2768ced497790cc05b9f73c6268833 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Tue, 22 Jan 2019 17:30:48 +0100
Subject: [PATCH] journald: periodically drop cache for all dead PIDs
In normal use, this allow us to drop dead entries from the cache and reduces
the cache size so that we don't evict entries unnecessarily. The time limit is
there mostly to serve as a guard against malicious logging from many different
PIDs.
(cherry-picked from commit 91714a7f427a6c9c5c3be8b3819fee45050028f3)
Related: #1664976
---
src/journal/journald-context.c | 28 ++++++++++++++++++++++++++--
src/journal/journald-server.h | 2 ++
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c
index 0f0dc1de4d..51f79fd803 100644
--- a/src/journal/journald-context.c
+++ b/src/journal/journald-context.c
@@ -541,15 +541,39 @@ refresh:
}
static void client_context_try_shrink_to(Server *s, size_t limit) {
+ ClientContext *c;
+ usec_t t;
+
assert(s);
+ /* Flush any cache entries for PIDs that have already moved on. Don't do this
+ * too often, since it's a slow process. */
+ t = now(CLOCK_MONOTONIC);
+ if (s->last_cache_pid_flush + MAX_USEC < t) {
+ unsigned n = prioq_size(s->client_contexts_lru), idx = 0;
+
+ /* We do a number of iterations based on the initial size of the prioq. When we remove an
+ * item, a new item is moved into its places, and items to the right might be reshuffled.
+ */
+ for (unsigned i = 0; i < n; i++) {
+ c = prioq_peek_by_index(s->client_contexts_lru, idx);
+
+ assert(c->n_ref == 0);
+
+ if (!pid_is_unwaited(c->pid))
+ client_context_free(s, c);
+ else
+ idx ++;
+ }
+
+ s->last_cache_pid_flush = t;
+ }
+
/* Bring the number of cache entries below the indicated limit, so that we can create a new entry without
* breaching the limit. Note that we only flush out entries that aren't pinned here. This means the number of
* cache entries may very well grow beyond the limit, if all entries stored remain pinned. */
while (hashmap_size(s->client_contexts) > limit) {
- ClientContext *c;
-
c = prioq_pop(s->client_contexts_lru);
if (!c)
break; /* All remaining entries are pinned, give up */
diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
index 983be8bb89..c6c9b1fb1d 100644
--- a/src/journal/journald-server.h
+++ b/src/journal/journald-server.h
@@ -163,6 +163,8 @@ struct Server {
Hashmap *client_contexts;
Prioq *client_contexts_lru;
+ usec_t last_cache_pid_flush;
+
ClientContext *my_context; /* the context of journald itself */
ClientContext *pid1_context; /* the context of PID 1 */
};

@ -0,0 +1,71 @@
From 9b9b6d8c7b10c069d36f85bd17f144011282cb58 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Tue, 22 Jan 2019 14:29:50 +0100
Subject: [PATCH] process-util: don't use overly large buffer to store process
command line
Allocate new string as a return value and free our "scratch pad"
buffer that is potentially much larger than needed (up to
_SC_ARG_MAX).
Fixes #11502
(cherry-picked from commit eb1ec489eef8a32918bbfc56a268c9d10464584d)
Related: #1664976
---
src/basic/process-util.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index a20f1e3ccf..aa3eff779a 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -101,7 +101,8 @@ int get_process_comm(pid_t pid, char **ret) {
int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
_cleanup_fclose_ FILE *f = NULL;
bool space = false;
- char *k, *ans = NULL;
+ char *k;
+ _cleanup_free_ char *ans = NULL;
const char *p;
int c;
@@ -142,7 +143,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
if (!ans)
return -ENOMEM;
- *line = ans;
+ *line = TAKE_PTR(ans);
return 0;
} else {
@@ -207,7 +208,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
_cleanup_free_ char *t = NULL;
int h;
- free(ans);
+ ans = mfree(ans);
if (!comm_fallback)
return -ENOENT;
@@ -240,9 +241,18 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
if (!ans)
return -ENOMEM;
}
+
+ *line = TAKE_PTR(ans);
+ return 0;
}
- *line = ans;
+ k = realloc(ans, strlen(ans) + 1);
+ if (!k)
+ return -ENOMEM;
+
+ ans = NULL;
+ *line = k;
+
return 0;
}

@ -0,0 +1,26 @@
From 47b256d63ac092137fe44e27560a14ee4aa5b7c8 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Fri, 8 Feb 2019 10:54:34 +0100
Subject: [PATCH] Revert "sysctl.d: switch net.ipv4.conf.all.rp_filter from 1
to 2"
This reverts commit 75c9af80cf3529c76988451e63f98010c86f48f1.
Resolves: #1653824
---
sysctl.d/50-default.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf
index b0645f33e7..e263cf0628 100644
--- a/sysctl.d/50-default.conf
+++ b/sysctl.d/50-default.conf
@@ -22,7 +22,7 @@ kernel.sysrq = 16
kernel.core_uses_pid = 1
# Source route verification
-net.ipv4.conf.all.rp_filter = 2
+net.ipv4.conf.all.rp_filter = 1
# Do not accept source routing
net.ipv4.conf.all.accept_source_route = 0

@ -0,0 +1,68 @@
From d355618518f26bd045df81a52dade79ac3079f3f Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 8 Aug 2018 15:06:36 +0900
Subject: [PATCH] journal: fix syslog_parse_identifier()
Fixes #9829.
(cherry-picked from commit a6aadf4ae0bae185dc4c414d492a4a781c80ffe5)
Resolves: #1664978
---
src/journal/journald-syslog.c | 6 +++---
src/journal/test-journal-syslog.c | 10 ++++++++--
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 9dea116722..97711ac7a3 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -194,7 +194,7 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid)
e = l;
l--;
- if (p[l-1] == ']') {
+ if (l > 0 && p[l-1] == ']') {
size_t k = l-1;
for (;;) {
@@ -219,8 +219,8 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid)
if (t)
*identifier = t;
- if (strchr(WHITESPACE, p[e]))
- e++;
+ e += strspn(p + e, WHITESPACE);
+
*buf = p + e;
return e;
}
diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c
index 9ba86f6c8a..05f759817e 100644
--- a/src/journal/test-journal-syslog.c
+++ b/src/journal/test-journal-syslog.c
@@ -5,8 +5,8 @@
#include "macro.h"
#include "string-util.h"
-static void test_syslog_parse_identifier(const char* str,
- const char *ident, const char*pid, int ret) {
+static void test_syslog_parse_identifier(const char *str,
+ const char *ident, const char *pid, int ret) {
const char *buf = str;
_cleanup_free_ char *ident2 = NULL, *pid2 = NULL;
int ret2;
@@ -21,7 +21,13 @@ static void test_syslog_parse_identifier(const char* str,
int main(void) {
test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", 11);
test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 6);
+ test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 7);
test_syslog_parse_identifier("pidu xxx", NULL, NULL, 0);
+ test_syslog_parse_identifier(":", "", NULL, 1);
+ test_syslog_parse_identifier(": ", "", NULL, 3);
+ test_syslog_parse_identifier("pidu:", "pidu", NULL, 5);
+ test_syslog_parse_identifier("pidu: ", "pidu", NULL, 6);
+ test_syslog_parse_identifier("pidu : ", NULL, NULL, 0);
return 0;
}

@ -0,0 +1,54 @@
From 9f53d3cded6cf7eccb40c810dfb8fd6e101c7a3b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 5 Dec 2018 22:45:02 +0100
Subject: [PATCH] journald: set a limit on the number of fields (1k)
We allocate a iovec entry for each field, so with many short entries,
our memory usage and processing time can be large, even with a relatively
small message size. Let's refuse overly long entries.
CVE-2018-16865
https://bugzilla.redhat.com/show_bug.cgi?id=1653861
What from I can see, the problem is not from an alloca, despite what the CVE
description says, but from the attack multiplication that comes from creating
many very small iovecs: (void* + size_t) for each three bytes of input message.
(cherry-picked from commit 052c57f132f04a3cf4148f87561618da1a6908b4)
Resolves: #1664977
---
src/journal/journal-file.h | 3 +++
src/journal/journald-native.c | 5 +++++
2 files changed, 8 insertions(+)
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index c8114ee2d0..cd8a48a364 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -165,6 +165,9 @@ int journal_file_open_reliably(
* files without adding too many zeros. */
#define OFSfmt "%06"PRIx64
+/* The maximum number of fields in an entry */
+#define ENTRY_FIELD_COUNT_MAX 1024
+
static inline bool VALID_REALTIME(uint64_t u) {
/* This considers timestamps until the year 3112 valid. That should be plenty room... */
return u > 0 && u < (1ULL << 55);
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index 5ff22a10af..951d092053 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -140,6 +140,11 @@ static int server_process_entry(
}
/* A property follows */
+ if (n > ENTRY_FIELD_COUNT_MAX) {
+ log_debug("Received an entry that has more than " STRINGIFY(ENTRY_FIELD_COUNT_MAX) " fields, ignoring entry.");
+ r = 1;
+ goto finish;
+ }
/* n existing properties, 1 new, +1 for _TRANSPORT */
if (!GREEDY_REALLOC(iovec, m,

@ -0,0 +1,205 @@
From ed028441cc2ef0ffb9771d7266d40f18910f0ae1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 5 Dec 2018 22:50:39 +0100
Subject: [PATCH] journald: when processing a native message, bail more quickly
on overbig messages
We'd first parse all or most of the message, and only then consider if it
is not too large. Also, when encountering a single field over the limit,
we'd still process the preceding part of the message. Let's be stricter,
and check size limits early, and let's refuse the whole message if it fails
any of the size limits.
(cherry-picked from commit 964ef920ea6735d39f856b05fd8ef451a09a6a1d)
Related: #1664977
---
src/journal/journald-native.c | 65 ++++++++++++++++++++---------------
1 file changed, 37 insertions(+), 28 deletions(-)
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index 951d092053..110ab3641c 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -109,7 +109,7 @@ static int server_process_entry(
int priority = LOG_INFO;
pid_t object_pid = 0;
const char *p;
- int r = 0;
+ int r = 1;
p = buffer;
@@ -121,8 +121,7 @@ static int server_process_entry(
if (!e) {
/* Trailing noise, let's ignore it, and flush what we collected */
log_debug("Received message with trailing noise, ignoring.");
- r = 1; /* finish processing of the message */
- break;
+ break; /* finish processing of the message */
}
if (e == p) {
@@ -132,8 +131,7 @@ static int server_process_entry(
}
if (IN_SET(*p, '.', '#')) {
- /* Ignore control commands for now, and
- * comments too. */
+ /* Ignore control commands for now, and comments too. */
*remaining -= (e - p) + 1;
p = e + 1;
continue;
@@ -142,7 +140,6 @@ static int server_process_entry(
/* A property follows */
if (n > ENTRY_FIELD_COUNT_MAX) {
log_debug("Received an entry that has more than " STRINGIFY(ENTRY_FIELD_COUNT_MAX) " fields, ignoring entry.");
- r = 1;
goto finish;
}
@@ -152,7 +149,7 @@ static int server_process_entry(
N_IOVEC_META_FIELDS + N_IOVEC_OBJECT_FIELDS +
client_context_extra_fields_n_iovec(context))) {
r = log_oom();
- break;
+ goto finish;
}
q = memchr(p, '=', e - p);
@@ -161,6 +158,16 @@ static int server_process_entry(
size_t l;
l = e - p;
+ if (l > DATA_SIZE_MAX) {
+ log_debug("Received text block of %zu bytes is too large, ignoring entry.", l);
+ goto finish;
+ }
+
+ if (entry_size + l + n + 1 > ENTRY_SIZE_MAX) { /* data + separators + trailer */
+ log_debug("Entry is too big (%zu bytes after processing %zu entries), ignoring entry.",
+ entry_size + l, n + 1);
+ goto finish;
+ }
/* If the field name starts with an underscore, skip the variable, since that indicates
* a trusted field */
@@ -178,7 +185,7 @@ static int server_process_entry(
p = e + 1;
continue;
} else {
- uint64_t l;
+ uint64_t l, total;
char *k;
if (*remaining < e - p + 1 + sizeof(uint64_t) + 1) {
@@ -187,10 +194,16 @@ static int server_process_entry(
}
l = unaligned_read_le64(e + 1);
-
if (l > DATA_SIZE_MAX) {
- log_debug("Received binary data block of %"PRIu64" bytes is too large, ignoring.", l);
- break;
+ log_debug("Received binary data block of %"PRIu64" bytes is too large, ignoring entry.", l);
+ goto finish;
+ }
+
+ total = (e - p) + 1 + l;
+ if (entry_size + total + n + 1 > ENTRY_SIZE_MAX) { /* data + separators + trailer */
+ log_debug("Entry is too big (%"PRIu64"bytes after processing %zu fields), ignoring.",
+ entry_size + total, n + 1);
+ goto finish;
}
if ((uint64_t) *remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
@@ -199,7 +212,7 @@ static int server_process_entry(
break;
}
- k = malloc((e - p) + 1 + l);
+ k = malloc(total);
if (!k) {
log_oom();
break;
@@ -228,15 +241,8 @@ static int server_process_entry(
}
}
- if (n <= 0) {
- r = 1;
+ if (n <= 0)
goto finish;
- }
-
- if (!client_context_test_priority(context, priority)) {
- r = 0;
- goto finish;
- }
tn = n++;
iovec[tn] = IOVEC_MAKE_STRING("_TRANSPORT=journal");
@@ -247,6 +253,11 @@ static int server_process_entry(
goto finish;
}
+ r = 0; /* Success, we read the message. */
+
+ if (!client_context_test_priority(context, priority))
+ goto finish;
+
if (message) {
if (s->forward_to_syslog)
server_forward_syslog(s, syslog_fixup_facility(priority), identifier, message, ucred, tv);
@@ -318,15 +329,13 @@ void server_process_native_file(
bool sealed;
int r;
- /* Data is in the passed fd, since it didn't fit in a
- * datagram. */
+ /* Data is in the passed fd, probably it didn't fit in a datagram. */
assert(s);
assert(fd >= 0);
/* If it's a memfd, check if it is sealed. If so, we can just
- * use map it and use it, and do not need to copy the data
- * out. */
+ * mmap it and use it, and do not need to copy the data out. */
sealed = memfd_get_sealed(fd) > 0;
if (!sealed && (!ucred || ucred->uid != 0)) {
@@ -397,7 +406,7 @@ void server_process_native_file(
ssize_t n;
if (fstatvfs(fd, &vfs) < 0) {
- log_error_errno(errno, "Failed to stat file system of passed file, ignoring: %m");
+ log_error_errno(errno, "Failed to stat file system of passed file, not processing it: %m");
return;
}
@@ -407,7 +416,7 @@ void server_process_native_file(
* https://github.com/systemd/systemd/issues/1822
*/
if (vfs.f_flag & ST_MANDLOCK) {
- log_error("Received file descriptor from file system with mandatory locking enabled, refusing.");
+ log_error("Received file descriptor from file system with mandatory locking enabled, not processing it.");
return;
}
@@ -420,13 +429,13 @@ void server_process_native_file(
* and so is SMB. */
r = fd_nonblock(fd, true);
if (r < 0) {
- log_error_errno(r, "Failed to make fd non-blocking, ignoring: %m");
+ log_error_errno(r, "Failed to make fd non-blocking, not processing it: %m");
return;
}
/* The file is not sealed, we can't map the file here, since
* clients might then truncate it and trigger a SIGBUS for
- * us. So let's stupidly read it */
+ * us. So let's stupidly read it. */
p = malloc(st.st_size);
if (!p) {

@ -0,0 +1,37 @@
From a4d1779b5ee28b1c27c509a1baebf881943cad1b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 5 Dec 2018 22:52:53 +0100
Subject: [PATCH] =?UTF-8?q?journald:=20lower=20the=20maximum=20entry=20siz?=
=?UTF-8?q?e=20limit=20to=20=C2=BD=20for=20non-sealed=20fds?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We immediately read the whole contents into memory, making thigs much more
expensive. Sealed fds should be used instead since they are more efficient
on our side.
(cherry-picked from commit 6670c9de196c8e2d5e84a8890cbb68f70c4db6e3)
Related: #1664977
---
src/journal/journald-native.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
index 110ab3641c..da62448ca6 100644
--- a/src/journal/journald-native.c
+++ b/src/journal/journald-native.c
@@ -380,8 +380,10 @@ void server_process_native_file(
if (st.st_size <= 0)
return;
- if (st.st_size > ENTRY_SIZE_MAX) {
- log_error("File passed too large. Ignoring.");
+ /* When !sealed, set a lower memory limit. We have to read the file,
+ * effectively doubling memory use. */
+ if (st.st_size > ENTRY_SIZE_MAX / (sealed ? 1 : 2)) {
+ log_error("File passed too large (%"PRIu64" bytes). Ignoring.", (uint64_t) st.st_size);
return;
}

@ -0,0 +1,198 @@
From c9290315ce840ed1001b897220f3f733811ffc66 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Fri, 7 Dec 2018 12:13:10 +0100
Subject: [PATCH] =?UTF-8?q?=C2=B5httpd:=20use=20a=20cleanup=20function=20t?=
=?UTF-8?q?o=20call=20MHD=5Fdestroy=5Fresponse?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
(cherry-picked from commit d101fb24eb1c58c97f2adce1f69f4b61a788933a)
Related: #1664977
---
src/journal-remote/journal-gatewayd.c | 53 +++++++--------------------
src/journal-remote/microhttpd-util.c | 11 ++----
src/journal-remote/microhttpd-util.h | 2 +
3 files changed, 19 insertions(+), 47 deletions(-)
diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c
index 9e77e314ff..3a167ab890 100644
--- a/src/journal-remote/journal-gatewayd.c
+++ b/src/journal-remote/journal-gatewayd.c
@@ -451,7 +451,7 @@ static int request_handler_entries(
struct MHD_Connection *connection,
void *connection_cls) {
- struct MHD_Response *response;
+ _cleanup_(MHD_destroy_responsep) struct MHD_Response *response = NULL;
RequestMeta *m = connection_cls;
int r;
@@ -493,11 +493,7 @@ static int request_handler_entries(
return respond_oom(connection);
MHD_add_response_header(response, "Content-Type", mime_types[m->mode]);
-
- r = MHD_queue_response(connection, MHD_HTTP_OK, response);
- MHD_destroy_response(response);
-
- return r;
+ return MHD_queue_response(connection, MHD_HTTP_OK, response);
}
static int output_field(FILE *f, OutputMode m, const char *d, size_t l) {
@@ -609,7 +605,7 @@ static int request_handler_fields(
const char *field,
void *connection_cls) {
- struct MHD_Response *response;
+ _cleanup_(MHD_destroy_responsep) struct MHD_Response *response = NULL;
RequestMeta *m = connection_cls;
int r;
@@ -632,11 +628,7 @@ static int request_handler_fields(
return respond_oom(connection);
MHD_add_response_header(response, "Content-Type", mime_types[m->mode == OUTPUT_JSON ? OUTPUT_JSON : OUTPUT_SHORT]);
-
- r = MHD_queue_response(connection, MHD_HTTP_OK, response);
- MHD_destroy_response(response);
-
- return r;
+ return MHD_queue_response(connection, MHD_HTTP_OK, response);
}
static int request_handler_redirect(
@@ -644,8 +636,7 @@ static int request_handler_redirect(
const char *target) {
char *page;
- struct MHD_Response *response;
- int ret;
+ _cleanup_(MHD_destroy_responsep) struct MHD_Response *response = NULL;
assert(connection);
assert(target);
@@ -661,11 +652,7 @@ static int request_handler_redirect(
MHD_add_response_header(response, "Content-Type", "text/html");
MHD_add_response_header(response, "Location", target);
-
- ret = MHD_queue_response(connection, MHD_HTTP_MOVED_PERMANENTLY, response);
- MHD_destroy_response(response);
-
- return ret;
+ return MHD_queue_response(connection, MHD_HTTP_MOVED_PERMANENTLY, response);
}
static int request_handler_file(
@@ -673,8 +660,7 @@ static int request_handler_file(
const char *path,
const char *mime_type) {
- struct MHD_Response *response;
- int ret;
+ _cleanup_(MHD_destroy_responsep) struct MHD_Response *response = NULL;
_cleanup_close_ int fd = -1;
struct stat st;
@@ -692,15 +678,10 @@ static int request_handler_file(
response = MHD_create_response_from_fd_at_offset64(st.st_size, fd, 0);
if (!response)
return respond_oom(connection);
-
- fd = -1;
+ TAKE_FD(fd);
MHD_add_response_header(response, "Content-Type", mime_type);
-
- ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
- MHD_destroy_response(response);
-
- return ret;
+ return MHD_queue_response(connection, MHD_HTTP_OK, response);
}
static int get_virtualization(char **v) {
@@ -737,14 +718,13 @@ static int request_handler_machine(
struct MHD_Connection *connection,
void *connection_cls) {
- struct MHD_Response *response;
+ _cleanup_(MHD_destroy_responsep) struct MHD_Response *response = NULL;
RequestMeta *m = connection_cls;
int r;
_cleanup_free_ char* hostname = NULL, *os_name = NULL;
uint64_t cutoff_from = 0, cutoff_to = 0, usage = 0;
- char *json;
sd_id128_t mid, bid;
- _cleanup_free_ char *v = NULL;
+ _cleanup_free_ char *v = NULL, *json = NULL;
assert(connection);
assert(m);
@@ -793,21 +773,16 @@ static int request_handler_machine(
usage,
cutoff_from,
cutoff_to);
-
if (r < 0)
return respond_oom(connection);
response = MHD_create_response_from_buffer(strlen(json), json, MHD_RESPMEM_MUST_FREE);
- if (!response) {
- free(json);
+ if (!response)
return respond_oom(connection);
- }
+ TAKE_PTR(json);
MHD_add_response_header(response, "Content-Type", "application/json");
- r = MHD_queue_response(connection, MHD_HTTP_OK, response);
- MHD_destroy_response(response);
-
- return r;
+ return MHD_queue_response(connection, MHD_HTTP_OK, response);
}
static int request_handler(
diff --git a/src/journal-remote/microhttpd-util.c b/src/journal-remote/microhttpd-util.c
index 34dd9ea555..2ae5172fe9 100644
--- a/src/journal-remote/microhttpd-util.c
+++ b/src/journal-remote/microhttpd-util.c
@@ -32,21 +32,16 @@ static int mhd_respond_internal(struct MHD_Connection *connection,
const char *buffer,
size_t size,
enum MHD_ResponseMemoryMode mode) {
- struct MHD_Response *response;
- int r;
-
assert(connection);
- response = MHD_create_response_from_buffer(size, (char*) buffer, mode);
+ _cleanup_(MHD_destroy_responsep) struct MHD_Response *response
+ = MHD_create_response_from_buffer(size, (char*) buffer, mode);
if (!response)
return MHD_NO;
log_debug("Queueing response %u: %s", code, buffer);
MHD_add_response_header(response, "Content-Type", "text/plain");
- r = MHD_queue_response(connection, code, response);
- MHD_destroy_response(response);
-
- return r;
+ return MHD_queue_response(connection, code, response);
}
int mhd_respond(struct MHD_Connection *connection,
diff --git a/src/journal-remote/microhttpd-util.h b/src/journal-remote/microhttpd-util.h
index a50a2a75c7..26909082a1 100644
--- a/src/journal-remote/microhttpd-util.h
+++ b/src/journal-remote/microhttpd-util.h
@@ -73,3 +73,5 @@ int check_permissions(struct MHD_Connection *connection, int *code, char **hostn
* interesting events without overwhelming detail.
*/
int setup_gnutls_logger(char **categories);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct MHD_Response*, MHD_destroy_response);

@ -0,0 +1,109 @@
From ad18012c46724aa097f37015a8036a4343206efe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Fri, 7 Dec 2018 12:47:14 +0100
Subject: [PATCH] journal-remote: verify entry length from header
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Calling mhd_respond(), which ulimately calls MHD_queue_response() is
ineffective at point, becuase MHD_queue_response() immediately returns
MHD_NO signifying an error, because the connection is in state
MHD_CONNECTION_CONTINUE_SENT.
As Christian Grothoff kindly explained:
> You are likely calling MHD_queue_repsonse() too late: once you are
> receiving upload_data, HTTP forces you to process it all. At this time,
> MHD has already sent "100 continue" and cannot take it back (hence you
> get MHD_NO!).
>
> In your request handler, the first time when you are called for a
> connection (and when hence *upload_data_size == 0 and upload_data ==
> NULL) you must check the content-length header and react (with
> MHD_queue_response) based on this (to prevent MHD from automatically
> generating 100 continue).
If we ever encounter this kind of error, print a warning and immediately
abort the connection. (The alternative would be to keep reading the data,
but ignore it, and return an error after we get to the end of data.
That is possible, but of course puts additional load on both the
sender and reciever, and doesn't seem important enough just to return
a good error message.)
Note that sending of the error does not work (the connection is always aborted
when MHD_queue_response is used with MHD_RESPMEM_MUST_FREE, as in this case)
with libµhttpd 0.59, but works with 0.61:
https://src.fedoraproject.org/rpms/libmicrohttpd/pull-request/1
(cherry-picked from commit 7fdb237f5473cb8fc2129e57e8a0039526dcb4fd)
Related: #1664977
---
src/journal-remote/journal-remote-main.c | 34 +++++++++++++++++-------
1 file changed, 24 insertions(+), 10 deletions(-)
diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c
index 8fda9d1499..e9b3702e8a 100644
--- a/src/journal-remote/journal-remote-main.c
+++ b/src/journal-remote/journal-remote-main.c
@@ -210,16 +210,14 @@ static int process_http_upload(
journal_remote_server_global->seal);
if (r == -EAGAIN)
break;
- else if (r < 0) {
- log_warning("Failed to process data for connection %p", connection);
+ if (r < 0) {
if (r == -E2BIG)
- return mhd_respondf(connection,
- r, MHD_HTTP_PAYLOAD_TOO_LARGE,
- "Entry is too large, maximum is " STRINGIFY(DATA_SIZE_MAX) " bytes.");
+ log_warning_errno(r, "Entry is too above maximum of %u, aborting connection %p.",
+ DATA_SIZE_MAX, connection);
else
- return mhd_respondf(connection,
- r, MHD_HTTP_UNPROCESSABLE_ENTITY,
- "Processing failed: %m.");
+ log_warning_errno(r, "Failed to process data, aborting connection %p: %m",
+ connection);
+ return MHD_NO;
}
}
@@ -253,6 +251,7 @@ static int request_handler(
const char *header;
int r, code, fd;
_cleanup_free_ char *hostname = NULL;
+ size_t len;
assert(connection);
assert(connection_cls);
@@ -272,12 +271,27 @@ static int request_handler(
if (!streq(url, "/upload"))
return mhd_respond(connection, MHD_HTTP_NOT_FOUND, "Not found.");
- header = MHD_lookup_connection_value(connection,
- MHD_HEADER_KIND, "Content-Type");
+ header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-Type");
if (!header || !streq(header, "application/vnd.fdo.journal"))
return mhd_respond(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE,
"Content-Type: application/vnd.fdo.journal is required.");
+ header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-Length");
+ if (!header)
+ return mhd_respond(connection, MHD_HTTP_LENGTH_REQUIRED,
+ "Content-Length header is required.");
+ r = safe_atozu(header, &len);
+ if (r < 0)
+ return mhd_respondf(connection, r, MHD_HTTP_LENGTH_REQUIRED,
+ "Content-Length: %s cannot be parsed: %m", header);
+
+ if (len > ENTRY_SIZE_MAX)
+ /* When serialized, an entry of maximum size might be slightly larger,
+ * so this does not correspond exactly to the limit in journald. Oh well.
+ */
+ return mhd_respondf(connection, 0, MHD_HTTP_PAYLOAD_TOO_LARGE,
+ "Payload larger than maximum size of %u bytes", ENTRY_SIZE_MAX);
+
{
const union MHD_ConnectionInfo *ci;

@ -0,0 +1,56 @@
From fde3fa3e9c0330c7de645ce2140f9dd39640a693 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Fri, 7 Dec 2018 10:48:10 +0100
Subject: [PATCH] journal-remote: set a limit on the number of fields in a
message
Existing use of E2BIG is replaced with ENOBUFS (entry too long), and E2BIG is
reused for the new error condition (too many fields).
This matches the change done for systemd-journald, hence forming the second
part of the fix for CVE-2018-16865
(https://bugzilla.redhat.com/show_bug.cgi?id=1653861).
(cherry-picked from commit ef4d6abe7c7fab6cbff975b32e76b09feee56074)
Resolves: #1664977
---
src/journal-remote/journal-remote-main.c | 7 +++++--
src/journal-remote/journal-remote.c | 5 ++++-
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c
index e9b3702e8a..5b0bbba310 100644
--- a/src/journal-remote/journal-remote-main.c
+++ b/src/journal-remote/journal-remote-main.c
@@ -211,9 +211,12 @@ static int process_http_upload(
if (r == -EAGAIN)
break;
if (r < 0) {
- if (r == -E2BIG)
- log_warning_errno(r, "Entry is too above maximum of %u, aborting connection %p.",
+ if (r == -ENOBUFS)
+ log_warning_errno(r, "Entry is above the maximum of %u, aborting connection %p.",
DATA_SIZE_MAX, connection);
+ else if (r == -E2BIG)
+ log_warning_errno(r, "Entry with more fields than the maximum of %u, aborting connection %p.",
+ ENTRY_FIELD_COUNT_MAX, connection);
else
log_warning_errno(r, "Failed to process data, aborting connection %p: %m",
connection);
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index beb75a1cb4..67e3a70c06 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -408,7 +408,10 @@ int journal_remote_handle_raw_source(
log_debug("%zu active sources remaining", s->active);
return 0;
} else if (r == -E2BIG) {
- log_notice_errno(E2BIG, "Entry too big, skipped");
+ log_notice("Entry with too many fields, skipped");
+ return 1;
+ } else if (r == -ENOBUFS) {
+ log_notice("Entry too big, skipped");
return 1;
} else if (r == -EAGAIN) {
return 0;

@ -0,0 +1,54 @@
From 7c52627446e32df64ad4cd3ac56ad515d0233cea Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Fri, 14 Dec 2018 15:17:27 +0100
Subject: [PATCH] journald: correctly attribute log messages also with
cgroupsv1
With cgroupsv1 a zombie process is migrated to root cgroup in all
hierarchies. This was changed for unified hierarchy and /proc/PID/cgroup
reports cgroup to which process belonged before it exited.
Be more suspicious about cgroup path reported by the kernel and use
unit_id provided by the log client if the kernel reports that process is
running in the root cgroup.
Users tend to care the most about 'log->unit_id' mapping so systemctl
status can correctly report last log lines. Also we wouldn't be able to
infer anything useful from "/" path anyway.
See: https://github.com/torvalds/linux/commit/2e91fa7f6d451e3ea9fec999065d2fd199691f9d
(cherry picked from commit 672773b63a4ebf95242b27e63071b93073ebc1f5)
Resolves: #1658115
---
src/journal/journald-context.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c
index 51f79fd803..dba3525ed8 100644
--- a/src/journal/journald-context.c
+++ b/src/journal/journald-context.c
@@ -13,6 +13,8 @@
#include "io-util.h"
#include "journal-util.h"
#include "journald-context.h"
+#include "parse-util.h"
+#include "path-util.h"
#include "process-util.h"
#include "procfs-util.h"
#include "string-util.h"
@@ -281,9 +283,11 @@ static int client_context_read_cgroup(Server *s, ClientContext *c, const char *u
/* Try to acquire the current cgroup path */
r = cg_pid_get_path_shifted(c->pid, s->cgroup_root, &t);
- if (r < 0) {
+ if (r < 0 || empty_or_root(t)) {
- /* If that didn't work, we use the unit ID passed in as fallback, if we have nothing cached yet */
+ /* We use the unit ID passed in as fallback if we have nothing cached yet and cg_pid_get_path_shifted()
+ * failed or process is running in a root cgroup. Zombie processes are automatically migrated to root cgroup
+ * on cgroupsv1 and we want to be able to map log messages from them too. */
if (unit_id && !c->unit) {
c->unit = strdup(unit_id);
if (c->unit)

@ -0,0 +1,50 @@
From bf7631e7c0a7d1cac2f071ce998d5c669aa5abd7 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Tue, 29 Jan 2019 19:33:15 +0100
Subject: [PATCH] test: replace echo with socat
The original version of the test used netcat along with a standard
AF_UNIX socket, which caused issues across different netcat
implementations. The AF_UNIX socket was then replaced by a FIFO with a
simple echo, which, however, suffers from the same issue (some echo
implementations don't check if the write() was successful).
Let's revert back to the AF_UNIX socket, but replace netcat with socat,
which, hopefully, resolves the main issue.
Relevant commit: 9b45c2bf02a43e3e1b42de1ab0c3fe29c64dc5f5
(cherry picked from commit b35d6d828b3216d022e565820d9971cb0f7746c1)
---
test/TEST-10-ISSUE-2467/test.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/test/TEST-10-ISSUE-2467/test.sh b/test/TEST-10-ISSUE-2467/test.sh
index e61f5acd3c..0e61236686 100755
--- a/test/TEST-10-ISSUE-2467/test.sh
+++ b/test/TEST-10-ISSUE-2467/test.sh
@@ -17,7 +17,7 @@ test_setup() {
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
- dracut_install true rm
+ dracut_install true rm socat
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<'EOF'
@@ -29,13 +29,13 @@ After=multi-user.target
Type=oneshot
StandardOutput=tty
StandardError=tty
-ExecStart=/bin/sh -e -x -c 'rm -f /tmp/nonexistent; systemctl start test.socket; echo > /run/test.ctl; >/testok'
+ExecStart=/bin/sh -e -x -c 'rm -f /tmp/nonexistent; systemctl start test.socket; printf x > test.file; socat -t20 OPEN:test.file UNIX-CONNECT:/run/test.ctl; >/testok'
TimeoutStartSec=10s
EOF
cat >$initdir/etc/systemd/system/test.socket <<'EOF'
[Socket]
-ListenFIFO=/run/test.ctl
+ListenStream=/run/test.ctl
EOF
cat > $initdir/etc/systemd/system/test.service <<'EOF'

@ -0,0 +1,25 @@
From ce123e87018b0345f1027950397f8556bfabb622 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 6 Feb 2019 12:02:15 +0100
Subject: [PATCH] test-network: ignore tunnel devices automatically added by
kernel
Fixes #10934.
(cherry picked from commit e327272d795453f68a4c30ba21eb0e887516cf68)
---
test/test-execute/exec-privatenetwork-yes.service | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/test-execute/exec-privatenetwork-yes.service b/test/test-execute/exec-privatenetwork-yes.service
index a38d24912f..8f5cbadf04 100644
--- a/test/test-execute/exec-privatenetwork-yes.service
+++ b/test/test-execute/exec-privatenetwork-yes.service
@@ -2,6 +2,6 @@
Description=Test for PrivateNetwork
[Service]
-ExecStart=/bin/sh -x -c '! ip link | grep ": " | grep -Ev ": (lo|sit0@.*):"'
+ExecStart=/bin/sh -x -c '! ip link | grep -E "^[0-9]+: " | grep -Ev ": (lo|(erspan|gre|gretap|ip_vti|ip6_vti|ip6gre|ip6tnl|sit|tunl)0@.*):"'
Type=oneshot
PrivateNetwork=yes

@ -0,0 +1,42 @@
From 1255584bb0a595fb555af7e14230ab1b7aa6adcd Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Tue, 12 Feb 2019 16:58:16 +0100
Subject: [PATCH] rules: add elevator= kernel command line parameter
Kernel removed the elevator= option, so let's reintroduce
it for rhel8 via udev rule.
rhel-only
Resolves: #1670126
---
rules/40-elevator.rules | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
create mode 100644 rules/40-elevator.rules
diff --git a/rules/40-elevator.rules b/rules/40-elevator.rules
new file mode 100644
index 0000000000..dbe8fc81a4
--- /dev/null
+++ b/rules/40-elevator.rules
@@ -0,0 +1,20 @@
+# We aren't adding devices skip the elevator check
+ACTION!="add", GOTO="sched_out"
+
+SUBSYSTEM!="block", GOTO="sched_out"
+ENV{DEVTYPE}!="disk", GOTO="sched_out"
+
+# Technically, dm-multipath can be configured to use an I/O scheduler.
+# However, there are races between the 'add' uevent and the linking in
+# of the queue/scheduler sysfs file. For now, just skip dm- devices.
+KERNEL=="dm-*|md*", GOTO="sched_out"
+
+# Skip bio-based devices, which don't support an I/O scheduler.
+ATTR{queue/scheduler}=="none", GOTO="sched_out"
+
+# If elevator= is specified on the kernel command line, change the
+# scheduler to the one specified.
+IMPORT{cmdline}="elevator"
+ENV{elevator}!="", ATTR{queue/scheduler}="$env{elevator}"
+
+LABEL="sched_out"
\ No newline at end of file

@ -0,0 +1,33 @@
From 1dd326b6dd0a23d1a9ee1c567962c6d5d4ef03ca Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Wed, 30 Jan 2019 12:22:41 +0100
Subject: [PATCH] rule-syntax-check: allow PROGRAM as an assignment
(cherry picked from commit ed2dc503da57b0110819563e0d1c85d023435e07)
---
test/rule-syntax-check.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py
index 706d93632e..c7c0a1a656 100755
--- a/test/rule-syntax-check.py
+++ b/test/rule-syntax-check.py
@@ -17,6 +17,8 @@ if not rules_files:
quoted_string_re = r'"(?:[^\\"]|\\.)*"'
no_args_tests = re.compile(r'(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|PROGRAM|RESULT|TEST)\s*(?:=|!)=\s*' + quoted_string_re + '$')
+# PROGRAM can also be specified as an assignment.
+program_assign = re.compile(r'PROGRAM\s*=\s*' + quoted_string_re + '$')
args_tests = re.compile(r'(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$')
no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|WAIT_FOR|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$')
args_assign = re.compile(r'(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*' + quoted_string_re + '$')
@@ -51,7 +53,8 @@ for path in rules_files:
for clause_match in comma_separated_group_re.finditer(line):
clause = clause_match.group().strip()
if not (no_args_tests.match(clause) or args_tests.match(clause) or
- no_args_assign.match(clause) or args_assign.match(clause)):
+ no_args_assign.match(clause) or args_assign.match(clause) or
+ program_assign.match(clause)):
print('Invalid line {}:{}: {}'.format(path, lineno, line))
print(' clause:', clause)

@ -0,0 +1,50 @@
From c95026c6979bb6f8dc52a6392318bc16615ace77 Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Wed, 30 Jan 2019 10:36:53 +0100
Subject: [PATCH] rules: implement new memory hotplug policy
Our new policy is based on following motivations (assumptions),
* we want to allow the system to use hotplugged memory
* we want memory ballon inflation to work as expected in VMs (going for small
to big in terms of memory footprint)
* we want to allow memory hotplug and memory hot-unplug on high-end
enterprise server (we assume that node0 will have sufficient memory
resources and marking all memory as movable shouldn't be a problem)
Policy:
* nevert online memory on s390 (on both physical and z/VM)
* mark memory as "online_movable" on physical machines
* mark memory as "online" in VMs
If you have the feeling that all this is very wrong and we shouldn't
encode complex policies in udev rules you are absolutely right. However,
for now, we don't have any better place where to put it. In ideal world
we would have a user-space daemon that would be able to configure the
system wrt. to currently present HW and user-defined policy.
Resolves: #1670728
---
rules/40-redhat.rules | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 8ac96933c3..17b33682bd 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -4,7 +4,15 @@
SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
# Memory hotadd request
-SUBSYSTEM=="memory", ACTION=="add", PROGRAM=="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online"
+SUBSYSTEM!="memory", GOTO="memory_hotplug_end"
+ACTION!="add", GOTO="memory_hotplug_end"
+PROGRAM="/bin/uname -p", RESULT=="s390*", GOTO="memory_hotplug_end"
+
+ENV{.state}="online"
+PROGRAM="/bin/systemd-detect-virt", RESULT=="none", ENV{.state}="online_movable"
+ATTR{state}=="offline", ATTR{state}="$env{.state}"
+
+LABEL="memory_hotplug_end"
# reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"

@ -0,0 +1,27 @@
From 9123fecee040fc961905f5c2e56152443907015a Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 24 Jul 2018 01:37:29 +0900
Subject: [PATCH] LGTM: make LGTM.com use meson from pip
(cherry picked from commit 55d651d8f69919b98cdc062e312e4454c34428ef)
---
.lgtm.yml | 10 ++++++++++
1 file changed, 10 insertions(+)
create mode 100644 .lgtm.yml
diff --git a/.lgtm.yml b/.lgtm.yml
new file mode 100644
index 0000000000..37f9c4335c
--- /dev/null
+++ b/.lgtm.yml
@@ -0,0 +1,10 @@
+extraction:
+ cpp:
+ prepare:
+ packages:
+ - python3-pip
+ - python3-setuptools
+ - python3-wheel
+ after_prepare:
+ - pip3 install meson
+ - export PATH="$HOME/.local/bin/:$PATH"

@ -0,0 +1,21 @@
From dbb6c3db4a9e38dd13525b073b2de1b5eac0ef7d Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sat, 8 Dec 2018 20:51:56 +0900
Subject: [PATCH] lgtm: use python3
(cherry picked from commit fc1c09e1dfd2073fb49c4e7bb87102c88a551876)
---
.lgtm.yml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.lgtm.yml b/.lgtm.yml
index 37f9c4335c..5948d8c2bc 100644
--- a/.lgtm.yml
+++ b/.lgtm.yml
@@ -8,3 +8,6 @@ extraction:
after_prepare:
- pip3 install meson
- export PATH="$HOME/.local/bin/:$PATH"
+ python:
+ python_setup:
+ version: 3

@ -0,0 +1,73 @@
From 5adeea95a7310d97b98821322b51794a46199417 Mon Sep 17 00:00:00 2001
From: Lucas Werkmeister <mail@lucaswerkmeister.de>
Date: Sat, 25 Aug 2018 18:41:42 +0200
Subject: [PATCH] tools: use print function in Python 3 code
This GDB script was converted to use Python 3 along with all other
Python scripts in commit b95f5528cc, but still used the Python 2 print
statement syntax instead of the Python 3 print function. Fix that.
We also add the Python 2 compatibility statement, just in case some GDB
still uses Python 2 instead of Python 3.
---
tools/gdb-sd_dump_hashmaps.py | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/tools/gdb-sd_dump_hashmaps.py b/tools/gdb-sd_dump_hashmaps.py
index e6ddd14ea7..ea15160107 100644
--- a/tools/gdb-sd_dump_hashmaps.py
+++ b/tools/gdb-sd_dump_hashmaps.py
@@ -2,6 +2,8 @@
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
# SPDX-License-Identifier: LGPL-2.1+
+from __future__ import print_function
+
import gdb
class sd_dump_hashmaps(gdb.Command):
@@ -19,7 +21,7 @@ class sd_dump_hashmaps(gdb.Command):
ulong_t = gdb.lookup_type("unsigned long")
debug_offset = gdb.parse_and_eval("(unsigned long)&((HashmapBase*)0)->debug")
- print "type, hash, indirect, entries, max_entries, buckets, creator"
+ print("type, hash, indirect, entries, max_entries, buckets, creator")
while d:
h = gdb.parse_and_eval("(HashmapBase*)((char*)%d - %d)" % (int(d.cast(ulong_t)), debug_offset))
@@ -34,7 +36,7 @@ class sd_dump_hashmaps(gdb.Command):
t = ["plain", "ordered", "set"][int(h["type"])]
- print "{}, {}, {}, {}, {}, {}, {} ({}:{})".format(t, h["hash_ops"], bool(h["has_indirect"]), n_entries, d["max_entries"], n_buckets, d["func"], d["file"], d["line"])
+ print("{}, {}, {}, {}, {}, {}, {} ({}:{})".format(t, h["hash_ops"], bool(h["has_indirect"]), n_entries, d["max_entries"], n_buckets, d["func"], d["file"], d["line"]))
if arg != "" and n_entries > 0:
dib_raw_addr = storage_ptr + (all_entry_sizes[h["type"]] * n_buckets)
@@ -46,10 +48,10 @@ class sd_dump_hashmaps(gdb.Command):
for dib in sorted(iter(histogram)):
if dib != 255:
- print "{:>3} {:>8} {} of entries".format(dib, histogram[dib], 100.0*histogram[dib]/n_entries)
+ print("{:>3} {:>8} {} of entries".format(dib, histogram[dib], 100.0*histogram[dib]/n_entries))
else:
- print "{:>3} {:>8} {} of slots".format(dib, histogram[dib], 100.0*histogram[dib]/n_buckets)
- print "mean DIB of entries: {}".format(sum([dib*histogram[dib] for dib in iter(histogram) if dib != 255])*1.0/n_entries)
+ print("{:>3} {:>8} {} of slots".format(dib, histogram[dib], 100.0*histogram[dib]/n_buckets))
+ print("mean DIB of entries: {}".format(sum([dib*histogram[dib] for dib in iter(histogram) if dib != 255])*1.0/n_entries))
blocks = []
current_len = 1
@@ -70,9 +72,9 @@ class sd_dump_hashmaps(gdb.Command):
if len(blocks) > 1 and blocks[0][0] == blocks[0][1] and blocks[-1][0] == n_buckets - 1:
blocks[0][1] += blocks[-1][1]
blocks = blocks[0:-1]
- print "max block: {}".format(max(blocks, key=lambda a: a[1]))
- print "sum block lens: {}".format(sum(b[1] for b in blocks))
- print "mean block len: {}".format((1.0 * sum(b[1] for b in blocks) / len(blocks)))
+ print("max block: {}".format(max(blocks, key=lambda a: a[1])))
+ print("sum block lens: {}".format(sum(b[1] for b in blocks)))
+ print("mean block len: {}".format((1.0 * sum(b[1] for b in blocks) / len(blocks))))
d = d["debug_list_next"]

@ -0,0 +1,44 @@
From c9fdcd0693ac63bc4b7326e248854617d9573bd6 Mon Sep 17 00:00:00 2001
From: Evgeny Vereshchagin <evvers@ya.ru>
Date: Fri, 26 Oct 2018 09:19:09 +0000
Subject: [PATCH] lgtm: add a custom query for catching the use of fgets
As everybody knows, nodoby really reads CODING_STYLE (especially
the last paragraph :-)) so let's utilize LGTM to help us catch the
use of fgets.
(cherry picked from commit f86c1da28340f2a2afd34d72c9f416a2a94219a8)
---
.lgtm/cpp-queries/fgets.ql | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 .lgtm/cpp-queries/fgets.ql
diff --git a/.lgtm/cpp-queries/fgets.ql b/.lgtm/cpp-queries/fgets.ql
new file mode 100644
index 0000000000..82de8c4482
--- /dev/null
+++ b/.lgtm/cpp-queries/fgets.ql
@@ -0,0 +1,23 @@
+/**
+ * @name Use of fgets()
+ * @description fgets() is dangerous to call. Use read_line() instead.
+ * @kind problem
+ * @problem.severity error
+ * @precision high
+ * @id cpp/fgets
+ * @tags reliability
+ * security
+ */
+import cpp
+
+
+predicate dangerousFunction(Function function) {
+ exists (string name | name = function.getQualifiedName() |
+ name = "fgets")
+}
+
+
+from FunctionCall call, Function target
+where call.getTarget() = target
+ and dangerousFunction(target)
+select call, target.getQualifiedName() + " is potentially dangerous"

@ -0,0 +1,28 @@
From d26406cc3f2c186691ce0a09052d3c39d15cc722 Mon Sep 17 00:00:00 2001
From: Evgeny Vereshchagin <evvers@ya.ru>
Date: Fri, 26 Oct 2018 10:25:36 +0000
Subject: [PATCH] lgtm: drop redundant newlines
(cherry picked from commit 845702c63863add5606a7a7f00a959ffdcf89635)
---
.lgtm/cpp-queries/fgets.ql | 2 --
1 file changed, 2 deletions(-)
diff --git a/.lgtm/cpp-queries/fgets.ql b/.lgtm/cpp-queries/fgets.ql
index 82de8c4482..a4181e4f3d 100644
--- a/.lgtm/cpp-queries/fgets.ql
+++ b/.lgtm/cpp-queries/fgets.ql
@@ -10,13 +10,11 @@
*/
import cpp
-
predicate dangerousFunction(Function function) {
exists (string name | name = function.getQualifiedName() |
name = "fgets")
}
-
from FunctionCall call, Function target
where call.getTarget() = target
and dangerousFunction(target)

@ -0,0 +1,24 @@
From 16d1f6e5122038fa24392e166a0a88c6cab41dd0 Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Tue, 26 Feb 2019 15:22:38 +0100
Subject: [PATCH] rules: add the rule that adds elevator= kernel command line
parameter
rhel-only
Resolves: #1670126
---
rules/meson.build | 1 +
1 file changed, 1 insertion(+)
diff --git a/rules/meson.build b/rules/meson.build
index e04a18aca6..b6aae596b6 100644
--- a/rules/meson.build
+++ b/rules/meson.build
@@ -2,6 +2,7 @@
rules = files('''
40-redhat.rules
+ 40-elevator.rules
60-block.rules
60-cdrom_id.rules
60-drm.rules

@ -0,0 +1,176 @@
From e4ff044489f43d2c7e1ecbdfb88692d87d63bd2a Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Wed, 19 Sep 2018 14:30:29 +0900
Subject: [PATCH] test: add TEST-24-UNIT-TESTS running all basic tests under
containers
(cherry picked from commit 3f6f58e03a7d22154aabe036439e7f2fb4849570)
---
test/TEST-24-UNIT-TESTS/Makefile | 1 +
test/TEST-24-UNIT-TESTS/test.sh | 106 +++++++++++++++++++++++++++
test/TEST-24-UNIT-TESTS/testsuite.sh | 34 +++++++++
3 files changed, 141 insertions(+)
create mode 120000 test/TEST-24-UNIT-TESTS/Makefile
create mode 100755 test/TEST-24-UNIT-TESTS/test.sh
create mode 100755 test/TEST-24-UNIT-TESTS/testsuite.sh
diff --git a/test/TEST-24-UNIT-TESTS/Makefile b/test/TEST-24-UNIT-TESTS/Makefile
new file mode 120000
index 0000000000..e9f93b1104
--- /dev/null
+++ b/test/TEST-24-UNIT-TESTS/Makefile
@@ -0,0 +1 @@
+../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-24-UNIT-TESTS/test.sh b/test/TEST-24-UNIT-TESTS/test.sh
new file mode 100755
index 0000000000..014ee52277
--- /dev/null
+++ b/test/TEST-24-UNIT-TESTS/test.sh
@@ -0,0 +1,106 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+set -e
+TEST_DESCRIPTION="Run unit tests under containers"
+RUN_IN_UNPRIVILEGED_CONTAINER=yes
+
+. $TEST_BASE_DIR/test-functions
+
+check_result_nspawn() {
+ local _ret=1
+ [[ -e $TESTDIR/$1/testok ]] && _ret=0
+ if [[ -s $TESTDIR/$1/failed ]]; then
+ _ret=$(($_ret+1))
+ echo "=== Failed test log ==="
+ cat $TESTDIR/$1/failed
+ else
+ if [[ -s $TESTDIR/$1/skipped ]]; then
+ echo "=== Skipped test log =="
+ cat $TESTDIR/$1/skipped
+ fi
+ if [[ -s $TESTDIR/$1/testok ]]; then
+ echo "=== Passed tests ==="
+ cat $TESTDIR/$1/testok
+ fi
+ fi
+ cp -a $TESTDIR/$1/var/log/journal $TESTDIR
+ [[ -n "$TIMED_OUT" ]] && _ret=$(($_ret+1))
+ return $_ret
+}
+
+check_result_qemu() {
+ local _ret=1
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+ [[ -e $TESTDIR/root/testok ]] && _ret=0
+ if [[ -s $TESTDIR/root/failed ]]; then
+ _ret=$(($_ret+1))
+ echo "=== Failed test log ==="
+ cat $TESTDIR/root/failed
+ else
+ if [[ -s $TESTDIR/root/skipped ]]; then
+ echo "=== Skipped test log =="
+ cat $TESTDIR/root/skipped
+ fi
+ if [[ -s $TESTDIR/root/testok ]]; then
+ echo "=== Passed tests ==="
+ cat $TESTDIR/root/testok
+ fi
+ fi
+ cp -a $TESTDIR/root/var/log/journal $TESTDIR
+ umount $TESTDIR/root
+ [[ -n "$TIMED_OUT" ]] && _ret=$(($_ret+1))
+ return $_ret
+}
+
+test_setup() {
+ if type -P meson && [[ "$(meson configure $BUILD_DIR | grep install-tests | awk '{ print $2 }')" != "true" ]]; then
+ dfatal "Needs to be built with -Dinstall-tests=true"
+ exit 1
+ fi
+
+ create_empty_image
+ mkdir -p $TESTDIR/root
+ mount ${LOOPDEV}p1 $TESTDIR/root
+
+ # Create what will eventually be our root filesystem onto an overlay
+ (
+ LOG_LEVEL=5
+ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+
+ for i in getfacl dirname basename capsh cut rev stat mktemp rmdir ionice unshare uname tr awk getent diff xzcat lz4cat; do
+ inst_binary $i
+ done
+
+ inst /etc/hosts
+
+ setup_basic_environment
+ install_keymaps yes
+ install_zoneinfo
+
+ # setup the testsuite service
+ cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+[Unit]
+Description=Testsuite service
+
+[Service]
+ExecStart=/testsuite.sh
+Type=oneshot
+EOF
+ cp testsuite.sh $initdir/
+
+ setup_testsuite
+ ) || return 1
+ setup_nspawn_root
+
+ # mask some services that we do not want to run in these tests
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
+
+ ddebug "umount $TESTDIR/root"
+ umount $TESTDIR/root
+}
+
+do_test "$@"
diff --git a/test/TEST-24-UNIT-TESTS/testsuite.sh b/test/TEST-24-UNIT-TESTS/testsuite.sh
new file mode 100755
index 0000000000..7c0e495dbd
--- /dev/null
+++ b/test/TEST-24-UNIT-TESTS/testsuite.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+#set -ex
+#set -o pipefail
+
+for i in /usr/lib/systemd/tests/test-*; do
+ if [[ ! -x $i ]]; then continue; fi
+ NAME=${i##*/}
+ echo "Running $NAME"
+ $i > /$NAME.log 2>&1
+ ret=$?
+ if (( $ret && $ret != 77 )); then
+ echo "$NAME failed with $ret"
+ echo $NAME >> /failed-tests
+ echo "--- $NAME begin ---" >> /failed
+ cat /$NAME.log >> /failed
+ echo "--- $NAME end ---" >> /failed
+ elif (( $ret == 77 )); then
+ echo "$NAME skipped"
+ echo $NAME >> /skipped-tests
+ echo "--- $NAME begin ---" >> /skipped
+ cat /$NAME.log >> /skipped
+ echo "--- $NAME end ---" >> /skipped
+ else
+ echo "$NAME OK"
+ echo $NAME >> /testok
+ fi
+
+ systemd-cat echo "--- $NAME ---"
+ systemd-cat cat /$NAME.log
+done
+
+exit 0

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save