import systemd-239-55.el8

This commit is contained in:
CentOS Sources 2022-01-19 21:25:15 +00:00 committed by Stepan Oksanichenko
parent 0ab46f1dd7
commit fb093fc238
23 changed files with 2110 additions and 1 deletions

View File

@ -0,0 +1,171 @@
From cecb3cc06f6025835324c1837c03def1d9be8eb1 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 1 Dec 2021 21:31:43 +0100
Subject: [PATCH] lgtm: detect uninitialized variables using the __cleanup__
attribute
This is a slightly modified version of the original
`cpp/uninitialized-local` CodeQL query which focuses only on variables
using the cleanup macros. Since this has proven to cause issues in the
past, let's panic on every uninitialized variable using any of the
cleanup macros (as long as they're written using the __cleanup__
attribute).
Some test results from a test I used when writing the query:
```
#define _cleanup_foo_ __attribute__((__cleanup__(foo)))
#define _cleanup_(x) __attribute__((__cleanup__(x)))
static inline void freep(void *p) {
*(void**)p = mfree(*(void**) p);
}
#define _cleanup_free_ _cleanup_(freep)
static inline void foo(char **p) {
if (*p)
*p = free(*p);
}
int main(void) {
__attribute__((__cleanup__(foo))) char *a;
char *b;
_cleanup_foo_ char *c;
char **d;
_cleanup_free_ char *e;
int r;
r = fun(&e);
if (r < 0)
return 1;
puts(a);
puts(b);
puts(c);
puts(*d);
puts(e);
return 0;
}
```
```
+| test.c:23:14:23:14 | e | The variable $@ may not be initialized here, but has a cleanup handler. | test.c:20:26:20:26 | e | e |
+| test.c:27:10:27:10 | a | The variable $@ may not be initialized here, but has a cleanup handler. | test.c:16:45:16:45 | a | a |
+| test.c:29:10:29:10 | c | The variable $@ may not be initialized here, but has a cleanup handler. | test.c:18:25:18:25 | c | c |
```
(cherry picked from commit 863bff75488d33f519deea6390988f3d9d72e6de)
Related: #2017033
---
.../UninitializedVariableWithCleanup.ql | 99 +++++++++++++++++++
1 file changed, 99 insertions(+)
create mode 100644 .lgtm/cpp-queries/UninitializedVariableWithCleanup.ql
diff --git a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql
new file mode 100644
index 0000000000..6bf0ae01eb
--- /dev/null
+++ b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql
@@ -0,0 +1,99 @@
+/**
+ * vi: sw=2 ts=2 et syntax=ql:
+ *
+ * Based on cpp/uninitialized-local.
+ *
+ * @name Potentially uninitialized local variable using the cleanup attribute
+ * @description Running the cleanup handler on a possibly uninitialized variable
+ * is generally a bad idea.
+ * @id cpp/uninitialized-local-with-cleanup
+ * @kind problem
+ * @problem.severity error
+ * @precision high
+ * @tags security
+ */
+
+import cpp
+import semmle.code.cpp.controlflow.StackVariableReachability
+
+/**
+ * Auxiliary predicate: Types that don't require initialization
+ * before they are used, since they're stack-allocated.
+ */
+predicate allocatedType(Type t) {
+ /* Arrays: "int foo[1]; foo[0] = 42;" is ok. */
+ t instanceof ArrayType
+ or
+ /* Structs: "struct foo bar; bar.baz = 42" is ok. */
+ t instanceof Class
+ or
+ /* Typedefs to other allocated types are fine. */
+ allocatedType(t.(TypedefType).getUnderlyingType())
+ or
+ /* Type specifiers don't affect whether or not a type is allocated. */
+ allocatedType(t.getUnspecifiedType())
+}
+
+/**
+ * A declaration of a local variable using __attribute__((__cleanup__(x)))
+ * that leaves the variable uninitialized.
+ */
+DeclStmt declWithNoInit(LocalVariable v) {
+ result.getADeclaration() = v and
+ not exists(v.getInitializer()) and
+ /* The variable has __attribute__((__cleanup__(...))) set */
+ v.getAnAttribute().hasName("cleanup") and
+ /* The type of the variable is not stack-allocated. */
+ exists(Type t | t = v.getType() | not allocatedType(t))
+}
+
+class UninitialisedLocalReachability extends StackVariableReachability {
+ UninitialisedLocalReachability() { this = "UninitialisedLocal" }
+
+ override predicate isSource(ControlFlowNode node, StackVariable v) { node = declWithNoInit(v) }
+
+ /* Note: _don't_ use the `useOfVarActual()` predicate here (and a couple of lines
+ * below), as it assumes that the callee always modifies the variable if
+ * it's passed to the function.
+ *
+ * i.e.:
+ * _cleanup_free char *x;
+ * fun(&x);
+ * puts(x);
+ *
+ * `useOfVarActual()` won't treat this an an uninitialized read even if the callee
+ * doesn't modify the argument, however, `useOfVar()` will
+ */
+ override predicate isSink(ControlFlowNode node, StackVariable v) { useOfVar(v, node) }
+
+ override predicate isBarrier(ControlFlowNode node, StackVariable v) {
+ // only report the _first_ possibly uninitialized use
+ useOfVar(v, node) or
+ definitionBarrier(v, node)
+ }
+}
+
+pragma[noinline]
+predicate containsInlineAssembly(Function f) { exists(AsmStmt s | s.getEnclosingFunction() = f) }
+
+/**
+ * Auxiliary predicate: List common exceptions or false positives
+ * for this check to exclude them.
+ */
+VariableAccess commonException() {
+ // If the uninitialized use we've found is in a macro expansion, it's
+ // typically something like va_start(), and we don't want to complain.
+ result.getParent().isInMacroExpansion()
+ or
+ result.getParent() instanceof BuiltInOperation
+ or
+ // Finally, exclude functions that contain assembly blocks. It's
+ // anyone's guess what happens in those.
+ containsInlineAssembly(result.getEnclosingFunction())
+}
+
+from UninitialisedLocalReachability r, LocalVariable v, VariableAccess va
+where
+ r.reaches(_, v, va) and
+ not va = commonException()
+select va, "The variable $@ may not be initialized here, but has a cleanup handler.", v, v.getName()

View File

@ -0,0 +1,84 @@
From c4a34b71d4f51f071f7a722059e36388b41d30e4 Mon Sep 17 00:00:00 2001
From: Evgeny Vereshchagin <evvers@ya.ru>
Date: Mon, 11 Mar 2019 21:05:13 +0100
Subject: [PATCH] lgtm: replace the query used for looking for fgets with a
more general query
to make it easier to comlain about `strtok` :-)
Inspired by https://github.com/systemd/systemd/pull/11963, which, in turn,
was prompted by https://github.com/systemd/systemd/pull/11555.
(cherry picked from commit 7ba5ded9dbd7737bc368521f5ea7c90e5b06ab3e)
Related: #2017033
---
.../PotentiallyDangerousFunction.ql | 30 +++++++++++++++++++
.lgtm/cpp-queries/fgets.ql | 21 -------------
2 files changed, 30 insertions(+), 21 deletions(-)
create mode 100644 .lgtm/cpp-queries/PotentiallyDangerousFunction.ql
delete mode 100644 .lgtm/cpp-queries/fgets.ql
diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
new file mode 100644
index 0000000000..ba80f4ad8c
--- /dev/null
+++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
@@ -0,0 +1,30 @@
+/**
+ * @name Use of potentially dangerous function
+ * @description Certain standard library functions are dangerous to call.
+ * @kind problem
+ * @problem.severity error
+ * @precision high
+ * @id cpp/potentially-dangerous-function
+ * @tags reliability
+ * security
+ *
+ * Borrowed from
+ * https://github.com/Semmle/ql/blob/master/cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql
+ */
+import cpp
+
+predicate potentiallyDangerousFunction(Function f, string message) {
+ (
+ f.getQualifiedName() = "fgets" and
+ message = "Call to fgets is potentially dangerous. Use read_line() instead."
+ ) or (
+ f.getQualifiedName() = "strtok" and
+ message = "Call to strtok is potentially dangerous. Use extract_first_word() instead."
+ )
+}
+
+from FunctionCall call, Function target, string message
+where
+ call.getTarget() = target and
+ potentiallyDangerousFunction(target, message)
+select call, message
diff --git a/.lgtm/cpp-queries/fgets.ql b/.lgtm/cpp-queries/fgets.ql
deleted file mode 100644
index a4181e4f3d..0000000000
--- a/.lgtm/cpp-queries/fgets.ql
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * @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"

View File

