77 lines
3.0 KiB
Diff
77 lines
3.0 KiB
Diff
From 03101b5186a43b893165f44726f4865702005d8e Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
Date: Fri, 7 Oct 2022 17:34:53 +0200
|
|
Subject: [PATCH] shared/condition: avoid nss lookup in PID1
|
|
|
|
PID 1 is not allowed to do nss lookups because this may take a long time or
|
|
even deadlock.
|
|
|
|
While at it, the comparisons are reordered to do the "easy" comparisons which
|
|
only require a string comparison first. Delay parsing of the UID until it is
|
|
really necessary. The result is the same, because we know that "root" and
|
|
"nobody" parse as valid.
|
|
|
|
(cherry picked from commit 734f96b8490a2c48712ff6754a84fcaeac3d53c1)
|
|
(cherry picked from commit 5da595db39e8c6b229dfe388130683ff9a32eda5)
|
|
(cherry picked from commit 4ddeea92faf69291449af95dc9ba6440ad06ec1b)
|
|
|
|
Conflict:NA
|
|
Reference:https://github.com/systemd/systemd/commit/03101b5186a43b893165f44726f4865702005d8e
|
|
---
|
|
src/shared/condition.c | 23 ++++++++++++++---------
|
|
1 file changed, 14 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/src/shared/condition.c b/src/shared/condition.c
|
|
index b0520566ed..ed7de273bf 100644
|
|
--- a/src/shared/condition.c
|
|
+++ b/src/shared/condition.c
|
|
@@ -373,31 +373,36 @@ static int condition_test_cpus(Condition *c, char **env) {
|
|
static int condition_test_user(Condition *c, char **env) {
|
|
uid_t id;
|
|
int r;
|
|
- _cleanup_free_ char *username = NULL;
|
|
- const char *u;
|
|
|
|
assert(c);
|
|
assert(c->parameter);
|
|
assert(c->type == CONDITION_USER);
|
|
|
|
+ /* Do the quick&easy comparisons first, and only parse the UID later. */
|
|
+ if (streq(c->parameter, "root"))
|
|
+ return getuid() == 0 || geteuid() == 0;
|
|
+ if (streq(c->parameter, NOBODY_USER_NAME))
|
|
+ return getuid() == UID_NOBODY || geteuid() == UID_NOBODY;
|
|
+ if (streq(c->parameter, "@system"))
|
|
+ return uid_is_system(getuid()) || uid_is_system(geteuid());
|
|
+
|
|
r = parse_uid(c->parameter, &id);
|
|
if (r >= 0)
|
|
return id == getuid() || id == geteuid();
|
|
|
|
- if (streq("@system", c->parameter))
|
|
- return uid_is_system(getuid()) || uid_is_system(geteuid());
|
|
+ if (getpid_cached() == 1) /* We already checked for "root" above, and we know that
|
|
+ * PID 1 is running as root, hence we know it cannot match. */
|
|
+ return false;
|
|
|
|
- username = getusername_malloc();
|
|
+ /* getusername_malloc() may do an nss lookup, which is not allowed in PID 1. */
|
|
+ _cleanup_free_ char *username = getusername_malloc();
|
|
if (!username)
|
|
return -ENOMEM;
|
|
|
|
if (streq(username, c->parameter))
|
|
return 1;
|
|
|
|
- if (getpid_cached() == 1)
|
|
- return streq(c->parameter, "root");
|
|
-
|
|
- u = c->parameter;
|
|
+ const char *u = c->parameter;
|
|
r = get_user_creds(&u, &id, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING);
|
|
if (r < 0)
|
|
return 0;
|
|
--
|
|
2.27.0
|
|
|