1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-02-09 09:57:26 +03:00

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.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2022-10-07 17:34:53 +02:00
parent 9154bd57db
commit 734f96b849

View File

@ -338,31 +338,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;