@ -0,0 +1,48 @@
From 8b60932555141e1fe61a343863eae7655c2449a9 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 2 Apr 2019 12:43:47 +0200
Subject: [PATCH] lgtm: beef up list of dangerous/questionnable API calls not
to make
(cherry picked from commit 9b4805421eb2a7319f6507a26febfb9d2cdc3a93)
Related: #2017033
---
.../PotentiallyDangerousFunction.ql | 22 +++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
index ba80f4ad8c..cd0284b37a 100644
--- a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
+++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
@@ -16,10 +16,28 @@ import cpp
predicate potentiallyDangerousFunction(Function f, string message) {
(
f.getQualifiedName() = "fgets" and
- message = "Call to fgets is potentially dangerous. Use read_line() instead."
+ message = "Call to fgets() is potentially dangerous. Use read_line() instead."
) or (
f.getQualifiedName() = "strtok" and
- message = "Call to strtok is potentially dangerous. Use extract_first_word() instead."
+ message = "Call to strtok() is potentially dangerous. Use extract_first_word() instead."
+ ) or (
+ f.getQualifiedName() = "strsep" and
+ message = "Call to strsep() is potentially dangerous. Use extract_first_word() instead."
+ ) or (
+ f.getQualifiedName() = "dup" and
+ message = "Call to dup() is potentially dangerous. Use fcntl(fd, FD_DUPFD_CLOEXEC, 3) instead."
+ ) or (
+ f.getQualifiedName() = "htonl" and
+ message = "Call to htonl() is confusing. Use htobe32() instead."
+ ) or (
+ f.getQualifiedName() = "htons" and
+ message = "Call to htons() is confusing. Use htobe16() instead."
+ ) or (
+ f.getQualifiedName() = "ntohl" and
+ message = "Call to ntohl() is confusing. Use be32toh() instead."
+ ) or (
+ f.getQualifiedName() = "ntohs" and
+ message = "Call to ntohs() is confusing. Use be16toh() instead."
)
}

View File

@ -0,0 +1,26 @@
From af6eac25456d4ca7e8233e00aec7531e640f17af Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 5 Apr 2019 15:31:34 +0200
Subject: [PATCH] lgtm: warn about strerror() use
(cherry picked from commit 9ff46eded2b99d244455467eb55c0ff3f51c5362)
Related: #2017033
---
.lgtm/cpp-queries/PotentiallyDangerousFunction.ql | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
index cd0284b37a..96712cf1c6 100644
--- a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
+++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
@@ -38,6 +38,9 @@ predicate potentiallyDangerousFunction(Function f, string message) {
) or (
f.getQualifiedName() = "ntohs" and
message = "Call to ntohs() is confusing. Use be16toh() instead."
+ ) or (
+ f.getQualifiedName() = "strerror" and
+ message = "Call to strerror() is not thread-safe. Use strerror_r() or printf()'s %m format string instead."
)
}

View File

@ -0,0 +1,27 @@
From bfa090ce83f2b0734c526a4426a20f6f0f943aa0 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 10 Apr 2019 19:36:40 +0200
Subject: [PATCH] lgtm: complain about accept() [people should use accept4()
instead, due to O_CLOEXEC]
(cherry picked from commit e2d0fa6feb3797246c8bfda3db45a2f5b62e1b5b)
Related: #2017033
---
.lgtm/cpp-queries/PotentiallyDangerousFunction.ql | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
index 96712cf1c6..865330430d 100644
--- a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
+++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
@@ -41,6 +41,9 @@ predicate potentiallyDangerousFunction(Function f, string message) {
) or (
f.getQualifiedName() = "strerror" and
message = "Call to strerror() is not thread-safe. Use strerror_r() or printf()'s %m format string instead."
+ ) or (
+ f.getQualifiedName() = "accept" and
+ message = "Call to accept() is not O_CLOEXEC-safe. Use accept4() instead."
)
}

View File

@ -0,0 +1,40 @@
From 6eeaef95566e6d85e714280c412e5df347838e34 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Thu, 2 Dec 2021 16:55:17 +0100
Subject: [PATCH] lgtm: don't treat the custom note as a list of tags
Just a cosmetic change.
(cherry picked from commit c7d70210fa45c3210b8b1eda51bc0f6d68bd8392)
Related: #2017033
---
.lgtm/cpp-queries/PotentiallyDangerousFunction.ql | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
index 865330430d..39e8dddd13 100644
--- a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
+++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql
@@ -1,15 +1,17 @@
/**
+ * vi: sw=2 ts=2 et syntax=ql:
+ *
+ * Borrowed from
+ * https://github.com/Semmle/ql/blob/master/cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql
+ *
* @name Use of potentially dangerous function
* @description Certain standard library functions are dangerous to call.
+ * @id cpp/potentially-dangerous-function
* @kind problem
* @problem.severity error
* @precision high
- * @id cpp/potentially-dangerous-function
* @tags reliability
* security
- *
- * Borrowed from
- * https://github.com/Semmle/ql/blob/master/cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql
*/
import cpp

View File

@ -0,0 +1,42 @@
From 42123e9614ea73c7f64c684c90e4dbb049ef67ef Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Sun, 5 Dec 2021 10:25:28 +0100
Subject: [PATCH] lgtm: ignore certain cleanup functions
as they don't do any illegal stuff even when used with an uninitialized
variable.
(cherry picked from commit af1868213657b38b8d4008608976eb81546cfb8e)
Related: #2017033
---
.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql
index 6bf0ae01eb..8c24b6d8f1 100644
--- a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql
+++ b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql
@@ -34,6 +34,13 @@ predicate allocatedType(Type t) {
allocatedType(t.getUnspecifiedType())
}
+/** Auxiliary predicate: List cleanup functions we want to explicitly ignore
+ * since they don't do anything illegal even when the variable is uninitialized
+ */
+predicate cleanupFunctionDenyList(string fun) {
+ fun = "erase_char"
+}
+
/**
* A declaration of a local variable using __attribute__((__cleanup__(x)))
* that leaves the variable uninitialized.
@@ -43,6 +50,8 @@ DeclStmt declWithNoInit(LocalVariable v) {
not exists(v.getInitializer()) and
/* The variable has __attribute__((__cleanup__(...))) set */
v.getAnAttribute().hasName("cleanup") and
+ /* Check if the cleanup function is not on a deny list */
+ not exists(Attribute a | a = v.getAnAttribute() and a.getName() = "cleanup" | cleanupFunctionDenyList(a.getAnArgument().getValueText())) and
/* The type of the variable is not stack-allocated. */
exists(Type t | t = v.getType() | not allocatedType(t))
}

View File

@ -0,0 +1,96 @@
From f9b19c9d4caaf870b30cce8a3d6be79eda099c4e Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Sun, 5 Dec 2021 16:11:35 +0100
Subject: [PATCH] lgtm: detect more possible problematic scenarios
1) don't ignore stack-allocated variables, since they may hide
heap-allocated stuff (compound types)
2) check if there's a return between the variable declaration and its
initialization; if so, treat the variable as uninitialized
3) introduction of 2) increased the query runtime exponentially, so
introduce some optimizations to bring it back to some reasonable
values
(cherry picked from commit c8fec8bf9b086f9fc7638db0f1a613a00d7c63a3)
Related: #2017033
---
.../UninitializedVariableWithCleanup.ql | 48 ++++++++++---------
1 file changed, 25 insertions(+), 23 deletions(-)
diff --git a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql
index 8c24b6d8f1..6b3b62f8bc 100644
--- a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql
+++ b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql
@@ -16,24 +16,6 @@
import cpp
import semmle.code.cpp.controlflow.StackVariableReachability
-/**
- * Auxiliary predicate: Types that don't require initialization
- * before they are used, since they're stack-allocated.
- */
-predicate allocatedType(Type t) {
- /* Arrays: "int foo[1]; foo[0] = 42;" is ok. */
- t instanceof ArrayType
- or
- /* Structs: "struct foo bar; bar.baz = 42" is ok. */
- t instanceof Class
- or
- /* Typedefs to other allocated types are fine. */
- allocatedType(t.(TypedefType).getUnderlyingType())
- or
- /* Type specifiers don't affect whether or not a type is allocated. */
- allocatedType(t.getUnspecifiedType())
-}
-
/** Auxiliary predicate: List cleanup functions we want to explicitly ignore
* since they don't do anything illegal even when the variable is uninitialized
*/
@@ -47,13 +29,11 @@ predicate cleanupFunctionDenyList(string fun) {
*/
DeclStmt declWithNoInit(LocalVariable v) {
result.getADeclaration() = v and
- not exists(v.getInitializer()) and
+ not v.hasInitializer() and
/* The variable has __attribute__((__cleanup__(...))) set */
v.getAnAttribute().hasName("cleanup") and
/* Check if the cleanup function is not on a deny list */
- not exists(Attribute a | a = v.getAnAttribute() and a.getName() = "cleanup" | cleanupFunctionDenyList(a.getAnArgument().getValueText())) and
- /* The type of the variable is not stack-allocated. */
- exists(Type t | t = v.getType() | not allocatedType(t))
+ not cleanupFunctionDenyList(v.getAnAttribute().getAnArgument().getValueText())
}
class UninitialisedLocalReachability extends StackVariableReachability {
@@ -78,7 +58,29 @@ class UninitialisedLocalReachability extends StackVariableReachability {
override predicate isBarrier(ControlFlowNode node, StackVariable v) {
// only report the _first_ possibly uninitialized use
useOfVar(v, node) or
- definitionBarrier(v, node)
+ (
+ /* If there's an return statement somewhere between the variable declaration
+ * and a possible definition, don't accept is as a valid initialization.
+ *
+ * E.g.:
+ * _cleanup_free_ char *x;
+ * ...
+ * if (...)
+ * return;
+ * ...
+ * x = malloc(...);
+ *
+ * is not a valid initialization, since we might return from the function
+ * _before_ the actual iniitialization (emphasis on _might_, since we
+ * don't know if the return statement might ever evaluate to true).
+ */
+ definitionBarrier(v, node) and
+ not exists(ReturnStmt rs |
+ /* The attribute check is "just" a complexity optimization */
+ v.getFunction() = rs.getEnclosingFunction() and v.getAnAttribute().hasName("cleanup") |
+ rs.getLocation().isBefore(node.getLocation())
+ )
+ )
}
}

View File

@ -0,0 +1,48 @@
From 842c676a36abab0d92f1e68de2c8881fd00fdf4b Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Tue, 30 Nov 2021 23:40:28 +0100
Subject: [PATCH] lgtm: enable more (and potentially useful) queries
Not all available queries on LGTM are enabled by default, but some of
the excluded ones might come in handy, hence let's enable them
explicitly.
(cherry picked from commit 38f36b9f3443b4d2085799c772e901a402b84af3)
Related: #2017033
---
.lgtm.yml | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/.lgtm.yml b/.lgtm.yml
index 5948d8c2bc..fe93957b67 100644
--- a/.lgtm.yml
+++ b/.lgtm.yml
@@ -1,3 +1,27 @@
+---
+# vi: ts=2 sw=2 et:
+
+# Explicitly enable certain checks which are hidden by default
+queries:
+ - include: cpp/bad-strncpy-size
+ - include: cpp/declaration-hides-variable
+ - include: cpp/inconsistent-null-check
+ - include: cpp/mistyped-function-arguments
+ - include: cpp/nested-loops-with-same-variable
+ - include: cpp/sizeof-side-effect
+ - include: cpp/suspicious-pointer-scaling
+ - include: cpp/suspicious-pointer-scaling-void
+ - include: cpp/suspicious-sizeof
+ - include: cpp/unsafe-strcat
+ - include: cpp/unsafe-strncat
+ - include: cpp/unsigned-difference-expression-compared-zero
+ - include: cpp/unused-local-variable
+ - include:
+ tags:
+ - "security"
+ - "correctness"
+ severity: "error"
+
extraction:
cpp:
prepare:

View File

@ -0,0 +1,36 @@
From 4433c31a80c4477b0a0c503c74e8faebc44f4453 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 7 Nov 2019 11:32:26 +0100
Subject: [PATCH] meson: avoid bogus meson warning
With meson-0.52.0-1.module_f31+6771+f5d842eb.noarch I get:
src/test/meson.build:19: WARNING: Overriding previous value of environment variable 'PATH' with a new one
When we're using *prepend*, the whole point is to modify an existing variable,
so meson shouldn't warn. But let's set avoid the warning and shorten things by
setting the final value immediately.
(cherry picked from commit cbe804947482998cc767bfb0c169e6263a6ef097)
---
src/test/meson.build | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/test/meson.build b/src/test/meson.build
index 40cf56d73d..6eaa62e53f 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -10,12 +10,11 @@ test_hashmap_ordered_c = custom_target(
test_include_dir = include_directories('.')
-path = run_command('sh', ['-c', 'echo "$PATH"']).stdout()
+path = run_command('sh', ['-c', 'echo "$PATH"']).stdout().strip()
test_env = environment()
test_env.set('SYSTEMD_KBD_MODEL_MAP', kbd_model_map)
test_env.set('SYSTEMD_LANGUAGE_FALLBACK_MAP', language_fallback_map)
-test_env.set('PATH', path)
-test_env.prepend('PATH', meson.build_root())
+test_env.set('PATH', '@0@:@1@'.format(meson.build_root(), path))
############################################################

View File

@ -0,0 +1,33 @@
From de7125dcfe6d6c8af05262ab786f9fe7cbf15113 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 15 Dec 2021 12:15:19 +0100
Subject: [PATCH] test: make TEST-47 less racy
Based on:
- 2e7090e94d0c8b31d418555ab2f6a9b75318f6a4
- e00e2e0b50bbd120290572c8d1242703fb98b34e
- 197298ff9fc930de450330095cc5b67d165d0801
Related: #2017033
---
test/TEST-47-ISSUE-14566/testsuite.sh | 2 ++
1 file changed, 2 insertions(+)
diff --git a/test/TEST-47-ISSUE-14566/testsuite.sh b/test/TEST-47-ISSUE-14566/testsuite.sh
index d917cf52ff..b12b50e96c 100755
--- a/test/TEST-47-ISSUE-14566/testsuite.sh
+++ b/test/TEST-47-ISSUE-14566/testsuite.sh
@@ -6,11 +6,13 @@ systemd-analyze log-level debug
systemd-analyze log-target console
systemctl start issue_14566_test
+sleep 4
systemctl status issue_14566_test
leaked_pid=$(cat /leakedtestpid)
systemctl stop issue_14566_test
+sleep 4
# Leaked PID will still be around if we're buggy.
# I personally prefer to see 42.

View File

@ -0,0 +1,179 @@
From 894d307d0d149adb46e630550566e5a3f6ff8d2e Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 18 Mar 2019 12:21:27 +0100
Subject: [PATCH] core: rename unit_{start_limit|condition|assert}_test() to
unit_test_xyz()
Just some renaming, no change in behaviour.
Background: I'd like to add more functions unit_test_xyz() that test
various things, hence let's streamline the naming a bit.
(cherry picked from commit 97a3f4ee052e1b8a0ff03accfa478e352891a84f)
Related: #2036608
---
src/core/automount.c | 2 +-
src/core/mount.c | 2 +-
src/core/path.c | 2 +-
src/core/service.c | 2 +-
src/core/socket.c | 2 +-
src/core/swap.c | 2 +-
src/core/timer.c | 2 +-
src/core/unit.c | 11 +++++------
src/core/unit.h | 2 +-
9 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/src/core/automount.c b/src/core/automount.c
index 76e70f4dac..2bc160cb07 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -808,7 +808,7 @@ static int automount_start(Unit *u) {
return -ENOENT;
}
- r = unit_start_limit_test(u);
+ r = unit_test_start_limit(u);
if (r < 0) {
automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT);
return r;
diff --git a/src/core/mount.c b/src/core/mount.c
index 7e80a0c974..aa586d88cb 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1065,7 +1065,7 @@ static int mount_start(Unit *u) {
assert(IN_SET(m->state, MOUNT_DEAD, MOUNT_FAILED));
- r = unit_start_limit_test(u);
+ r = unit_test_start_limit(u);
if (r < 0) {
mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT);
return r;
diff --git a/src/core/path.c b/src/core/path.c
index ed40bc6c19..4bccc0396b 100644
--- a/src/core/path.c
+++ b/src/core/path.c
@@ -565,7 +565,7 @@ static int path_start(Unit *u) {
return -ENOENT;
}
- r = unit_start_limit_test(u);
+ r = unit_test_start_limit(u);
if (r < 0) {
path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT);
return r;
diff --git a/src/core/service.c b/src/core/service.c
index 7969bbf071..1a1de43d0d 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -2388,7 +2388,7 @@ static int service_start(Unit *u) {
assert(IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED));
/* Make sure we don't enter a busy loop of some kind. */
- r = unit_start_limit_test(u);
+ r = unit_test_start_limit(u);
if (r < 0) {
service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false);
return r;
diff --git a/src/core/socket.c b/src/core/socket.c
index 50c32ed8f4..09491c6677 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -2469,7 +2469,7 @@ static int socket_start(Unit *u) {
assert(IN_SET(s->state, SOCKET_DEAD, SOCKET_FAILED));
- r = unit_start_limit_test(u);
+ r = unit_test_start_limit(u);
if (r < 0) {
socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT);
return r;
diff --git a/src/core/swap.c b/src/core/swap.c
index a8f127f660..823699699e 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -851,7 +851,7 @@ static int swap_start(Unit *u) {
if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING)
return -EAGAIN;
- r = unit_start_limit_test(u);
+ r = unit_test_start_limit(u);
if (r < 0) {
swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT);
return r;
diff --git a/src/core/timer.c b/src/core/timer.c
index 1718ffc5a5..be16321296 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -599,7 +599,7 @@ static int timer_start(Unit *u) {
return -ENOENT;
}
- r = unit_start_limit_test(u);
+ r = unit_test_start_limit(u);
if (r < 0) {
timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT);
return r;
diff --git a/src/core/unit.c b/src/core/unit.c
index 23afa24c77..9013186d8a 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1633,7 +1633,7 @@ static bool unit_condition_test_list(Unit *u, Condition *first, const char *(*to
return triggered != 0;
}
-static bool unit_condition_test(Unit *u) {
+static bool unit_test_condition(Unit *u) {
assert(u);
dual_timestamp_get(&u->condition_timestamp);
@@ -1642,7 +1642,7 @@ static bool unit_condition_test(Unit *u) {
return u->condition_result;
}
-static bool unit_assert_test(Unit *u) {
+static bool unit_test_assert(Unit *u) {
assert(u);
dual_timestamp_get(&u->assert_timestamp);
@@ -1657,8 +1657,7 @@ void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg
REENABLE_WARNING;
}
-
-int unit_start_limit_test(Unit *u) {
+int unit_test_start_limit(Unit *u) {
assert(u);
if (ratelimit_below(&u->start_limit)) {
@@ -1750,14 +1749,14 @@ int unit_start(Unit *u) {
* speed up activation in case there is some hold-off time,
* but we don't want to recheck the condition in that case. */
if (state != UNIT_ACTIVATING &&
- !unit_condition_test(u)) {
+ !unit_test_condition(u)) {
log_unit_debug(u, "Starting requested but condition failed. Not starting unit.");
return -EALREADY;
}
/* If the asserts failed, fail the entire job */
if (state != UNIT_ACTIVATING &&
- !unit_assert_test(u)) {
+ !unit_test_assert(u)) {
log_unit_notice(u, "Starting requested but asserts failed.");
return -EPROTO;
}
diff --git a/src/core/unit.h b/src/core/unit.h
index ec45b5fb48..a8bc350b66 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -786,7 +786,7 @@ static inline bool unit_supported(Unit *u) {
void unit_warn_if_dir_nonempty(Unit *u, const char* where);
int unit_fail_if_noncanonical(Unit *u, const char* where);
-int unit_start_limit_test(Unit *u);
+int unit_test_start_limit(Unit *u);
void unit_unref_uid(Unit *u, bool destroy_now);
int unit_ref_uid(Unit *u, uid_t uid, bool clean_ipc);

View File

@ -0,0 +1,400 @@
From 471eda89a25a3ceac91a2d05e39a54aae78038ed Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
Date: Tue, 24 Aug 2021 16:46:47 +0100
Subject: [PATCH] core: Check unit start rate limiting earlier
Fixes #17433. Currently, if any of the validations we do before we
check start rate limiting fail, we can still enter a busy loop as
no rate limiting gets applied. A common occurence of this scenario
is path units triggering a service that fails a condition check.
To fix the issue, we simply move up start rate limiting checks to
be the first thing we do when starting a unit. To achieve this,
we add a new method to the unit vtable and implement it for the
relevant unit types so that we can do the start rate limit checks
earlier on.
(cherry picked from commit 9727f2427ff6b2e1f4ab927cc57ad8e888f04e95)
Related: #2036608
[msekleta: I've deleted part of the original commit that adds test for
issue #17433. This was necessary because upstream commit assumes newer
organization of the test code which we don't have in RHEL-8 tree. As
a consequence we must add explicit test for this in the internal
test-suite.]
---
src/core/automount.c | 23 +++++++++++++++++------
src/core/mount.c | 23 +++++++++++++++++------
src/core/path.c | 23 +++++++++++++++++------
src/core/service.c | 25 ++++++++++++++++++-------
src/core/socket.c | 23 +++++++++++++++++------
src/core/swap.c | 23 +++++++++++++++++------
src/core/timer.c | 22 ++++++++++++++++------
src/core/unit.c | 14 ++++++++++----
src/core/unit.h | 4 ++++
9 files changed, 133 insertions(+), 47 deletions(-)
diff --git a/src/core/automount.c b/src/core/automount.c
index 2bc160cb07..5e16adabb5 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -808,12 +808,6 @@ static int automount_start(Unit *u) {
return -ENOENT;
}
- r = unit_test_start_limit(u);
- if (r < 0) {
- automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT);
- return r;
- }
-
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -1077,6 +1071,21 @@ static bool automount_supported(void) {
return supported;
}
+static int automount_test_start_limit(Unit *u) {
+ Automount *a = AUTOMOUNT(u);
+ int r;
+
+ assert(a);
+
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
+ return 0;
+}
+
static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
[AUTOMOUNT_SUCCESS] = "success",
[AUTOMOUNT_FAILURE_RESOURCES] = "resources",
@@ -1135,4 +1144,6 @@ const UnitVTable automount_vtable = {
[JOB_FAILED] = "Failed to unset automount %s.",
},
},
+
+ .test_start_limit = automount_test_start_limit,
};
diff --git a/src/core/mount.c b/src/core/mount.c
index aa586d88cb..22848847e5 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1065,12 +1065,6 @@ static int mount_start(Unit *u) {
assert(IN_SET(m->state, MOUNT_DEAD, MOUNT_FAILED));
- r = unit_test_start_limit(u);
- if (r < 0) {
- mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT);
- return r;
- }
-
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -1957,6 +1951,21 @@ static int mount_control_pid(Unit *u) {
return m->control_pid;
}
+static int mount_test_start_limit(Unit *u) {
+ Mount *m = MOUNT(u);
+ int r;
+
+ assert(m);
+
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
+ return 0;
+}
+
static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
[MOUNT_EXEC_MOUNT] = "ExecMount",
[MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
@@ -2048,4 +2057,6 @@ const UnitVTable mount_vtable = {
[JOB_TIMEOUT] = "Timed out unmounting %s.",
},
},
+
+ .test_start_limit = mount_test_start_limit,
};
diff --git a/src/core/path.c b/src/core/path.c
index 4bccc0396b..1e69a1f05f 100644
--- a/src/core/path.c
+++ b/src/core/path.c
@@ -565,12 +565,6 @@ static int path_start(Unit *u) {
return -ENOENT;
}
- r = unit_test_start_limit(u);
- if (r < 0) {
- path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT);
- return r;
- }
-
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -730,6 +724,21 @@ static void path_reset_failed(Unit *u) {
p->result = PATH_SUCCESS;
}
+static int path_test_start_limit(Unit *u) {
+ Path *p = PATH(u);
+ int r;
+
+ assert(p);
+
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
+ return 0;
+}
+
static const char* const path_type_table[_PATH_TYPE_MAX] = {
[PATH_EXISTS] = "PathExists",
[PATH_EXISTS_GLOB] = "PathExistsGlob",
@@ -782,4 +791,6 @@ const UnitVTable path_vtable = {
.bus_vtable = bus_path_vtable,
.bus_set_property = bus_path_set_property,
+
+ .test_start_limit = path_test_start_limit,
};
diff --git a/src/core/service.c b/src/core/service.c
index 1a1de43d0d..c5f408d817 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -2387,13 +2387,6 @@ static int service_start(Unit *u) {
assert(IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED));
- /* Make sure we don't enter a busy loop of some kind. */
- r = unit_test_start_limit(u);
- if (r < 0) {
- service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false);
- return r;
- }
-
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -4081,6 +4074,22 @@ static bool service_needs_console(Unit *u) {
SERVICE_FINAL_SIGKILL);
}
+static int service_test_start_limit(Unit *u) {
+ Service *s = SERVICE(u);
+ int r;
+
+ assert(s);
+
+ /* Make sure we don't enter a busy loop of some kind. */
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false);
+ return r;
+ }
+
+ return 0;
+}
+
static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
[SERVICE_RESTART_NO] = "no",
[SERVICE_RESTART_ON_SUCCESS] = "on-success",
@@ -4222,4 +4231,6 @@ const UnitVTable service_vtable = {
[JOB_FAILED] = "Stopped (with error) %s.",
},
},
+
+ .test_start_limit = service_test_start_limit,
};
diff --git a/src/core/socket.c b/src/core/socket.c
index 09491c6677..36d2e4f823 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -2469,12 +2469,6 @@ static int socket_start(Unit *u) {
assert(IN_SET(s->state, SOCKET_DEAD, SOCKET_FAILED));
- r = unit_test_start_limit(u);
- if (r < 0) {
- socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT);
- return r;
- }
-
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -3267,6 +3261,21 @@ static int socket_control_pid(Unit *u) {
return s->control_pid;
}
+static int socket_test_start_limit(Unit *u) {
+ Socket *s = SOCKET(u);
+ int r;
+
+ assert(s);
+
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
+ return 0;
+}
+
static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
[SOCKET_EXEC_START_PRE] = "ExecStartPre",
[SOCKET_EXEC_START_CHOWN] = "ExecStartChown",
@@ -3359,4 +3368,6 @@ const UnitVTable socket_vtable = {
[JOB_TIMEOUT] = "Timed out stopping %s.",
},
},
+
+ .test_start_limit = socket_test_start_limit,
};
diff --git a/src/core/swap.c b/src/core/swap.c
index 823699699e..90fcd69300 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -851,12 +851,6 @@ static int swap_start(Unit *u) {
if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING)
return -EAGAIN;
- r = unit_test_start_limit(u);
- if (r < 0) {
- swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT);
- return r;
- }
-
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -1458,6 +1452,21 @@ static int swap_control_pid(Unit *u) {
return s->control_pid;
}
+static int swap_test_start_limit(Unit *u) {
+ Swap *s = SWAP(u);
+ int r;
+
+ assert(s);
+
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
+ return 0;
+}
+
static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
[SWAP_EXEC_ACTIVATE] = "ExecActivate",
[SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
@@ -1547,4 +1556,6 @@ const UnitVTable swap_vtable = {
[JOB_TIMEOUT] = "Timed out deactivating swap %s.",
},
},
+
+ .test_start_limit = swap_test_start_limit,
};
diff --git a/src/core/timer.c b/src/core/timer.c
index be16321296..fb9ae17990 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -599,12 +599,6 @@ static int timer_start(Unit *u) {
return -ENOENT;
}
- r = unit_test_start_limit(u);
- if (r < 0) {
- timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT);
- return r;
- }
-
r = unit_acquire_invocation_id(u);
if (r < 0)
return r;
@@ -829,6 +823,21 @@ static void timer_timezone_change(Unit *u) {
timer_enter_waiting(t, false);
}
+static int timer_test_start_limit(Unit *u) {
+ Timer *t = TIMER(u);
+ int r;
+
+ assert(t);
+
+ r = unit_test_start_limit(u);
+ if (r < 0) {
+ timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT);
+ return r;
+ }
+
+ return 0;
+}
+
static const char* const timer_base_table[_TIMER_BASE_MAX] = {
[TIMER_ACTIVE] = "OnActiveSec",
[TIMER_BOOT] = "OnBootSec",
@@ -884,4 +893,5 @@ const UnitVTable timer_vtable = {
.bus_set_property = bus_timer_set_property,
.can_transient = true,
+ .test_start_limit = timer_test_start_limit,
};
diff --git a/src/core/unit.c b/src/core/unit.c
index 9013186d8a..f0df7452fa 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1728,10 +1728,16 @@ int unit_start(Unit *u) {
assert(u);
- /* If this is already started, then this will succeed. Note
- * that this will even succeed if this unit is not startable
- * by the user. This is relied on to detect when we need to
- * wait for units and when waiting is finished. */
+ /* Check start rate limiting early so that failure conditions don't cause us to enter a busy loop. */
+ if (UNIT_VTABLE(u)->test_start_limit) {
+ int r = UNIT_VTABLE(u)->test_start_limit(u);
+ if (r < 0)
+ return r;
+ }
+
+ /* If this is already started, then this will succeed. Note that this will even succeed if this unit
+ * is not startable by the user. This is relied on to detect when we need to wait for units and when
+ * waiting is finished. */
state = unit_active_state(u);
if (UNIT_IS_ACTIVE_OR_RELOADING(state))
return -EALREADY;
diff --git a/src/core/unit.h b/src/core/unit.h
index a8bc350b66..9e6f1bcf81 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -567,6 +567,10 @@ typedef struct UnitVTable {
/* The bus vtable */
const sd_bus_vtable *bus_vtable;
+ /* If this function is set, it's invoked first as part of starting a unit to allow start rate
+ * limiting checks to occur before we do anything else. */
+ int (*test_start_limit)(Unit *u);
+
/* The strings to print in status messages */
UnitStatusMessageFormats status_message_formats;

View File

@ -0,0 +1,226 @@
From 51210a849ea7f163a1760de989756206c01dd758 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 4 Oct 2021 19:44:06 +0200
Subject: [PATCH] sd-event: introduce callback invoked when event source
ratelimit expires
(cherry picked from commit fd69f2247520b0be3190ded96d646a415edc97b7)
Related: #2036608
---
src/libsystemd/libsystemd.sym | 5 +++
src/libsystemd/sd-event/sd-event.c | 61 +++++++++++++++++++++++-----
src/libsystemd/sd-event/test-event.c | 12 ++++++
src/systemd/sd-event.h | 1 +
4 files changed, 68 insertions(+), 11 deletions(-)
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index 149d2e7b82..f4a1426248 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -579,3 +579,8 @@ global:
sd_event_source_get_ratelimit;
sd_event_source_is_ratelimited;
} LIBSYSTEMD_239;
+
+LIBSYSTEMD_250 {
+global:
+ sd_event_source_set_ratelimit_expire_callback;
+} LIBSYSTEMD_248;
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index 47cf93b3f4..0adfdd9e1a 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -125,6 +125,7 @@ struct sd_event_source {
uint64_t prepare_iteration;
sd_event_destroy_t destroy_callback;
+ sd_event_handler_t ratelimit_expire_callback;
LIST_FIELDS(sd_event_source, sources);
@@ -2734,7 +2735,7 @@ fail:
return r;
}
-static int event_source_leave_ratelimit(sd_event_source *s) {
+static int event_source_leave_ratelimit(sd_event_source *s, bool run_callback) {
int r;
assert(s);
@@ -2766,6 +2767,23 @@ static int event_source_leave_ratelimit(sd_event_source *s) {
ratelimit_reset(&s->rate_limit);
log_debug("Event source %p (%s) left rate limit state.", s, strna(s->description));
+
+ if (run_callback && s->ratelimit_expire_callback) {
+ s->dispatching = true;
+ r = s->ratelimit_expire_callback(s, s->userdata);
+ s->dispatching = false;
+
+ if (r < 0) {
+ log_debug_errno(r, "Ratelimit expiry callback of event source %s (type %s) returned error, disabling: %m",
+ strna(s->description),
+ event_source_type_to_string(s->type));
+
+ sd_event_source_set_enabled(s, SD_EVENT_OFF);
+ }
+
+ return 1;
+ }
+
return 0;
fail:
@@ -2966,6 +2984,7 @@ static int process_timer(
struct clock_data *d) {
sd_event_source *s;
+ bool callback_invoked = false;
int r;
assert(e);
@@ -2981,9 +3000,11 @@ static int process_timer(
* again. */
assert(s->ratelimited);
- r = event_source_leave_ratelimit(s);
+ r = event_source_leave_ratelimit(s, /* run_callback */ true);
if (r < 0)
return r;
+ else if (r == 1)
+ callback_invoked = true;
continue;
}
@@ -2998,7 +3019,7 @@ static int process_timer(
event_source_time_prioq_reshuffle(s);
}
- return 0;
+ return callback_invoked;
}
static int process_child(sd_event *e) {
@@ -3698,15 +3719,15 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
if (r < 0)
goto finish;
- r = process_timer(e, e->timestamp.realtime, &e->realtime);
+ r = process_inotify(e);
if (r < 0)
goto finish;
- r = process_timer(e, e->timestamp.boottime, &e->boottime);
+ r = process_timer(e, e->timestamp.realtime, &e->realtime);
if (r < 0)
goto finish;
- r = process_timer(e, e->timestamp.monotonic, &e->monotonic);
+ r = process_timer(e, e->timestamp.boottime, &e->boottime);
if (r < 0)
goto finish;
@@ -3718,16 +3739,27 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
if (r < 0)
goto finish;
+ r = process_timer(e, e->timestamp.monotonic, &e->monotonic);
+ if (r < 0)
+ goto finish;
+ else if (r == 1) {
+ /* Ratelimit expiry callback was called. Let's postpone processing pending sources and
+ * put loop in the initial state in order to evaluate (in the next iteration) also sources
+ * there were potentially re-enabled by the callback.
+ *
+ * Wondering why we treat only this invocation of process_timer() differently? Once event
+ * source is ratelimited we essentially transform it into CLOCK_MONOTONIC timer hence
+ * ratelimit expiry callback is never called for any other timer type. */
+ r = 0;
+ goto finish;
+ }
+
if (e->need_process_child) {
r = process_child(e);
if (r < 0)
goto finish;
}
- r = process_inotify(e);
- if (r < 0)
- goto finish;
-
if (event_next_pending(e)) {
e->state = SD_EVENT_PENDING;
@@ -4054,7 +4086,7 @@ _public_ int sd_event_source_set_ratelimit(sd_event_source *s, uint64_t interval
/* When ratelimiting is configured we'll always reset the rate limit state first and start fresh,
* non-ratelimited. */
- r = event_source_leave_ratelimit(s);
+ r = event_source_leave_ratelimit(s, /* run_callback */ false);
if (r < 0)
return r;
@@ -4062,6 +4094,13 @@ _public_ int sd_event_source_set_ratelimit(sd_event_source *s, uint64_t interval
return 0;
}
+_public_ int sd_event_source_set_ratelimit_expire_callback(sd_event_source *s, sd_event_handler_t callback) {
+ assert_return(s, -EINVAL);
+
+ s->ratelimit_expire_callback = callback;
+ return 0;
+}
+
_public_ int sd_event_source_get_ratelimit(sd_event_source *s, uint64_t *ret_interval, unsigned *ret_burst) {
assert_return(s, -EINVAL);
diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c
index e3ee4cd5c3..9135b22839 100644
--- a/src/libsystemd/sd-event/test-event.c
+++ b/src/libsystemd/sd-event/test-event.c
@@ -506,6 +506,11 @@ static int ratelimit_time_handler(sd_event_source *s, uint64_t usec, void *userd
return 0;
}
+static int expired = -1;
+static int ratelimit_expired(sd_event_source *s, void *userdata) {
+ return ++expired;
+}
+
static void test_ratelimit(void) {
_cleanup_close_pair_ int p[2] = {-1, -1};
_cleanup_(sd_event_unrefp) sd_event *e = NULL;
@@ -568,12 +573,19 @@ static void test_ratelimit(void) {
assert_se(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 10) >= 0);
+ /* Set callback that will be invoked when we leave rate limited state. */
+ assert_se(sd_event_source_set_ratelimit_expire_callback(s, ratelimit_expired) >= 0);
+
do {
assert_se(sd_event_run(e, UINT64_MAX) >= 0);
} while (!sd_event_source_is_ratelimited(s));
log_info("ratelimit_time_handler: called 10 more times, event source got ratelimited");
assert_se(count == 20);
+
+ /* Dispatch the event loop once more and check that ratelimit expiration callback got called */
+ assert_se(sd_event_run(e, UINT64_MAX) >= 0);
+ assert_se(expired == 0);
}
int main(int argc, char *argv[]) {
diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h
index a17a9b3488..c2e9c9614d 100644
--- a/src/systemd/sd-event.h
+++ b/src/systemd/sd-event.h
@@ -147,6 +147,7 @@ int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t
int sd_event_source_set_ratelimit(sd_event_source *s, uint64_t interval_usec, unsigned burst);
int sd_event_source_get_ratelimit(sd_event_source *s, uint64_t *ret_interval_usec, unsigned *ret_burst);
int sd_event_source_is_ratelimited(sd_event_source *s);
+int sd_event_source_set_ratelimit_expire_callback(sd_event_source *s, sd_event_handler_t callback);
/* Define helpers so that __attribute__((cleanup(sd_event_unrefp))) and similar may be used. */
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_event, sd_event_unref);

View File

@ -0,0 +1,263 @@
From 3674514b7220a136dcfd464c205d41609f0c99a7 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 4 Oct 2021 17:51:52 +0200
Subject: [PATCH] core: rename/generalize UNIT(u)->test_start_limit() hook
Up until now the main reason why we didn't proceed with starting the
unit was exceed start limit burst. However, for unit types like mounts
the other reason could be effective ratelimit on /proc/self/mountinfo
event source. That means our mount unit state may not reflect current
kernel state. Hence, we need to attempt to re-run the start job again
after ratelimit on event source expires.
As we will be introducing another reason than start limit let's rename
the virtual function that implements the check.
(cherry picked from commit 705578c3b9d794097233aa66010cf67b2a444716)
Related: #2036608
---
src/core/automount.c | 6 +++---
src/core/mount.c | 6 +++---
src/core/path.c | 6 +++---
src/core/service.c | 6 +++---
src/core/socket.c | 6 +++---
src/core/swap.c | 6 +++---
src/core/timer.c | 6 +++---
src/core/unit.c | 6 +++---
src/core/unit.h | 2 +-
9 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/src/core/automount.c b/src/core/automount.c
index 5e16adabb5..f212620c8f 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -1071,7 +1071,7 @@ static bool automount_supported(void) {
return supported;
}
-static int automount_test_start_limit(Unit *u) {
+static int automount_can_start(Unit *u) {
Automount *a = AUTOMOUNT(u);
int r;
@@ -1083,7 +1083,7 @@ static int automount_test_start_limit(Unit *u) {
return r;
}
- return 0;
+ return 1;
}
static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
@@ -1145,5 +1145,5 @@ const UnitVTable automount_vtable = {
},
},
- .test_start_limit = automount_test_start_limit,
+ .can_start = automount_can_start,
};
diff --git a/src/core/mount.c b/src/core/mount.c
index 22848847e5..032a2ca156 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1951,7 +1951,7 @@ static int mount_control_pid(Unit *u) {
return m->control_pid;
}
-static int mount_test_start_limit(Unit *u) {
+static int mount_can_start(Unit *u) {
Mount *m = MOUNT(u);
int r;
@@ -1963,7 +1963,7 @@ static int mount_test_start_limit(Unit *u) {
return r;
}
- return 0;
+ return 1;
}
static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
@@ -2058,5 +2058,5 @@ const UnitVTable mount_vtable = {
},
},
- .test_start_limit = mount_test_start_limit,
+ .can_start = mount_can_start,
};
diff --git a/src/core/path.c b/src/core/path.c
index 1e69a1f05f..58f490589d 100644
--- a/src/core/path.c
+++ b/src/core/path.c
@@ -724,7 +724,7 @@ static void path_reset_failed(Unit *u) {
p->result = PATH_SUCCESS;
}
-static int path_test_start_limit(Unit *u) {
+static int path_can_start(Unit *u) {
Path *p = PATH(u);
int r;
@@ -736,7 +736,7 @@ static int path_test_start_limit(Unit *u) {
return r;
}
- return 0;
+ return 1;
}
static const char* const path_type_table[_PATH_TYPE_MAX] = {
@@ -792,5 +792,5 @@ const UnitVTable path_vtable = {
.bus_vtable = bus_path_vtable,
.bus_set_property = bus_path_set_property,
- .test_start_limit = path_test_start_limit,
+ .can_start = path_can_start,
};
diff --git a/src/core/service.c b/src/core/service.c
index c5f408d817..e8ae1a5772 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -4074,7 +4074,7 @@ static bool service_needs_console(Unit *u) {
SERVICE_FINAL_SIGKILL);
}
-static int service_test_start_limit(Unit *u) {
+static int service_can_start(Unit *u) {
Service *s = SERVICE(u);
int r;
@@ -4087,7 +4087,7 @@ static int service_test_start_limit(Unit *u) {
return r;
}
- return 0;
+ return 1;
}
static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
@@ -4232,5 +4232,5 @@ const UnitVTable service_vtable = {
},
},
- .test_start_limit = service_test_start_limit,
+ .can_start = service_can_start,
};
diff --git a/src/core/socket.c b/src/core/socket.c
index 36d2e4f823..3589300e68 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -3261,7 +3261,7 @@ static int socket_control_pid(Unit *u) {
return s->control_pid;
}
-static int socket_test_start_limit(Unit *u) {
+static int socket_can_start(Unit *u) {
Socket *s = SOCKET(u);
int r;
@@ -3273,7 +3273,7 @@ static int socket_test_start_limit(Unit *u) {
return r;
}
- return 0;
+ return 1;
}
static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
@@ -3369,5 +3369,5 @@ const UnitVTable socket_vtable = {
},
},
- .test_start_limit = socket_test_start_limit,
+ .can_start = socket_can_start,
};
diff --git a/src/core/swap.c b/src/core/swap.c
index 90fcd69300..498c5a6d69 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -1452,7 +1452,7 @@ static int swap_control_pid(Unit *u) {
return s->control_pid;
}
-static int swap_test_start_limit(Unit *u) {
+static int swap_can_start(Unit *u) {
Swap *s = SWAP(u);
int r;
@@ -1464,7 +1464,7 @@ static int swap_test_start_limit(Unit *u) {
return r;
}
- return 0;
+ return 1;
}
static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
@@ -1557,5 +1557,5 @@ const UnitVTable swap_vtable = {
},
},
- .test_start_limit = swap_test_start_limit,
+ .can_start = swap_can_start,
};
diff --git a/src/core/timer.c b/src/core/timer.c
index fb9ae17990..684180bf99 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -823,7 +823,7 @@ static void timer_timezone_change(Unit *u) {
timer_enter_waiting(t, false);
}
-static int timer_test_start_limit(Unit *u) {
+static int timer_can_start(Unit *u) {
Timer *t = TIMER(u);
int r;
@@ -835,7 +835,7 @@ static int timer_test_start_limit(Unit *u) {
return r;
}
- return 0;
+ return 1;
}
static const char* const timer_base_table[_TIMER_BASE_MAX] = {
@@ -893,5 +893,5 @@ const UnitVTable timer_vtable = {
.bus_set_property = bus_timer_set_property,
.can_transient = true,
- .test_start_limit = timer_test_start_limit,
+ .can_start = timer_can_start,
};
diff --git a/src/core/unit.c b/src/core/unit.c
index f0df7452fa..4de218feac 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1728,9 +1728,9 @@ int unit_start(Unit *u) {
assert(u);
- /* Check start rate limiting early so that failure conditions don't cause us to enter a busy loop. */
- if (UNIT_VTABLE(u)->test_start_limit) {
- int r = UNIT_VTABLE(u)->test_start_limit(u);
+ /* Check our ability to start early so that failure conditions don't cause us to enter a busy loop. */
+ if (UNIT_VTABLE(u)->can_start) {
+ int r = UNIT_VTABLE(u)->can_start(u);
if (r < 0)
return r;
}
diff --git a/src/core/unit.h b/src/core/unit.h
index 9e6f1bcf81..0cd259411f 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -569,7 +569,7 @@ typedef struct UnitVTable {
/* If this function is set, it's invoked first as part of starting a unit to allow start rate
* limiting checks to occur before we do anything else. */
- int (*test_start_limit)(Unit *u);
+ int (*can_start)(Unit *u);
/* The strings to print in status messages */
UnitStatusMessageFormats status_message_formats;

View File

@ -0,0 +1,27 @@
From cb519c7d769851ee5e24c797fc04eaa13383c674 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 4 Oct 2021 19:41:34 +0200
Subject: [PATCH] mount: make mount units start jobs not runnable if
/p/s/mountinfo ratelimit is in effect
(cherry picked from commit a7c93dfe91e88a5a561341c523a45c7f8d71a588)
Related: #2036608
---
src/core/mount.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/core/mount.c b/src/core/mount.c
index 032a2ca156..ab09e6fbb0 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1957,6 +1957,9 @@ static int mount_can_start(Unit *u) {
assert(m);
+ if (sd_event_source_is_ratelimited(u->manager->mount_event_source))
+ return -EAGAIN;
+
r = unit_test_start_limit(u);
if (r < 0) {
mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT);

View File

@ -0,0 +1,54 @@
From b0c226e9fd3e6bfa5388832cc2745d9ec935f3ec Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 4 Oct 2021 20:31:49 +0200
Subject: [PATCH] mount: retrigger run queue after ratelimit expired to run
delayed mount start jobs
Fixes #20329
(cherry picked from commit edc027b4f1cfaa49e8ecdde763eb8c623402d464)
Related: #2036608
---
src/core/mount.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/src/core/mount.c b/src/core/mount.c
index ab09e6fbb0..bdba9e6884 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1710,6 +1710,21 @@ static bool mount_is_mounted(Mount *m) {
return UNIT(m)->perpetual || m->is_mounted;
}
+static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) {
+ Manager *m = userdata;
+ int r;
+
+ assert(m);
+
+ /* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so let's
+ * make sure we dispatch them in the next iteration. */
+ r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_ONESHOT);
+ if (r < 0)
+ log_debug_errno(r, "Failed to enable run queue event source, ignoring: %m");
+
+ return 0;
+}
+
static void mount_enumerate(Manager *m) {
int r;
@@ -1763,6 +1778,12 @@ static void mount_enumerate(Manager *m) {
goto fail;
}
+ r = sd_event_source_set_ratelimit_expire_callback(m->mount_event_source, mount_on_ratelimit_expire);
+ if (r < 0) {
+ log_error_errno(r, "Failed to enable rate limit for mount events: %m");
+ goto fail;
+ }
+
(void) sd_event_source_set_description(m->mount_event_source, "mount-monitor-dispatch");
}

View File

@ -0,0 +1,98 @@
From 5a218b6820be7ffaf21cd42cd4c96b47d18442ee Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 12 Nov 2021 09:43:07 +0100
Subject: [PATCH] pid1: add a manager_trigger_run_queue() helper
We have two different places where we re-trigger the run queue now.
let's unify it under a common function, that is part of the Manager
code.
Follow-up for #20953
(cherry picked from commit b0c4b2824693fe6a27ea9439ec7a6328a0e23704)
Related: #2036608
---
src/core/job.c | 5 ++---
src/core/manager.c | 12 ++++++++++++
src/core/manager.h | 2 ++
src/core/mount.c | 9 +++------
4 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/src/core/job.c b/src/core/job.c
index 43ab55ed18..55f36b928f 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -1139,11 +1139,10 @@ void job_add_to_run_queue(Job *j) {
if (j->in_run_queue)
return;
- if (!j->manager->run_queue)
- sd_event_source_set_enabled(j->manager->run_queue_event_source, SD_EVENT_ONESHOT);
-
LIST_PREPEND(run_queue, j->manager->run_queue, j);
j->in_run_queue = true;
+
+ manager_trigger_run_queue(j->manager);
}
void job_add_to_dbus_queue(Job *j) {
diff --git a/src/core/manager.c b/src/core/manager.c
index ee976f70b3..845c26f498 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -2120,6 +2120,18 @@ static int manager_dispatch_run_queue(sd_event_source *source, void *userdata) {
return 1;
}
+void manager_trigger_run_queue(Manager *m) {
+ int r;
+
+ assert(m);
+
+ r = sd_event_source_set_enabled(
+ m->run_queue_event_source,
+ m->run_queue ? SD_EVENT_ONESHOT: SD_EVENT_OFF);
+ if (r < 0)
+ log_warning_errno(r, "Failed to enable job run queue event source, ignoring: %m");
+}
+
static unsigned manager_dispatch_dbus_queue(Manager *m) {
unsigned n = 0, budget;
Unit *u;
diff --git a/src/core/manager.h b/src/core/manager.h
index c4b8e80093..7b572c8dfd 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -416,6 +416,8 @@ unsigned manager_dispatch_load_queue(Manager *m);
int manager_environment_add(Manager *m, char **minus, char **plus);
int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit);
+void manager_trigger_run_queue(Manager *m);
+
int manager_loop(Manager *m);
int manager_open_serialization(Manager *m, FILE **_f);
diff --git a/src/core/mount.c b/src/core/mount.c
index bdba9e6884..c17154cde1 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1712,15 +1712,12 @@ static bool mount_is_mounted(Mount *m) {
static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) {
Manager *m = userdata;
- int r;
assert(m);
- /* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so let's
- * make sure we dispatch them in the next iteration. */
- r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_ONESHOT);
- if (r < 0)
- log_debug_errno(r, "Failed to enable run queue event source, ignoring: %m");
+ /* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so
+ * let's make sure we dispatch them in the next iteration. */
+ manager_trigger_run_queue(m);
return 0;
}

View File

@ -0,0 +1,46 @@
From dd662fc39a28655b89619a828a15e5e457bf6f4c Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 25 Nov 2021 18:28:25 +0100
Subject: [PATCH] unit: add jobs that were skipped because of ratelimit back to
run_queue
Assumption in edc027b was that job we first skipped because of active
ratelimit is still in run_queue. Hence we trigger the queue and dispatch
it in the next iteration. Actually we remove jobs from run_queue in
job_run_and_invalidate() before we call unit_start(). Hence if we want
to attempt to run the job again in the future we need to add it back
to run_queue.
Fixes #21458
(cherry picked from commit c29e6a9530316823b0455cd83eb6d0bb8dd664f4)
Related: #2036608
---
src/core/mount.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/core/mount.c b/src/core/mount.c
index c17154cde1..691b23ca74 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1712,9 +1712,19 @@ static bool mount_is_mounted(Mount *m) {
static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) {
Manager *m = userdata;
+ Job *j;
+ Iterator i;
assert(m);
+ /* Let's enqueue all start jobs that were previously skipped because of active ratelimit. */
+ HASHMAP_FOREACH(j, m->jobs, i) {
+ if (j->unit->type != UNIT_MOUNT)
+ continue;
+
+ job_add_to_run_queue(j);
+ }
+
/* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so
* let's make sure we dispatch them in the next iteration. */
manager_trigger_run_queue(m);

View File

@ -0,0 +1,37 @@
From 54faef034bb2062ed8afa72e2c1be40ef7cc41c5 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 26 Jul 2019 09:25:09 +0200
Subject: [PATCH] Revert "Revert "sysctl: Enable ping(8) inside rootless Podman
containers""
This reverts commit be74f51605b4c7cb74fec3a50cd13b67598a8ac1.
Let's add this again. With the new sysctl "-" thing we can make this
work.
Resolves: #2037807
(cherry picked from commit 0338934f4bcda6a96a5342449ae96b003de3378d)
---
sysctl.d/50-default.conf | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf
index e0afc9c702..21ae1df13d 100644
--- a/sysctl.d/50-default.conf
+++ b/sysctl.d/50-default.conf
@@ -33,6 +33,14 @@ net.ipv4.conf.all.accept_source_route = 0
# Promote secondary addresses when the primary address is removed
net.ipv4.conf.all.promote_secondaries = 1
+# ping(8) without CAP_NET_ADMIN and CAP_NET_RAW
+# The upper limit is set to 2^31-1. Values greater than that get rejected by
+# the kernel because of this definition in linux/include/net/ping.h:
+# #define GID_T_MAX (((gid_t)~0U) >> 1)
+# That's not so bad because values between 2^31 and 2^32-1 are reserved on
+# systemd-based systems anyway: https://systemd.io/UIDS-GIDS.html#summary
+net.ipv4.ping_group_range = 0 2147483647
+
# Fair Queue CoDel packet scheduler to fight bufferbloat
net.core.default_qdisc = fq_codel

View File

@ -0,0 +1,27 @@
From 41a32aeaf5d33f253f48bfbe8d00de9d160985f7 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 26 Jul 2019 09:26:07 +0200
Subject: [PATCH] sysctl: prefix ping port range setting with a dash
Fixes: #13177
Resolves: #2037807
(cherry picked from commit 000500c9d6347e0e2cdb92ec48fa10c0bb3ceca8)
---
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 21ae1df13d..5156d55ca9 100644
--- a/sysctl.d/50-default.conf
+++ b/sysctl.d/50-default.conf
@@ -39,7 +39,7 @@ net.ipv4.conf.all.promote_secondaries = 1
# #define GID_T_MAX (((gid_t)~0U) >> 1)
# That's not so bad because values between 2^31 and 2^32-1 are reserved on
# systemd-based systems anyway: https://systemd.io/UIDS-GIDS.html#summary
-net.ipv4.ping_group_range = 0 2147483647
+-net.ipv4.ping_group_range = 0 2147483647
# Fair Queue CoDel packet scheduler to fight bufferbloat
net.core.default_qdisc = fq_codel

View File

@ -0,0 +1,56 @@
From c236734f95550747c4979fe318e3a890adaa0a94 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 28 Nov 2018 12:41:44 +0100
Subject: [PATCH] mount: don't propagate errors from mount_setup_unit() further
up
If we can't process a specific line in /proc/self/mountinfo we should
log about it (which we do), but this should not affect other lines, nor
further processing of mount units. Let's keep these failures local.
Fixes: #10874
Cherry picked from commit ba0d56f55f2073164799be714b5bd1aad94d059a.
Trivial conflict in src/core/mount.c, function mount_load_proc_self_mountinfo,
due to local commit ca634baa10e. Also, due to the same commit, int k
is no longer used and is thus removed.
Resolves: #2036853
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
---
src/core/mount.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/core/mount.c b/src/core/mount.c
index 691b23ca74..4e0a4f238a 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1615,12 +1615,10 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
if (r < 0)
return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
- r = 0;
for (;;) {
struct libmnt_fs *fs;
const char *device, *path, *options, *fstype;
_cleanup_free_ char *d = NULL, *p = NULL;
- int k;
r = mnt_table_next_fs(table, iter, &fs);
if (r == 1)
@@ -1644,12 +1642,10 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
device_found_node(m, d, DEVICE_FOUND_MOUNT, DEVICE_FOUND_MOUNT);
- k = mount_setup_unit(m, d, p, options, fstype, set_flags);
- if (r == 0 && k < 0)
- r = k;
+ (void) mount_setup_unit(m, d, p, options, fstype, set_flags);
}
- return r;
+ return 0;
}
static void mount_shutdown(Manager *m) {

View File

@ -13,7 +13,7 @@
Name: systemd
Url: http://www.freedesktop.org/wiki/Software/systemd
Version: 239
Release: 54%{?dist}
Release: 55%{?dist}
# For a breakdown of the licensing, see README
License: LGPLv2+ and MIT and GPLv2+
Summary: System and Service Manager
@ -729,6 +729,28 @@ Patch0676: 0676-tests-add-helper-function-to-autodetect-CI-environme.patch
Patch0677: 0677-strv-rework-FOREACH_STRING-macro.patch
Patch0678: 0678-test-systemctl-use-const-char-instead-of-char.patch
Patch0679: 0679-ci-pass-the-GITHUB_ACTIONS-variable-to-the-CentOS-co.patch
Patch0680: 0680-lgtm-detect-uninitialized-variables-using-the-__clea.patch
Patch0681: 0681-lgtm-replace-the-query-used-for-looking-for-fgets-wi.patch
Patch0682: 0682-lgtm-beef-up-list-of-dangerous-questionnable-API-cal.patch
Patch0683: 0683-lgtm-warn-about-strerror-use.patch
Patch0684: 0684-lgtm-complain-about-accept-people-should-use-accept4.patch
Patch0685: 0685-lgtm-don-t-treat-the-custom-note-as-a-list-of-tags.patch
Patch0686: 0686-lgtm-ignore-certain-cleanup-functions.patch
Patch0687: 0687-lgtm-detect-more-possible-problematic-scenarios.patch
Patch0688: 0688-lgtm-enable-more-and-potentially-useful-queries.patch
Patch0689: 0689-meson-avoid-bogus-meson-warning.patch
Patch0690: 0690-test-make-TEST-47-less-racy.patch
Patch0691: 0691-core-rename-unit_-start_limit-condition-assert-_test.patch
Patch0692: 0692-core-Check-unit-start-rate-limiting-earlier.patch
Patch0693: 0693-sd-event-introduce-callback-invoked-when-event-sourc.patch
Patch0694: 0694-core-rename-generalize-UNIT-u-test_start_limit-hook.patch
Patch0695: 0695-mount-make-mount-units-start-jobs-not-runnable-if-p-.patch
Patch0696: 0696-mount-retrigger-run-queue-after-ratelimit-expired-to.patch
Patch0697: 0697-pid1-add-a-manager_trigger_run_queue-helper.patch
Patch0698: 0698-unit-add-jobs-that-were-skipped-because-of-ratelimit.patch
Patch0699: 0699-Revert-Revert-sysctl-Enable-ping-8-inside-rootless-P.patch
Patch0700: 0700-sysctl-prefix-ping-port-range-setting-with-a-dash.patch
Patch0701: 0701-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch
%ifarch %{ix86} x86_64 aarch64
@ -1356,6 +1378,29 @@ fi
%files tests -f .file-list-tests
%changelog
* Mon Jan 10 2022 systemd maintenance team <systemd-maint@redhat.com> - 239-55
- lgtm: detect uninitialized variables using the __cleanup__ attribute (#2017033)
- lgtm: replace the query used for looking for fgets with a more general query (#2017033)
- lgtm: beef up list of dangerous/questionnable API calls not to make (#2017033)
- lgtm: warn about strerror() use (#2017033)
- lgtm: complain about accept() [people should use accept4() instead, due to O_CLOEXEC] (#2017033)
- lgtm: don't treat the custom note as a list of tags (#2017033)
- lgtm: ignore certain cleanup functions (#2017033)
- lgtm: detect more possible problematic scenarios (#2017033)
- lgtm: enable more (and potentially useful) queries (#2017033)
- test: make TEST-47 less racy (#2017033)
- core: rename unit_{start_limit|condition|assert}_test() to unit_test_xyz() (#2036608)
- core: Check unit start rate limiting earlier (#2036608)
- sd-event: introduce callback invoked when event source ratelimit expires (#2036608)
- core: rename/generalize UNIT(u)->test_start_limit() hook (#2036608)
- mount: make mount units start jobs not runnable if /p/s/mountinfo ratelimit is in effect (#2036608)
- mount: retrigger run queue after ratelimit expired to run delayed mount start jobs (#2036608)
- pid1: add a manager_trigger_run_queue() helper (#2036608)
- unit: add jobs that were skipped because of ratelimit back to run_queue (#2036608)
- Revert "Revert "sysctl: Enable ping(8) inside rootless Podman containers"" (#2037807)
- sysctl: prefix ping port range setting with a dash (#2037807)
- mount: don't propagate errors from mount_setup_unit() further up (#2036853)
* Wed Dec 01 2021 systemd maintenance team <systemd-maint@redhat.com> - 239-54
- core: consider service with no start command immediately started (#1860899)
- man: move description of *Action= modes to FailureAction=/SuccessAction= (#1860899)