CVE-2020-13776
This commit is contained in:
parent
54e8778bc2
commit
9c9e3cf238
@ -0,0 +1,105 @@
|
||||
From 93c23c9297e48e594785e0bb9c51504aae5fbe3e Mon Sep 17 00:00:00 2001
|
||||
From: Balint Reczey <balint.reczey@canonical.com>
|
||||
Date: Wed, 18 Mar 2020 18:29:02 +0100
|
||||
Subject: [PATCH] user-util: Allow names starting with a digit
|
||||
|
||||
In 1a29610f5fa1bcb2eeb37d2c6b79d8d1a6dbb865 the change inadvertedly
|
||||
disabled names with digit as the first character. This follow-up change
|
||||
allows a digit as the first character in compat mode.
|
||||
|
||||
Fixes: #15141
|
||||
Reference: https://github.com/systemd/systemd/commit/93c23c9297e48e594785e0bb9c51504aae5fbe3e
|
||||
Conflict: NA
|
||||
---
|
||||
src/basic/user-util.c | 20 +++++++++++++++++---
|
||||
src/test/test-user-util.c | 4 ++--
|
||||
2 files changed, 19 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
|
||||
index a491f5505e..e998a46e72 100644
|
||||
--- a/src/basic/user-util.c
|
||||
+++ b/src/basic/user-util.c
|
||||
@@ -701,16 +701,18 @@ int take_etc_passwd_lock(const char *root) {
|
||||
bool valid_user_group_name_full(const char *u, bool strict) {
|
||||
const char *i;
|
||||
long sz;
|
||||
+ bool warned = false;
|
||||
|
||||
/* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition,
|
||||
* 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules:
|
||||
*
|
||||
* - We require that names fit into the appropriate utmp field
|
||||
* - We don't allow empty user names
|
||||
- * - No dots or digits in the first character
|
||||
+ * - No dots in the first character
|
||||
*
|
||||
* If strict==true, additionally:
|
||||
* - We don't allow any dots (this conflicts with chown syntax which permits dots as user/group name separator)
|
||||
+ * - We don't allow a digit as the first character
|
||||
*
|
||||
* Note that other systems are even more restrictive, and don't permit underscores or uppercase characters.
|
||||
*/
|
||||
@@ -720,17 +722,26 @@ bool valid_user_group_name_full(const char *u, bool strict) {
|
||||
|
||||
if (!(u[0] >= 'a' && u[0] <= 'z') &&
|
||||
!(u[0] >= 'A' && u[0] <= 'Z') &&
|
||||
+ !(u[0] >= '0' && u[0] <= '9' && !strict) &&
|
||||
u[0] != '_')
|
||||
return false;
|
||||
|
||||
- bool warned = false;
|
||||
+ bool only_digits_seen = u[0] >= '0' && u[0] <= '9';
|
||||
+
|
||||
+ if (only_digits_seen) {
|
||||
+ log_warning("User or group name \"%s\" starts with a digit, accepting for compatibility.", u);
|
||||
+ warned = true;
|
||||
+ }
|
||||
|
||||
for (i = u+1; *i; i++) {
|
||||
if (((*i >= 'a' && *i <= 'z') ||
|
||||
(*i >= 'A' && *i <= 'Z') ||
|
||||
(*i >= '0' && *i <= '9') ||
|
||||
- IN_SET(*i, '_', '-')))
|
||||
+ IN_SET(*i, '_', '-'))) {
|
||||
+ if (!(*i >= '0' && *i <= '9'))
|
||||
+ only_digits_seen = false;
|
||||
continue;
|
||||
+ }
|
||||
|
||||
if (*i == '.' && !strict) {
|
||||
if (!warned) {
|
||||
@@ -744,6 +755,9 @@ bool valid_user_group_name_full(const char *u, bool strict) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+ if (only_digits_seen)
|
||||
+ return false;
|
||||
+
|
||||
sz = sysconf(_SC_LOGIN_NAME_MAX);
|
||||
assert_se(sz > 0);
|
||||
|
||||
diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c
|
||||
index 084a584876..11c01e5189 100644
|
||||
--- a/src/test/test-user-util.c
|
||||
+++ b/src/test/test-user-util.c
|
||||
@@ -96,7 +96,7 @@ static void test_valid_user_group_name_compat(void) {
|
||||
assert_se(valid_user_group_name_compat("eff."));
|
||||
|
||||
assert_se(valid_user_group_name_compat("some5"));
|
||||
- assert_se(!valid_user_group_name_compat("5some"));
|
||||
+ assert_se(valid_user_group_name_compat("5some"));
|
||||
assert_se(valid_user_group_name_compat("INNER5NUMBER"));
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ static void test_valid_user_group_name_or_id_compat(void) {
|
||||
assert_se(valid_user_group_name_or_id_compat("kk-k"));
|
||||
|
||||
assert_se(valid_user_group_name_or_id_compat("some5"));
|
||||
- assert_se(!valid_user_group_name_or_id_compat("5some"));
|
||||
+ assert_se(valid_user_group_name_or_id_compat("5some"));
|
||||
assert_se(valid_user_group_name_or_id_compat("INNER5NUMBER"));
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
From a85daa0dfb3eb03be9845760e90e54b9af8fb00e Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Mon, 30 Mar 2020 21:46:01 +0200
|
||||
Subject: [PATCH] user-util: switch order of checks in
|
||||
valid_user_group_name_or_id_full()
|
||||
|
||||
When we are supposed to accept numeric UIDs formatted as string, then
|
||||
let's check that first, before passing things on to
|
||||
valid_user_group_name_full(), since that might log about, and not the
|
||||
other way round.
|
||||
|
||||
See: #15201
|
||||
Follow-up for: 93c23c9297e48e594785e0bb9c51504aae5fbe3e
|
||||
Reference: https://github.com/systemd/systemd/commit/a85daa0dfb3eb03be9845760e90e54b9af8fb00e
|
||||
Conflict: NA
|
||||
---
|
||||
src/basic/user-util.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
|
||||
index e998a46e72..1510fc96ef 100644
|
||||
--- a/src/basic/user-util.c
|
||||
+++ b/src/basic/user-util.c
|
||||
@@ -778,10 +778,10 @@ bool valid_user_group_name_or_id_full(const char *u, bool strict) {
|
||||
if (isempty(u))
|
||||
return false;
|
||||
|
||||
- if (valid_user_group_name_full(u, strict))
|
||||
+ if (parse_uid(u, NULL) >= 0)
|
||||
return true;
|
||||
|
||||
- return parse_uid(u, NULL) >= 0;
|
||||
+ return valid_user_group_name_full(u, strict);
|
||||
}
|
||||
|
||||
bool valid_gecos(const char *d) {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,793 @@
|
||||
From 7a8867abfab10e5bbca10590ec2aa40c5b27d8fb Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Sat, 4 Apr 2020 12:23:02 +0200
|
||||
Subject: [PATCH] user-util: rework how we validate user names
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This reworks the user validation infrastructure. There are now two
|
||||
modes. In regular mode we are strict and test against a strict set of
|
||||
valid chars. And in "relaxed" mode we just filter out some really
|
||||
obvious, dangerous stuff. i.e. strict is whitelisting what is OK, but
|
||||
"relaxed" is blacklisting what is really not OK.
|
||||
|
||||
The idea is that we use strict mode whenver we allocate a new user
|
||||
(i.e. in sysusers.d or homed), while "relaxed" mode is when we process
|
||||
users registered elsewhere, (i.e. userdb, logind, …)
|
||||
|
||||
The requirements on user name validity vary wildly. SSSD thinks its fine
|
||||
to embedd "@" for example, while the suggested NAME_REGEX field on
|
||||
Debian does not even allow uppercase chars…
|
||||
|
||||
This effectively liberaralizes a lot what we expect from usernames.
|
||||
|
||||
The code that warns about questionnable user names is now optional and
|
||||
only used at places such as unit file parsing, so that it doesn't show
|
||||
up on every userdb query, but only when processing configuration files
|
||||
that know better.
|
||||
|
||||
Fixes: #15149 #15090
|
||||
Reference: https://github.com/systemd/systemd/commit/7a8867abfab10e5bbca10590ec2aa40c5b27d8fb
|
||||
Conflict: Remove unneeded file and change the context.
|
||||
---
|
||||
src/basic/user-util.c | 185 +++++++++++++----------
|
||||
src/basic/user-util.h | 21 +--
|
||||
src/core/dbus-execute.c | 6 +-
|
||||
src/core/dbus-manager.c | 2 +-
|
||||
src/core/dbus-socket.c | 4 +-
|
||||
src/core/dbus-util.c | 7 +-
|
||||
src/core/dbus-util.h | 2 +-
|
||||
src/core/dynamic-user.c | 2 +-
|
||||
src/core/load-fragment.c | 4 +-
|
||||
src/core/unit.c | 2 +-
|
||||
src/nss-systemd/nss-systemd.c | 6 +-
|
||||
src/systemd/sd-messages.h | 3 +
|
||||
src/sysusers/sysusers.c | 4 +-
|
||||
src/test/test-user-util.c | 271 ++++++++++++++++++----------------
|
||||
14 files changed, 287 insertions(+), 232 deletions(-)
|
||||
|
||||
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
|
||||
index 1510fc96ef..2e3580017d 100644
|
||||
--- a/src/basic/user-util.c
|
||||
+++ b/src/basic/user-util.c
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
|
||||
+#include "sd-messages.h"
|
||||
+
|
||||
#include "alloc-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
@@ -698,90 +701,123 @@ int take_etc_passwd_lock(const char *root) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
-bool valid_user_group_name_full(const char *u, bool strict) {
|
||||
+bool valid_user_group_name(const char *u, ValidUserFlags flags) {
|
||||
const char *i;
|
||||
- long sz;
|
||||
- bool warned = false;
|
||||
|
||||
- /* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition,
|
||||
- * 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules:
|
||||
- *
|
||||
- * - We require that names fit into the appropriate utmp field
|
||||
- * - We don't allow empty user names
|
||||
- * - No dots in the first character
|
||||
- *
|
||||
- * If strict==true, additionally:
|
||||
- * - We don't allow any dots (this conflicts with chown syntax which permits dots as user/group name separator)
|
||||
- * - We don't allow a digit as the first character
|
||||
+ /* Checks if the specified name is a valid user/group name. There are two flavours of this call:
|
||||
+ * strict mode is the default which is POSIX plus some extra rules; and relaxed mode where we accept
|
||||
+ * pretty much everything except the really worst offending names.
|
||||
*
|
||||
- * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters.
|
||||
- */
|
||||
+ * Whenever we synthesize users ourselves we should use the strict mode. But when we process users
|
||||
+ * created by other stuff, let's be more liberal. */
|
||||
|
||||
- if (isempty(u))
|
||||
+ if (isempty(u)) /* An empty user name is never valid */
|
||||
return false;
|
||||
|
||||
- if (!(u[0] >= 'a' && u[0] <= 'z') &&
|
||||
- !(u[0] >= 'A' && u[0] <= 'Z') &&
|
||||
- !(u[0] >= '0' && u[0] <= '9' && !strict) &&
|
||||
- u[0] != '_')
|
||||
- return false;
|
||||
-
|
||||
- bool only_digits_seen = u[0] >= '0' && u[0] <= '9';
|
||||
+ if (parse_uid(u, NULL) >= 0) /* Something that parses as numeric UID string is valid exactly when the
|
||||
+ * flag for it is set */
|
||||
+ return FLAGS_SET(flags, VALID_USER_ALLOW_NUMERIC);
|
||||
+
|
||||
+ if (FLAGS_SET(flags, VALID_USER_RELAX)) {
|
||||
+
|
||||
+ /* In relaxed mode we just check very superficially. Apparently SSSD and other stuff is
|
||||
+ * extremely liberal (way too liberal if you ask me, even inserting "@" in user names, which
|
||||
+ * is bound to cause problems for example when used with an MTA), hence only filter the most
|
||||
+ * obvious cases, or where things would result in an invalid entry if such a user name would
|
||||
+ * show up in /etc/passwd (or equivalent getent output).
|
||||
+ *
|
||||
+ * Note that we stepped far out of POSIX territory here. It's not our fault though, but
|
||||
+ * SSSD's, Samba's and everybody else who ignored POSIX on this. (I mean, I am happy to step
|
||||
+ * outside of POSIX' bounds any day, but I must say in this case I probably wouldn't
|
||||
+ * have...) */
|
||||
+
|
||||
+ if (startswith(u, " ") || endswith(u, " ")) /* At least expect whitespace padding is removed
|
||||
+ * at front and back (accept in the middle, since
|
||||
+ * that's apparently a thing on Windows). Note
|
||||
+ * that this also blocks usernames consisting of
|
||||
+ * whitespace only. */
|
||||
+ return false;
|
||||
|
||||
- if (only_digits_seen) {
|
||||
- log_warning("User or group name \"%s\" starts with a digit, accepting for compatibility.", u);
|
||||
- warned = true;
|
||||
- }
|
||||
+ if (!utf8_is_valid(u)) /* We want to synthesize JSON from this, hence insist on UTF-8 */
|
||||
+ return false;
|
||||
|
||||
- for (i = u+1; *i; i++) {
|
||||
- if (((*i >= 'a' && *i <= 'z') ||
|
||||
- (*i >= 'A' && *i <= 'Z') ||
|
||||
- (*i >= '0' && *i <= '9') ||
|
||||
- IN_SET(*i, '_', '-'))) {
|
||||
- if (!(*i >= '0' && *i <= '9'))
|
||||
- only_digits_seen = false;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- if (*i == '.' && !strict) {
|
||||
- if (!warned) {
|
||||
- log_warning("Bad user or group name \"%s\", accepting for compatibility.", u);
|
||||
- warned = true;
|
||||
- }
|
||||
-
|
||||
- continue;
|
||||
- }
|
||||
+ if (string_has_cc(u, NULL)) /* CC characters are just dangerous (and \n in particular is the
|
||||
+ * record separator in /etc/passwd), so we can't allow that. */
|
||||
+ return false;
|
||||
|
||||
- return false;
|
||||
- }
|
||||
+ if (strpbrk(u, ":/")) /* Colons are the field separator in /etc/passwd, we can't allow
|
||||
+ * that. Slashes are special to file systems paths and user names
|
||||
+ * typically show up in the file system as home directories, hence
|
||||
+ * don't allow slashes. */
|
||||
+ return false;
|
||||
|
||||
- if (only_digits_seen)
|
||||
- return false;
|
||||
+ if (in_charset(u, "0123456789")) /* Don't allow fully numeric strings, they might be confused
|
||||
+ * with with UIDs (note that this test is more broad than
|
||||
+ * the parse_uid() test above, as it will cover more than
|
||||
+ * the 32bit range, and it will detect 65535 (which is in
|
||||
+ * invalid UID, even though in the unsigned 32 bit range) */
|
||||
+ return false;
|
||||
|
||||
- sz = sysconf(_SC_LOGIN_NAME_MAX);
|
||||
- assert_se(sz > 0);
|
||||
+ if (u[0] == '-' && in_charset(u + 1, "0123456789")) /* Don't allow negative fully numeric
|
||||
+ * strings either. After all some people
|
||||
+ * write 65535 as -1 (even though that's
|
||||
+ * not even true on 32bit uid_t
|
||||
+ * anyway) */
|
||||
+ return false;
|
||||
|
||||
- if ((size_t) (i-u) > (size_t) sz)
|
||||
- return false;
|
||||
+ if (dot_or_dot_dot(u)) /* User names typically become home directory names, and these two are
|
||||
+ * special in that context, don't allow that. */
|
||||
+ return false;
|
||||
|
||||
- if ((size_t) (i-u) > UT_NAMESIZE - 1)
|
||||
- return false;
|
||||
+ /* Compare with strict result and warn if result doesn't match */
|
||||
+ if (FLAGS_SET(flags, VALID_USER_WARN) && !valid_user_group_name(u, 0))
|
||||
+ log_struct(LOG_NOTICE,
|
||||
+ "MESSAGE=Accepting user/group name '%s', which does not match strict user/group name rules.", u,
|
||||
+ "USER_GROUP_NAME=%s", u,
|
||||
+ "MESSAGE_ID=" SD_MESSAGE_UNSAFE_USER_NAME_STR);
|
||||
|
||||
- return true;
|
||||
-}
|
||||
+ /* Note that we make no restrictions on the length in relaxed mode! */
|
||||
+ } else {
|
||||
+ long sz;
|
||||
+ size_t l;
|
||||
+
|
||||
+ /* Also see POSIX IEEE Std 1003.1-2008, 2016 Edition, 3.437. We are a bit stricter here
|
||||
+ * however. Specifically we deviate from POSIX rules:
|
||||
+ *
|
||||
+ * - We don't allow empty user names (see above)
|
||||
+ * - We require that names fit into the appropriate utmp field
|
||||
+ * - We don't allow any dots (this conflicts with chown syntax which permits dots as user/group name separator)
|
||||
+ * - We don't allow dashes or digit as the first character
|
||||
+ *
|
||||
+ * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters.
|
||||
+ */
|
||||
+
|
||||
+ if (!(u[0] >= 'a' && u[0] <= 'z') &&
|
||||
+ !(u[0] >= 'A' && u[0] <= 'Z') &&
|
||||
+ u[0] != '_')
|
||||
+ return false;
|
||||
|
||||
-bool valid_user_group_name_or_id_full(const char *u, bool strict) {
|
||||
+ for (i = u+1; *i; i++)
|
||||
+ if (!(*i >= 'a' && *i <= 'z') &&
|
||||
+ !(*i >= 'A' && *i <= 'Z') &&
|
||||
+ !(*i >= '0' && *i <= '9') &&
|
||||
+ !IN_SET(*i, '_', '-'))
|
||||
+ return false;
|
||||
|
||||
- /* Similar as above, but is also fine with numeric UID/GID specifications, as long as they are in the
|
||||
- * right range, and not the invalid user ids. */
|
||||
+ l = i - u;
|
||||
|
||||
- if (isempty(u))
|
||||
- return false;
|
||||
+ sz = sysconf(_SC_LOGIN_NAME_MAX);
|
||||
+ assert_se(sz > 0);
|
||||
|
||||
- if (parse_uid(u, NULL) >= 0)
|
||||
- return true;
|
||||
+ if (l > (size_t) sz)
|
||||
+ return false;
|
||||
+ if (l > FILENAME_MAX)
|
||||
+ return false;
|
||||
+ if (l > UT_NAMESIZE - 1)
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
- return valid_user_group_name_full(u, strict);
|
||||
+ return true;
|
||||
}
|
||||
|
||||
bool valid_gecos(const char *d) {
|
||||
diff --git a/src/basic/user-util.h b/src/basic/user-util.h
|
||||
index 6796ac42c1..1f267d21a3 100644
|
||||
--- a/src/basic/user-util.h
|
||||
+++ b/src/basic/user-util.h
|
||||
@@ -97,20 +97,13 @@ static inline bool userns_supported(void) {
|
||||
return access("/proc/self/uid_map", F_OK) >= 0;
|
||||
}
|
||||
|
||||
-bool valid_user_group_name_full(const char *u, bool strict);
|
||||
-bool valid_user_group_name_or_id_full(const char *u, bool strict);
|
||||
-static inline bool valid_user_group_name(const char *u) {
|
||||
- return valid_user_group_name_full(u, true);
|
||||
-}
|
||||
-static inline bool valid_user_group_name_or_id(const char *u) {
|
||||
- return valid_user_group_name_or_id_full(u, true);
|
||||
-}
|
||||
-static inline bool valid_user_group_name_compat(const char *u) {
|
||||
- return valid_user_group_name_full(u, false);
|
||||
-}
|
||||
-static inline bool valid_user_group_name_or_id_compat(const char *u) {
|
||||
- return valid_user_group_name_or_id_full(u, false);
|
||||
-}
|
||||
+typedef enum ValidUserFlags {
|
||||
+ VALID_USER_RELAX = 1 << 0,
|
||||
+ VALID_USER_WARN = 1 << 1,
|
||||
+ VALID_USER_ALLOW_NUMERIC = 1 << 2,
|
||||
+} ValidUserFlags;
|
||||
+
|
||||
+bool valid_user_group_name(const char *u, ValidUserFlags flags);
|
||||
bool valid_gecos(const char *d);
|
||||
bool valid_home(const char *p);
|
||||
|
||||
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
|
||||
index 5696a60ba8..93857436b4 100644
|
||||
--- a/src/core/dbus-execute.c
|
||||
+++ b/src/core/dbus-execute.c
|
||||
@@ -1204,10 +1204,10 @@ int bus_exec_context_set_transient_property(
|
||||
flags |= UNIT_PRIVATE;
|
||||
|
||||
if (streq(name, "User"))
|
||||
- return bus_set_transient_user_compat(u, name, &c->user, message, flags, error);
|
||||
+ return bus_set_transient_user_relaxed(u, name, &c->user, message, flags, error);
|
||||
|
||||
if (streq(name, "Group"))
|
||||
- return bus_set_transient_user_compat(u, name, &c->group, message, flags, error);
|
||||
+ return bus_set_transient_user_relaxed(u, name, &c->group, message, flags, error);
|
||||
|
||||
if (streq(name, "TTYPath"))
|
||||
return bus_set_transient_path(u, name, &c->tty_path, message, flags, error);
|
||||
@@ -1392,7 +1392,7 @@ int bus_exec_context_set_transient_property(
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(p, l)
|
||||
- if (!isempty(*p) && !valid_user_group_name_or_id_compat(*p))
|
||||
+ if (!isempty(*p) && !valid_user_group_name(*p, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Invalid supplementary group names");
|
||||
|
||||
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
|
||||
index 60f55aef5f..ef4bb316cc 100644
|
||||
--- a/src/core/dbus-manager.c
|
||||
+++ b/src/core/dbus-manager.c
|
||||
@@ -1643,7 +1643,7 @@ static int method_lookup_dynamic_user_by_name(sd_bus_message *message, void *use
|
||||
|
||||
if (!MANAGER_IS_SYSTEM(m))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Dynamic users are only supported in the system instance.");
|
||||
- if (!valid_user_group_name(name))
|
||||
+ if (!valid_user_group_name(name, VALID_USER_RELAX))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "User name invalid: %s", name);
|
||||
|
||||
r = dynamic_user_lookup_name(m, name, &uid);
|
||||
diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
|
||||
index c8253c7940..ad7b41a95b 100644
|
||||
--- a/src/core/dbus-socket.c
|
||||
+++ b/src/core/dbus-socket.c
|
||||
@@ -278,10 +278,10 @@ static int bus_socket_set_transient_property(
|
||||
return bus_set_transient_fdname(u, name, &s->fdname, message, flags, error);
|
||||
|
||||
if (streq(name, "SocketUser"))
|
||||
- return bus_set_transient_user_compat(u, name, &s->user, message, flags, error);
|
||||
+ return bus_set_transient_user_relaxed(u, name, &s->user, message, flags, error);
|
||||
|
||||
if (streq(name, "SocketGroup"))
|
||||
- return bus_set_transient_user_compat(u, name, &s->group, message, flags, error);
|
||||
+ return bus_set_transient_user_relaxed(u, name, &s->group, message, flags, error);
|
||||
|
||||
if (streq(name, "BindIPv6Only"))
|
||||
return bus_set_transient_bind_ipv6_only(u, name, &s->bind_ipv6_only, message, flags, error);
|
||||
diff --git a/src/core/dbus-util.c b/src/core/dbus-util.c
|
||||
index 7862beaacb..951450e53d 100644
|
||||
--- a/src/core/dbus-util.c
|
||||
+++ b/src/core/dbus-util.c
|
||||
@@ -30,7 +30,12 @@ int bus_property_get_triggered_unit(
|
||||
|
||||
BUS_DEFINE_SET_TRANSIENT(mode_t, "u", uint32_t, mode_t, "%040o");
|
||||
BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32);
|
||||
-BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user_compat, valid_user_group_name_or_id_compat);
|
||||
+
|
||||
+static inline bool valid_user_group_name_or_id_relaxed(const char *u) {
|
||||
+ return valid_user_group_name(u, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX);
|
||||
+}
|
||||
+
|
||||
+BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user_relaxed, valid_user_group_name_or_id_relaxed);
|
||||
BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(path, path_is_absolute);
|
||||
|
||||
int bus_set_transient_string(
|
||||
diff --git a/src/core/dbus-util.h b/src/core/dbus-util.h
|
||||
index ec8c245fff..654ceb5279 100644
|
||||
--- a/src/core/dbus-util.h
|
||||
+++ b/src/core/dbus-util.h
|
||||
@@ -236,7 +236,7 @@ int bus_property_get_triggered_unit(sd_bus *bus, const char *path, const char *i
|
||||
|
||||
int bus_set_transient_mode_t(Unit *u, const char *name, mode_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_unsigned(Unit *u, const char *name, unsigned *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
-int bus_set_transient_user_compat(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
+int bus_set_transient_user_relaxed(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_path(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_string(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_bool(Unit *u, const char *name, bool *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c
|
||||
index f1819b36bc..58b37925bf 100644
|
||||
--- a/src/core/dynamic-user.c
|
||||
+++ b/src/core/dynamic-user.c
|
||||
@@ -116,7 +116,7 @@ static int dynamic_user_acquire(Manager *m, const char *name, DynamicUser** ret)
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (!valid_user_group_name_or_id(name))
|
||||
+ if (!valid_user_group_name(name, VALID_USER_ALLOW_NUMERIC))
|
||||
return -EINVAL;
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, storage_socket) < 0)
|
||||
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
|
||||
index 646364eb89..f3fe73535e 100644
|
||||
--- a/src/core/load-fragment.c
|
||||
+++ b/src/core/load-fragment.c
|
||||
@@ -2068,7 +2068,7 @@ int config_parse_user_group_compat(
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
- if (!valid_user_group_name_or_id_compat(k)) {
|
||||
+ if (!valid_user_group_name(k, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
@@ -2122,7 +2122,7 @@ int config_parse_user_group_strv_compat(
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
- if (!valid_user_group_name_or_id_compat(k)) {
|
||||
+ if (!valid_user_group_name(k, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX|VALID_USER_WARN)) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
diff --git a/src/core/unit.c b/src/core/unit.c
|
||||
index 96e1a6c320..95d574d8d4 100644
|
||||
--- a/src/core/unit.c
|
||||
+++ b/src/core/unit.c
|
||||
@@ -4287,7 +4287,7 @@ static int user_from_unit_name(Unit *u, char **ret) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
- if (valid_user_group_name(n)) {
|
||||
+ if (valid_user_group_name(n, 0)) {
|
||||
*ret = TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c
|
||||
index 8ef1cd5..25d034a 100644
|
||||
--- a/src/nss-systemd/nss-systemd.c
|
||||
+++ b/src/nss-systemd/nss-systemd.c
|
||||
@@ -124,7 +124,7 @@ static int direct_lookup_uid(uid_t uid, char **ret) {
|
||||
r = readlink_malloc(path, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
- if (!valid_user_group_name(s)) { /* extra safety check */
|
||||
+ if (!valid_user_group_name(s, VALID_USER_RELAX)) { /* extra safety check */
|
||||
free(s);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -154,7 +154,7 @@ enum nss_status _nss_systemd_getpwnam_r(
|
||||
|
||||
/* If the username is not valid, then we don't know it. Ideally libc would filter these for us anyway. We don't
|
||||
* generate EINVAL here, because it isn't really out business to complain about invalid user names. */
|
||||
- if (!valid_user_group_name(name))
|
||||
+ if (!valid_user_group_name(name, VALID_USER_RELAX))
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
/* Synthesize entries for the root and nobody users, in case they are missing in /etc/passwd */
|
||||
@@ -357,7 +357,7 @@ enum nss_status _nss_systemd_getgrnam_r(
|
||||
assert(name);
|
||||
assert(gr);
|
||||
|
||||
- if (!valid_user_group_name(name))
|
||||
+ if (!valid_user_group_name(name, VALID_USER_RELAX))
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
/* Synthesize records for root and nobody, in case they are missing form /etc/group */
|
||||
diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h
|
||||
index e8d26ab71b..162b650e64 100644
|
||||
--- a/src/systemd/sd-messages.h
|
||||
+++ b/src/systemd/sd-messages.h
|
||||
@@ -158,6 +158,9 @@ _SD_BEGIN_DECLARATIONS;
|
||||
#define SD_MESSAGE_DNSSEC_DOWNGRADE SD_ID128_MAKE(36,db,2d,fa,5a,90,45,e1,bd,4a,f5,f9,3e,1c,f0,57)
|
||||
#define SD_MESSAGE_DNSSEC_DOWNGRADE_STR SD_ID128_MAKE_STR(36,db,2d,fa,5a,90,45,e1,bd,4a,f5,f9,3e,1c,f0,57)
|
||||
|
||||
+#define SD_MESSAGE_UNSAFE_USER_NAME SD_ID128_MAKE(b6,1f,da,c6,12,e9,4b,91,82,28,5b,99,88,43,06,1f)
|
||||
+#define SD_MESSAGE_UNSAFE_USER_NAME_STR SD_ID128_MAKE_STR(b6,1f,da,c6,12,e9,4b,91,82,28,5b,99,88,43,06,1f)
|
||||
+
|
||||
_SD_END_DECLARATIONS;
|
||||
|
||||
#endif
|
||||
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
|
||||
index 08a2df7..3e3da47 100644
|
||||
--- a/src/sysusers/sysusers.c
|
||||
+++ b/src/sysusers/sysusers.c
|
||||
@@ -1417,7 +1417,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
if (r < 0)
|
||||
log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s", fname, line, name);
|
||||
|
||||
- if (!valid_user_group_name(resolved_name))
|
||||
+ if (!valid_user_group_name(resolved_name, 0))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"[%s:%u] '%s' is not a valid user or group name.",
|
||||
fname, line, resolved_name);
|
||||
@@ -1520,7 +1520,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
"[%s:%u] Lines of type 'm' require a group name in the third field.",
|
||||
fname, line);
|
||||
|
||||
- if (!valid_user_group_name(resolved_id))
|
||||
+ if (!valid_user_group_name(resolved_id, 0))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"[%s:%u] '%s' is not a valid user or group name.",
|
||||
fname, line, resolved_id);
|
||||
diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c
|
||||
index 11c01e5189..a0e1495186 100644
|
||||
--- a/src/test/test-user-util.c
|
||||
+++ b/src/test/test-user-util.c
|
||||
@@ -63,144 +63,163 @@ static void test_uid_ptr(void) {
|
||||
assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
|
||||
}
|
||||
|
||||
-static void test_valid_user_group_name_compat(void) {
|
||||
+static void test_valid_user_group_name_relaxed(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
- assert_se(!valid_user_group_name_compat(NULL));
|
||||
- assert_se(!valid_user_group_name_compat(""));
|
||||
- assert_se(!valid_user_group_name_compat("1"));
|
||||
- assert_se(!valid_user_group_name_compat("65535"));
|
||||
- assert_se(!valid_user_group_name_compat("-1"));
|
||||
- assert_se(!valid_user_group_name_compat("-kkk"));
|
||||
- assert_se(!valid_user_group_name_compat("rööt"));
|
||||
- assert_se(!valid_user_group_name_compat("."));
|
||||
- assert_se(!valid_user_group_name_compat(".eff"));
|
||||
- assert_se(!valid_user_group_name_compat("foo\nbar"));
|
||||
- assert_se(!valid_user_group_name_compat("0123456789012345678901234567890123456789"));
|
||||
- assert_se(!valid_user_group_name_or_id_compat("aaa:bbb"));
|
||||
- assert_se(!valid_user_group_name_compat("."));
|
||||
- assert_se(!valid_user_group_name_compat(".1"));
|
||||
- assert_se(!valid_user_group_name_compat(".65535"));
|
||||
- assert_se(!valid_user_group_name_compat(".-1"));
|
||||
- assert_se(!valid_user_group_name_compat(".-kkk"));
|
||||
- assert_se(!valid_user_group_name_compat(".rööt"));
|
||||
- assert_se(!valid_user_group_name_or_id_compat(".aaa:bbb"));
|
||||
-
|
||||
- assert_se(valid_user_group_name_compat("root"));
|
||||
- assert_se(valid_user_group_name_compat("lennart"));
|
||||
- assert_se(valid_user_group_name_compat("LENNART"));
|
||||
- assert_se(valid_user_group_name_compat("_kkk"));
|
||||
- assert_se(valid_user_group_name_compat("kkk-"));
|
||||
- assert_se(valid_user_group_name_compat("kk-k"));
|
||||
- assert_se(valid_user_group_name_compat("eff.eff"));
|
||||
- assert_se(valid_user_group_name_compat("eff."));
|
||||
-
|
||||
- assert_se(valid_user_group_name_compat("some5"));
|
||||
- assert_se(valid_user_group_name_compat("5some"));
|
||||
- assert_se(valid_user_group_name_compat("INNER5NUMBER"));
|
||||
+ assert_se(!valid_user_group_name(NULL, VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("", VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("1", VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("65535", VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("-1", VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("foo\nbar", VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("0123456789012345678901234567890123456789", VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("aaa:bbb", VALID_USER_RELAX|VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name(".aaa:bbb", VALID_USER_RELAX|VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name(".", VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("..", VALID_USER_RELAX));
|
||||
+
|
||||
+ assert_se(valid_user_group_name("root", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("lennart", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("LENNART", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("_kkk", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("kkk-", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("kk-k", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("eff.eff", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("eff.", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("-kkk", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("rööt", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name(".eff", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name(".1", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name(".65535", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name(".-1", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name(".-kkk", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name(".rööt", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("...", VALID_USER_RELAX));
|
||||
+
|
||||
+ assert_se(valid_user_group_name("some5", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("5some", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("INNER5NUMBER", VALID_USER_RELAX));
|
||||
+
|
||||
+ assert_se(valid_user_group_name("piff.paff@ad.domain.example", VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("Dāvis", VALID_USER_RELAX));
|
||||
}
|
||||
|
||||
static void test_valid_user_group_name(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
- assert_se(!valid_user_group_name(NULL));
|
||||
- assert_se(!valid_user_group_name(""));
|
||||
- assert_se(!valid_user_group_name("1"));
|
||||
- assert_se(!valid_user_group_name("65535"));
|
||||
- assert_se(!valid_user_group_name("-1"));
|
||||
- assert_se(!valid_user_group_name("-kkk"));
|
||||
- assert_se(!valid_user_group_name("rööt"));
|
||||
- assert_se(!valid_user_group_name("."));
|
||||
- assert_se(!valid_user_group_name(".eff"));
|
||||
- assert_se(!valid_user_group_name("foo\nbar"));
|
||||
- assert_se(!valid_user_group_name("0123456789012345678901234567890123456789"));
|
||||
- assert_se(!valid_user_group_name_or_id("aaa:bbb"));
|
||||
- assert_se(!valid_user_group_name("."));
|
||||
- assert_se(!valid_user_group_name(".1"));
|
||||
- assert_se(!valid_user_group_name(".65535"));
|
||||
- assert_se(!valid_user_group_name(".-1"));
|
||||
- assert_se(!valid_user_group_name(".-kkk"));
|
||||
- assert_se(!valid_user_group_name(".rööt"));
|
||||
- assert_se(!valid_user_group_name_or_id(".aaa:bbb"));
|
||||
-
|
||||
- assert_se(valid_user_group_name("root"));
|
||||
- assert_se(valid_user_group_name("lennart"));
|
||||
- assert_se(valid_user_group_name("LENNART"));
|
||||
- assert_se(valid_user_group_name("_kkk"));
|
||||
- assert_se(valid_user_group_name("kkk-"));
|
||||
- assert_se(valid_user_group_name("kk-k"));
|
||||
- assert_se(!valid_user_group_name("eff.eff"));
|
||||
- assert_se(!valid_user_group_name("eff."));
|
||||
-
|
||||
- assert_se(valid_user_group_name("some5"));
|
||||
- assert_se(!valid_user_group_name("5some"));
|
||||
- assert_se(valid_user_group_name("INNER5NUMBER"));
|
||||
+ assert_se(!valid_user_group_name(NULL, 0));
|
||||
+ assert_se(!valid_user_group_name("", 0));
|
||||
+ assert_se(!valid_user_group_name("1", 0));
|
||||
+ assert_se(!valid_user_group_name("65535", 0));
|
||||
+ assert_se(!valid_user_group_name("-1", 0));
|
||||
+ assert_se(!valid_user_group_name("-kkk", 0));
|
||||
+ assert_se(!valid_user_group_name("rööt", 0));
|
||||
+ assert_se(!valid_user_group_name(".", 0));
|
||||
+ assert_se(!valid_user_group_name(".eff", 0));
|
||||
+ assert_se(!valid_user_group_name("foo\nbar", 0));
|
||||
+ assert_se(!valid_user_group_name("0123456789012345678901234567890123456789", 0));
|
||||
+ assert_se(!valid_user_group_name("aaa:bbb", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name(".", 0));
|
||||
+ assert_se(!valid_user_group_name("..", 0));
|
||||
+ assert_se(!valid_user_group_name("...", 0));
|
||||
+ assert_se(!valid_user_group_name(".1", 0));
|
||||
+ assert_se(!valid_user_group_name(".65535", 0));
|
||||
+ assert_se(!valid_user_group_name(".-1", 0));
|
||||
+ assert_se(!valid_user_group_name(".-kkk", 0));
|
||||
+ assert_se(!valid_user_group_name(".rööt", 0));
|
||||
+ assert_se(!valid_user_group_name(".aaa:bbb", VALID_USER_ALLOW_NUMERIC));
|
||||
+
|
||||
+ assert_se(valid_user_group_name("root", 0));
|
||||
+ assert_se(valid_user_group_name("lennart", 0));
|
||||
+ assert_se(valid_user_group_name("LENNART", 0));
|
||||
+ assert_se(valid_user_group_name("_kkk", 0));
|
||||
+ assert_se(valid_user_group_name("kkk-", 0));
|
||||
+ assert_se(valid_user_group_name("kk-k", 0));
|
||||
+ assert_se(!valid_user_group_name("eff.eff", 0));
|
||||
+ assert_se(!valid_user_group_name("eff.", 0));
|
||||
+
|
||||
+ assert_se(valid_user_group_name("some5", 0));
|
||||
+ assert_se(!valid_user_group_name("5some", 0));
|
||||
+ assert_se(valid_user_group_name("INNER5NUMBER", 0));
|
||||
+
|
||||
+ assert_se(!valid_user_group_name("piff.paff@ad.domain.example", 0));
|
||||
+ assert_se(!valid_user_group_name("Dāvis", 0));
|
||||
}
|
||||
|
||||
-static void test_valid_user_group_name_or_id_compat(void) {
|
||||
+static void test_valid_user_group_name_or_numeric_relaxed(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
- assert_se(!valid_user_group_name_or_id_compat(NULL));
|
||||
- assert_se(!valid_user_group_name_or_id_compat(""));
|
||||
- assert_se(valid_user_group_name_or_id_compat("0"));
|
||||
- assert_se(valid_user_group_name_or_id_compat("1"));
|
||||
- assert_se(valid_user_group_name_or_id_compat("65534"));
|
||||
- assert_se(!valid_user_group_name_or_id_compat("65535"));
|
||||
- assert_se(valid_user_group_name_or_id_compat("65536"));
|
||||
- assert_se(!valid_user_group_name_or_id_compat("-1"));
|
||||
- assert_se(!valid_user_group_name_or_id_compat("-kkk"));
|
||||
- assert_se(!valid_user_group_name_or_id_compat("rööt"));
|
||||
- assert_se(!valid_user_group_name_or_id_compat("."));
|
||||
- assert_se(!valid_user_group_name_or_id_compat(".eff"));
|
||||
- assert_se(valid_user_group_name_or_id_compat("eff.eff"));
|
||||
- assert_se(valid_user_group_name_or_id_compat("eff."));
|
||||
- assert_se(!valid_user_group_name_or_id_compat("foo\nbar"));
|
||||
- assert_se(!valid_user_group_name_or_id_compat("0123456789012345678901234567890123456789"));
|
||||
- assert_se(!valid_user_group_name_or_id_compat("aaa:bbb"));
|
||||
-
|
||||
- assert_se(valid_user_group_name_or_id_compat("root"));
|
||||
- assert_se(valid_user_group_name_or_id_compat("lennart"));
|
||||
- assert_se(valid_user_group_name_or_id_compat("LENNART"));
|
||||
- assert_se(valid_user_group_name_or_id_compat("_kkk"));
|
||||
- assert_se(valid_user_group_name_or_id_compat("kkk-"));
|
||||
- assert_se(valid_user_group_name_or_id_compat("kk-k"));
|
||||
-
|
||||
- assert_se(valid_user_group_name_or_id_compat("some5"));
|
||||
- assert_se(valid_user_group_name_or_id_compat("5some"));
|
||||
- assert_se(valid_user_group_name_or_id_compat("INNER5NUMBER"));
|
||||
+ assert_se(!valid_user_group_name(NULL, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("0", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("1", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("65534", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("65535", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("65536", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("-1", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("foo\nbar", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("0123456789012345678901234567890123456789", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("aaa:bbb", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name(".", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(!valid_user_group_name("..", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+
|
||||
+ assert_se(valid_user_group_name("root", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("lennart", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("LENNART", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("_kkk", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("kkk-", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("kk-k", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("-kkk", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("rööt", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name(".eff", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("eff.eff", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("eff.", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("...", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+
|
||||
+ assert_se(valid_user_group_name("some5", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("5some", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("INNER5NUMBER", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+
|
||||
+ assert_se(valid_user_group_name("piff.paff@ad.domain.example", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
+ assert_se(valid_user_group_name("Dāvis", VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX));
|
||||
}
|
||||
|
||||
-static void test_valid_user_group_name_or_id(void) {
|
||||
+static void test_valid_user_group_name_or_numeric(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
- assert_se(!valid_user_group_name_or_id(NULL));
|
||||
- assert_se(!valid_user_group_name_or_id(""));
|
||||
- assert_se(valid_user_group_name_or_id("0"));
|
||||
- assert_se(valid_user_group_name_or_id("1"));
|
||||
- assert_se(valid_user_group_name_or_id("65534"));
|
||||
- assert_se(!valid_user_group_name_or_id("65535"));
|
||||
- assert_se(valid_user_group_name_or_id("65536"));
|
||||
- assert_se(!valid_user_group_name_or_id("-1"));
|
||||
- assert_se(!valid_user_group_name_or_id("-kkk"));
|
||||
- assert_se(!valid_user_group_name_or_id("rööt"));
|
||||
- assert_se(!valid_user_group_name_or_id("."));
|
||||
- assert_se(!valid_user_group_name_or_id(".eff"));
|
||||
- assert_se(!valid_user_group_name_or_id("eff.eff"));
|
||||
- assert_se(!valid_user_group_name_or_id("eff."));
|
||||
- assert_se(!valid_user_group_name_or_id("foo\nbar"));
|
||||
- assert_se(!valid_user_group_name_or_id("0123456789012345678901234567890123456789"));
|
||||
- assert_se(!valid_user_group_name_or_id("aaa:bbb"));
|
||||
-
|
||||
- assert_se(valid_user_group_name_or_id("root"));
|
||||
- assert_se(valid_user_group_name_or_id("lennart"));
|
||||
- assert_se(valid_user_group_name_or_id("LENNART"));
|
||||
- assert_se(valid_user_group_name_or_id("_kkk"));
|
||||
- assert_se(valid_user_group_name_or_id("kkk-"));
|
||||
- assert_se(valid_user_group_name_or_id("kk-k"));
|
||||
-
|
||||
- assert_se(valid_user_group_name_or_id("some5"));
|
||||
- assert_se(!valid_user_group_name_or_id("5some"));
|
||||
- assert_se(valid_user_group_name_or_id("INNER5NUMBER"));
|
||||
+ assert_se(!valid_user_group_name(NULL, VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(valid_user_group_name("0", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(valid_user_group_name("1", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(valid_user_group_name("65534", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("65535", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(valid_user_group_name("65536", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("-1", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("-kkk", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("rööt", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name(".", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("..", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("...", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name(".eff", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("eff.eff", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("eff.", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("foo\nbar", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("0123456789012345678901234567890123456789", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("aaa:bbb", VALID_USER_ALLOW_NUMERIC));
|
||||
+
|
||||
+ assert_se(valid_user_group_name("root", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(valid_user_group_name("lennart", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(valid_user_group_name("LENNART", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(valid_user_group_name("_kkk", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(valid_user_group_name("kkk-", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(valid_user_group_name("kk-k", VALID_USER_ALLOW_NUMERIC));
|
||||
+
|
||||
+ assert_se(valid_user_group_name("some5", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("5some", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(valid_user_group_name("INNER5NUMBER", VALID_USER_ALLOW_NUMERIC));
|
||||
+
|
||||
+ assert_se(!valid_user_group_name("piff.paff@ad.domain.example", VALID_USER_ALLOW_NUMERIC));
|
||||
+ assert_se(!valid_user_group_name("Dāvis", VALID_USER_ALLOW_NUMERIC));
|
||||
}
|
||||
|
||||
static void test_valid_gecos(void) {
|
||||
@@ -355,10 +374,10 @@ int main(int argc, char *argv[]) {
|
||||
test_parse_uid();
|
||||
test_uid_ptr();
|
||||
|
||||
- test_valid_user_group_name_compat();
|
||||
+ test_valid_user_group_name_relaxed();
|
||||
test_valid_user_group_name();
|
||||
- test_valid_user_group_name_or_id_compat();
|
||||
- test_valid_user_group_name_or_id();
|
||||
+ test_valid_user_group_name_or_numeric_relaxed();
|
||||
+ test_valid_user_group_name_or_numeric();
|
||||
test_valid_gecos();
|
||||
test_valid_home();
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,191 @@
|
||||
From cafed7b32cdac13024c4093b7942a49ee8602dcf Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Tue, 7 Apr 2020 10:38:39 +0200
|
||||
Subject: [PATCH] docs: add a longer document explaining our rules on
|
||||
user/group names
|
||||
|
||||
Reference: https://github.com/systemd/systemd/commit/cafed7b32cdac13024c4093b7942a49ee8602dcf
|
||||
Conflict: NA
|
||||
---
|
||||
docs/USER_NAMES.md | 169 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 169 insertions(+)
|
||||
create mode 100644 docs/USER_NAMES.md
|
||||
|
||||
diff --git a/docs/USER_NAMES.md b/docs/USER_NAMES.md
|
||||
new file mode 100644
|
||||
index 0000000000..ccbb0a360d
|
||||
--- /dev/null
|
||||
+++ b/docs/USER_NAMES.md
|
||||
@@ -0,0 +1,169 @@
|
||||
+--
|
||||
+title: User/Group Name Syntax
|
||||
+category: Concepts
|
||||
+layout: default
|
||||
+---
|
||||
+
|
||||
+# User/Group Name Syntax
|
||||
+
|
||||
+The precise set of allowed user and group names on Linux systems is weakly
|
||||
+defined. Depending on the distribution a different set of requirements and
|
||||
+restrictions on the syntax of user/group names are enforced — on some
|
||||
+distributions the accepted syntax is even configurable by the administrator. In
|
||||
+the interest of interoperability systemd enforces different rules when
|
||||
+processing users/group defined by other subsystems and when defining users/groups
|
||||
+itself, following the principle of "Be conservative in what you send, be
|
||||
+liberal in what you accept". Also in the interest of interoperability systemd
|
||||
+will enforce the same rules everywhere and not make them configurable or
|
||||
+distribution dependent. The precise rules are described below.
|
||||
+
|
||||
+Generally, the same rules apply for user as for group names.
|
||||
+
|
||||
+## Other Systems
|
||||
+
|
||||
+* On POSIX the set of [valid user
|
||||
+ names](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_437)
|
||||
+ is defined as [lower and upper case ASCII letters, digits, period,
|
||||
+ underscore, and
|
||||
+ hyphen](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282),
|
||||
+ with the restriction that hyphen is now allowed as first character of the
|
||||
+ user name. Interestingly no size limit is declared, i.e. in neither
|
||||
+ direction, meaning that strictly speaking according to POSIX both the empty
|
||||
+ string is a valid user name as well as a string of gigabytes in length.
|
||||
+
|
||||
+* Debian/Ubuntu based systems enforce the regular expression
|
||||
+ `^[a-z][-a-z0-9]*$`, i.e. only lower case ASCII letters, digits and
|
||||
+ hyphens. As first character only lowercase ASCII letters are allowed. This
|
||||
+ regular expression is configurable by the administrator at runtime
|
||||
+ though. This rule enforces a minimum length of one character but no maximum
|
||||
+ length.
|
||||
+
|
||||
+* Upstream shadow-utils enforces the regular expression
|
||||
+ `^[a-z_][a-z0-9_-]*[$]$`, i.e. is similar to the Debian/Ubuntu rule, but
|
||||
+ allows underscores and hyphens, but the latter not as first character. Also,
|
||||
+ an optional trailing dollar character is permitted.
|
||||
+
|
||||
+* Fedora/Red Hat based systems enforce the regular expression of
|
||||
+ `^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,30}[a-zA-Z0-9_.$-]?$`, i.e. a size limit of
|
||||
+ 32 characters, with upper and lower case letters, digits, underscores,
|
||||
+ hyphens and periods. No hyphen as first character though, and the last
|
||||
+ character may be a dollar character. On top of that, `.` and `..` are not
|
||||
+ allowed as user/group names.
|
||||
+
|
||||
+* sssd is known to generate user names with embedded `@` and white-space
|
||||
+ characters, as well as non-ASCII (i.e. UTF-8) user/group names.
|
||||
+
|
||||
+* winbindd is known to generate user/group names with embedded `\` and
|
||||
+ white-space characters, as well as non-ASCII (i.e. UTF-8) user/group names.
|
||||
+
|
||||
+Other operating systems enforce different rules; in this documentation we'll
|
||||
+focus on Linux systems only however, hence those are out of scope. That said,
|
||||
+software like Samba is frequently deployed on Linux for providing compatibility
|
||||
+with Windows systems; on such systems it might be wise to stick to user/group
|
||||
+names also valid according to Windows rules.
|
||||
+
|
||||
+## Rules systemd enforces
|
||||
+
|
||||
+Distilled from the above, below are the rules systemd enforces on user/group
|
||||
+names. An additional, common rule between both modes listed below is that empty
|
||||
+strings are not valid user/group names.
|
||||
+
|
||||
+Philosophically, the strict mode described below enforces a white-list of what's
|
||||
+allowed and prohibits everything else, while the relaxed mode described below
|
||||
+implements a blacklist of what's not allowed and permits everything else.
|
||||
+
|
||||
+### Strict mode
|
||||
+
|
||||
+Strict user/group name syntax is enforced whenever a systemd component is used
|
||||
+to register a user or group in the system, for example a system user/group
|
||||
+using
|
||||
+[`systemd-sysusers.service`](https://www.freedesktop.org/software/systemd/man/systemd-sysusers.html)
|
||||
+or a regular user with
|
||||
+[`systemd-homed.service`](https://www.freedesktop.org/software/systemd/man/systemd-homed.html).
|
||||
+
|
||||
+In strict mode, only uppercase and lowercase characters are allowed, as well as
|
||||
+digits, underscores and hyphens. The first character may not be a digit or
|
||||
+hyphen. A size limit is enforced: the minimum of `sysconf(_SC_LOGIN_NAME_MAX)`
|
||||
+(typically 256 on Linux; rationale: this is how POSIX suggests to detect the
|
||||
+limit), `UT_NAMESIZE-1` (typically 31 on Linux; rationale: names longer than
|
||||
+this cannot correctly appear in `utmp`/`wtmp` and create ambiguity with login
|
||||
+accounting) and `FILENAME_MAX` (4096 on Linux; rationale: user names typically
|
||||
+appear in directory names, i.e. the home directory), thus MIN(256, 31, 4096) =
|
||||
+31.
|
||||
+
|
||||
+Note that these rules are both more strict and more relaxed than all of the
|
||||
+rules enforced by other systems listed above. A user/group name conforming to
|
||||
+systemd's strict rules will not necessarily pass a test by the rules enforced
|
||||
+by these other subsystems.
|
||||
+
|
||||
+Written as regular expression the above is: `^[a-zA-Z_][a-zA-Z0-9_-]{0,30}$`
|
||||
+
|
||||
+### Relaxed mode
|
||||
+
|
||||
+Relaxed user/group name syntax is enforced whenever a systemd component accepts
|
||||
+and makes use of user/group names registered by other (non-systemd)
|
||||
+components of the system, for example in
|
||||
+[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.html).
|
||||
+
|
||||
+Relaxed syntax is also enforced by the `User=` setting in service unit files,
|
||||
+i.e. for system services used for running services. Since these users may be
|
||||
+registered by a variety of tools relaxed mode is used, but since the primary
|
||||
+purpose of these users is to run a system service and thus a job for systemd a
|
||||
+warning is shown if the specified user name does not qualify by the strict
|
||||
+rules above.
|
||||
+
|
||||
+* No embedded NUL bytes (rationale: handling in C must be possible and
|
||||
+ straight-forward)
|
||||
+
|
||||
+* No names consisting fully of digits (rationale: avoid confusion with numeric
|
||||
+ UID/GID specifications)
|
||||
+
|
||||
+* Similar, no names consisting of an initial hyphen and otherwise entirely made
|
||||
+ up of digits (rationale: avoid confusion with negative, numeric UID/GID
|
||||
+ specifications, e.g. `-1`)
|
||||
+
|
||||
+* No strings that do not qualify as valid UTF-8 (rationale: we want to be able
|
||||
+ to embed these strings in JSON, with permits only valid UTF-8 in its strings;
|
||||
+ user names using other character sets, such as JIS/Shift-JIS will cause
|
||||
+ validation errors)
|
||||
+
|
||||
+* No control characters (i.e. characters in ASCII range 1…31; rationale: they
|
||||
+ tend to have special meaning when output on a terminal in other contexts,
|
||||
+ moreover the newline character — as a specific control character — is used as
|
||||
+ record separator in `/etc/passwd`, and hence it's crucial to avoid
|
||||
+ ambiguities here)
|
||||
+
|
||||
+* No colon characters (rationale: it is used as field separator in `/etc/passwd`)
|
||||
+
|
||||
+* The two strings `.` and `..` are not permitted, as these have special meaning
|
||||
+ in file system paths, and user names are frequently included in file system
|
||||
+ paths, in particular for the purpose of home directories.
|
||||
+
|
||||
+* Similar, no slashes, as these have special meaning in file system paths
|
||||
+
|
||||
+* No leading or trailing white-space is permitted; and hence no user/group names
|
||||
+ consisting of white-space only either (rationale: this typically indicates
|
||||
+ parsing errors, and creates confusion since not visible on screen)
|
||||
+
|
||||
+Note that these relaxed rules are implied by the strict rules above, i.e. all
|
||||
+user/group names accepted by the strict rules are also accepted by the relaxed
|
||||
+rules, but not vice versa.
|
||||
+
|
||||
+Note that this relaxed mode does not refuse a couple of very questionable
|
||||
+syntaxes. For example it permits a leading or embedded period. A leading period
|
||||
+is problematic because the matching home directory would typically be hidden
|
||||
+from the user's/administrator's view. An embedded period is problematic since
|
||||
+it creates ambiguity in traditional `chown` syntax (which is still accepted
|
||||
+today) that uses it to separate user and group names in the command's
|
||||
+parameter: without consulting the user/group databases it is not possible to
|
||||
+determine if a `chown` invocation would change just the owning user or both the
|
||||
+owning user and group. It also allows embeddeding `@` (which is confusing to
|
||||
+MTAs).
|
||||
+
|
||||
+## Common Core
|
||||
+
|
||||
+Combining all rules listed above, user/group names that shall be considered
|
||||
+valid in all systemd contexts and on all Linux systems should match the
|
||||
+following regular expression (at least according to our understanding):
|
||||
+
|
||||
+`^[a-z][a-z0-9-]{0,30}$`
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
From 887a8fa341d9b24a7c9cd3f1fce328f8e43a1b4f Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Tue, 7 Apr 2020 11:04:59 +0200
|
||||
Subject: [PATCH] docs: hook up the new USER_NAMES document everywhere
|
||||
|
||||
(Also correct the set of names we accept in User=, which was forgotten
|
||||
to be updated in ae480f0b09aec815b64579bb1828ea935d8ee236.
|
||||
|
||||
Reference: https://github.com/systemd/systemd/commit/887a8fa341d9b24a7c9cd3f1fce328f8e43a1b4f
|
||||
Conflict: Remove unneeded file changes.
|
||||
---
|
||||
man/systemd.exec.xml | 15 +++++++++------
|
||||
man/sysusers.d.xml | 3 +++
|
||||
2 files changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
|
||||
index a52d8fa..bf9b030 100644
|
||||
--- a/man/systemd.exec.xml
|
||||
+++ b/man/systemd.exec.xml
|
||||
@@ -186,12 +186,15 @@
|
||||
is set, the default group of the user is used. This setting does not affect commands whose command line is
|
||||
prefixed with <literal>+</literal>.</para>
|
||||
|
||||
- <para>Note that restrictions on the user/group name syntax are enforced: the specified name must consist only
|
||||
- of the characters a-z, A-Z, 0-9, <literal>_</literal> and <literal>-</literal>, except for the first character
|
||||
- which must be one of a-z, A-Z or <literal>_</literal> (i.e. numbers and <literal>-</literal> are not permitted
|
||||
- as first character). The user/group name must have at least one character, and at most 31. These restrictions
|
||||
- are enforced in order to avoid ambiguities and to ensure user/group names and unit files remain portable among
|
||||
- Linux systems.</para>
|
||||
+ <para>Note that this enforces only weak restrictions on the user/group name syntax, but will generate
|
||||
+ warnings in many cases where user/group names do not adhere to the following rules: the specified
|
||||
+ name should consist only of the characters a-z, A-Z, 0-9, <literal>_</literal> and
|
||||
+ <literal>-</literal>, except for the first character which must be one of a-z, A-Z and
|
||||
+ <literal>_</literal> (i.e. digits and <literal>-</literal> are not permitted as first character). The
|
||||
+ user/group name must have at least one character, and at most 31. These restrictions are made in
|
||||
+ order to avoid ambiguities and to ensure user/group names and unit files remain portable among Linux
|
||||
+ systems. For further details on the names accepted and the names warned about see <ulink
|
||||
+ url="https://systemd.io/USER_NAMES">User/Group Name Syntax</ulink>.</para>
|
||||
|
||||
<para>When used in conjunction with <varname>DynamicUser=</varname> the user/group name specified is
|
||||
dynamically allocated at the time the service is started, and released at the time the service is stopped —
|
||||
diff --git a/man/sysusers.d.xml b/man/sysusers.d.xml
|
||||
index e47d36c..840da44 100644
|
||||
--- a/man/sysusers.d.xml
|
||||
+++ b/man/sysusers.d.xml
|
||||
@@ -143,6 +143,9 @@ u root 0 "Superuser" /root /bin/zsh</pro
|
||||
A-Z or <literal>_</literal> (i.e. numbers and <literal>-</literal> are not permitted as first character). The
|
||||
user/group name must have at least one character, and at most 31.</para>
|
||||
|
||||
+ <para>For further details about the syntax of user/group names, see <ulink
|
||||
+ url="https://systemd.io/USER_NAMES">User/Group Name Syntax</ulink>.</para>
|
||||
+
|
||||
<para>It is strongly recommended to pick user and group names that are unlikely to clash with normal users
|
||||
created by the administrator. A good scheme to guarantee this is by prefixing all system and group names with the
|
||||
underscore, and avoiding too generic names.</para>
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
From ad313ec33bb367624c25c9264994d6e43b8a7e2e Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Tue, 7 Apr 2020 11:15:49 +0200
|
||||
Subject: [PATCH] catalog: add entry for SD_MESSAGE_UNSAFE_USER_NAME
|
||||
|
||||
Reference: https://github.com/systemd/systemd/commit/ad313ec33bb367624c25c9264994d6e43b8a7e2e
|
||||
Conflict: NA
|
||||
---
|
||||
catalog/systemd.catalog.in | 23 +++++++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
diff --git a/catalog/systemd.catalog.in b/catalog/systemd.catalog.in
|
||||
index db275d7c50..3342d59422 100644
|
||||
--- a/catalog/systemd.catalog.in
|
||||
+++ b/catalog/systemd.catalog.in
|
||||
@@ -412,3 +412,26 @@ as the best process to terminate and has been forcibly terminated by the
|
||||
kernel.
|
||||
|
||||
Note that the memory pressure might or might not have been caused by @UNIT@.
|
||||
+
|
||||
+-- b61fdac612e94b9182285b998843061f
|
||||
+Subject: Accepting user/group name @USER_GROUP_NAME@, which does not match strict user/group name rules.
|
||||
+Defined-By: systemd
|
||||
+Support: %SUPPORT_URL%
|
||||
+
|
||||
+The user/group name @USER_GROUP_NAME@ has been specified, which is accepted
|
||||
+according the relaxed user/group name rules, but does not qualify under the
|
||||
+strict rules.
|
||||
+
|
||||
+The strict user/group name rules written as regular expression are:
|
||||
+
|
||||
+^[a-zA-Z_][a-zA-Z0-9_-]{0,30}$
|
||||
+
|
||||
+The relaxed user/group name rules accept all names, except for the empty
|
||||
+string; names containing NUL bytes, control characters, colon or slash
|
||||
+characters; names not valid UTF-8; names with leading or trailing whitespace;
|
||||
+the strings "." or ".."; fully numeric strings, or strings beginning in a
|
||||
+hyphen and otherwise fully numeric.
|
||||
+
|
||||
+For further details on strict and relaxed user/group name rules, see:
|
||||
+
|
||||
+https://systemd.io/USER_NAMES
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,73 @@
|
||||
From 156a5fd297b61bce31630d7a52c15614bf784843 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Sun, 31 May 2020 18:21:09 +0200
|
||||
Subject: [PATCH] basic/user-util: always use base 10 for user/group numbers
|
||||
|
||||
We would parse numbers with base prefixes as user identifiers. For example,
|
||||
"0x2b3bfa0" would be interpreted as UID==45334432 and "01750" would be
|
||||
interpreted as UID==1000. This parsing was used also in cases where either a
|
||||
user/group name or number may be specified. This means that names like
|
||||
0x2b3bfa0 would be ambiguous: they are a valid user name according to our
|
||||
documented relaxed rules, but they would also be parsed as numeric uids.
|
||||
|
||||
This behaviour is definitely not expected by users, since tools generally only
|
||||
accept decimal numbers (e.g. id, getent passwd), while other tools only accept
|
||||
user names and thus will interpret such strings as user names without even
|
||||
attempting to convert them to numbers (su, ssh). So let's follow suit and only
|
||||
accept numbers in decimal notation. Effectively this means that we will reject
|
||||
such strings as a username/uid/groupname/gid where strict mode is used, and try
|
||||
to look up a user/group with such a name in relaxed mode.
|
||||
|
||||
Since the function changed is fairly low-level and fairly widely used, this
|
||||
affects multiple tools: loginctl show-user/enable-linger/disable-linger foo',
|
||||
the third argument in sysusers.d, fourth and fifth arguments in tmpfiles.d,
|
||||
etc.
|
||||
|
||||
Fixes #15985.
|
||||
Reference: https://github.com/systemd/systemd/commit/156a5fd297b61bce31630d7a52c15614bf784843
|
||||
Conflict: NA
|
||||
---
|
||||
src/basic/user-util.c | 2 +-
|
||||
src/test/test-user-util.c | 10 ++++++++++
|
||||
2 files changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
|
||||
index 2e3580017d..2db8ef6abf 100644
|
||||
--- a/src/basic/user-util.c
|
||||
+++ b/src/basic/user-util.c
|
||||
@@ -49,7 +49,7 @@ int parse_uid(const char *s, uid_t *ret) {
|
||||
assert(s);
|
||||
|
||||
assert_cc(sizeof(uid_t) == sizeof(uint32_t));
|
||||
- r = safe_atou32(s, &uid);
|
||||
+ r = safe_atou32_full(s, 10, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c
|
||||
index a0e1495186..3165232fef 100644
|
||||
--- a/src/test/test-user-util.c
|
||||
+++ b/src/test/test-user-util.c
|
||||
@@ -48,9 +48,19 @@ static void test_parse_uid(void) {
|
||||
|
||||
r = parse_uid("65535", &uid);
|
||||
assert_se(r == -ENXIO);
|
||||
+ assert_se(uid == 100);
|
||||
+
|
||||
+ r = parse_uid("0x1234", &uid);
|
||||
+ assert_se(r == -EINVAL);
|
||||
+ assert_se(uid == 100);
|
||||
+
|
||||
+ r = parse_uid("01234", &uid);
|
||||
+ assert_se(r == 0);
|
||||
+ assert_se(uid == 1234);
|
||||
|
||||
r = parse_uid("asdsdas", &uid);
|
||||
assert_se(r == -EINVAL);
|
||||
+ assert_se(uid == 1234);
|
||||
}
|
||||
|
||||
static void test_uid_ptr(void) {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,151 @@
|
||||
From 22810041c2200fe72b0e0c985d0e404f8b80f9e2 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 14 Nov 2019 14:49:40 +0100
|
||||
Subject: [PATCH] parse-util: sometimes it is useful to check if a string is a
|
||||
valid integer, but not actually parse it
|
||||
|
||||
Reference: https://github.com/systemd/systemd/commit/22810041c2200fe72b0e0c985d0e404f8b80f9e2
|
||||
Conflict: NA
|
||||
---
|
||||
src/basic/parse-util.c | 34 ++++++++++++++++++++--------------
|
||||
1 file changed, 20 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
|
||||
index aec6099c9c..b81db04989 100644
|
||||
--- a/src/basic/parse-util.c
|
||||
+++ b/src/basic/parse-util.c
|
||||
@@ -365,7 +365,6 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
||||
unsigned long l;
|
||||
|
||||
assert(s);
|
||||
- assert(ret_u);
|
||||
assert(base <= 16);
|
||||
|
||||
/* strtoul() is happy to parse negative values, and silently
|
||||
@@ -389,7 +388,9 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
||||
if ((unsigned long) (unsigned) l != l)
|
||||
return -ERANGE;
|
||||
|
||||
- *ret_u = (unsigned) l;
|
||||
+ if (ret_u)
|
||||
+ *ret_u = (unsigned) l;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -398,7 +399,6 @@ int safe_atoi(const char *s, int *ret_i) {
|
||||
long l;
|
||||
|
||||
assert(s);
|
||||
- assert(ret_i);
|
||||
|
||||
errno = 0;
|
||||
l = strtol(s, &x, 0);
|
||||
@@ -409,7 +409,9 @@ int safe_atoi(const char *s, int *ret_i) {
|
||||
if ((long) (int) l != l)
|
||||
return -ERANGE;
|
||||
|
||||
- *ret_i = (int) l;
|
||||
+ if (ret_i)
|
||||
+ *ret_i = (int) l;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -418,7 +420,6 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) {
|
||||
unsigned long long l;
|
||||
|
||||
assert(s);
|
||||
- assert(ret_llu);
|
||||
|
||||
s += strspn(s, WHITESPACE);
|
||||
|
||||
@@ -431,7 +432,9 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) {
|
||||
if (*s == '-')
|
||||
return -ERANGE;
|
||||
|
||||
- *ret_llu = l;
|
||||
+ if (ret_llu)
|
||||
+ *ret_llu = l;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -440,7 +443,6 @@ int safe_atolli(const char *s, long long int *ret_lli) {
|
||||
long long l;
|
||||
|
||||
assert(s);
|
||||
- assert(ret_lli);
|
||||
|
||||
errno = 0;
|
||||
l = strtoll(s, &x, 0);
|
||||
@@ -449,7 +451,9 @@ int safe_atolli(const char *s, long long int *ret_lli) {
|
||||
if (!x || x == s || *x != 0)
|
||||
return -EINVAL;
|
||||
|
||||
- *ret_lli = l;
|
||||
+ if (ret_lli)
|
||||
+ *ret_lli = l;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -458,7 +462,6 @@ int safe_atou8(const char *s, uint8_t *ret) {
|
||||
unsigned long l;
|
||||
|
||||
assert(s);
|
||||
- assert(ret);
|
||||
|
||||
s += strspn(s, WHITESPACE);
|
||||
|
||||
@@ -473,7 +476,8 @@ int safe_atou8(const char *s, uint8_t *ret) {
|
||||
if ((unsigned long) (uint8_t) l != l)
|
||||
return -ERANGE;
|
||||
|
||||
- *ret = (uint8_t) l;
|
||||
+ if (ret)
|
||||
+ *ret = (uint8_t) l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -507,7 +511,6 @@ int safe_atoi16(const char *s, int16_t *ret) {
|
||||
long l;
|
||||
|
||||
assert(s);
|
||||
- assert(ret);
|
||||
|
||||
errno = 0;
|
||||
l = strtol(s, &x, 0);
|
||||
@@ -518,7 +521,9 @@ int safe_atoi16(const char *s, int16_t *ret) {
|
||||
if ((long) (int16_t) l != l)
|
||||
return -ERANGE;
|
||||
|
||||
- *ret = (int16_t) l;
|
||||
+ if (ret)
|
||||
+ *ret = (int16_t) l;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -528,7 +533,6 @@ int safe_atod(const char *s, double *ret_d) {
|
||||
double d = 0;
|
||||
|
||||
assert(s);
|
||||
- assert(ret_d);
|
||||
|
||||
loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
|
||||
if (loc == (locale_t) 0)
|
||||
@@ -541,7 +545,9 @@ int safe_atod(const char *s, double *ret_d) {
|
||||
if (!x || x == s || *x != 0)
|
||||
return -EINVAL;
|
||||
|
||||
- *ret_d = (double) d;
|
||||
+ if (ret_d)
|
||||
+ *ret_d = (double) d;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,132 @@
|
||||
From ce51632a357d347737bf40d3817df331cd8874cb Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Thu, 9 Apr 2020 11:18:26 +0200
|
||||
Subject: [PATCH] basic/parse-util: add safe_atoux64()
|
||||
|
||||
Reference: https://github.com/systemd/systemd/commit/ce51632a357d347737bf40d3817df331cd8874cb
|
||||
Conflict: NA
|
||||
---
|
||||
src/basic/parse-util.c | 4 ++--
|
||||
src/basic/parse-util.h | 12 +++++++++++-
|
||||
src/test/test-parse-util.c | 39 ++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 52 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
|
||||
index e0094b0f37..8de5cd5c56 100644
|
||||
--- a/src/basic/parse-util.c
|
||||
+++ b/src/basic/parse-util.c
|
||||
@@ -395,7 +395,7 @@ int safe_atoi(const char *s, int *ret_i) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int safe_atollu(const char *s, long long unsigned *ret_llu) {
|
||||
+int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu) {
|
||||
char *x = NULL;
|
||||
unsigned long long l;
|
||||
|
||||
@@ -404,7 +404,7 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) {
|
||||
s += strspn(s, WHITESPACE);
|
||||
|
||||
errno = 0;
|
||||
- l = strtoull(s, &x, 0);
|
||||
+ l = strtoull(s, &x, base);
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
if (!x || x == s || *x != 0)
|
||||
diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h
|
||||
index 36d76ba576..970bdefbf0 100644
|
||||
--- a/src/basic/parse-util.h
|
||||
+++ b/src/basic/parse-util.h
|
||||
@@ -28,7 +28,6 @@ static inline int safe_atou(const char *s, unsigned *ret_u) {
|
||||
}
|
||||
|
||||
int safe_atoi(const char *s, int *ret_i);
|
||||
-int safe_atollu(const char *s, unsigned long long *ret_u);
|
||||
int safe_atolli(const char *s, long long int *ret_i);
|
||||
|
||||
int safe_atou8(const char *s, uint8_t *ret);
|
||||
@@ -59,6 +58,12 @@ static inline int safe_atoi32(const char *s, int32_t *ret_i) {
|
||||
return safe_atoi(s, (int*) ret_i);
|
||||
}
|
||||
|
||||
+int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu);
|
||||
+
|
||||
+static inline int safe_atollu(const char *s, long long unsigned *ret_llu) {
|
||||
+ return safe_atollu_full(s, 0, ret_llu);
|
||||
+}
|
||||
+
|
||||
static inline int safe_atou64(const char *s, uint64_t *ret_u) {
|
||||
assert_cc(sizeof(uint64_t) == sizeof(unsigned long long));
|
||||
return safe_atollu(s, (unsigned long long*) ret_u);
|
||||
@@ -69,6 +74,11 @@ static inline int safe_atoi64(const char *s, int64_t *ret_i) {
|
||||
return safe_atolli(s, (long long int*) ret_i);
|
||||
}
|
||||
|
||||
+static inline int safe_atoux64(const char *s, uint64_t *ret) {
|
||||
+ assert_cc(sizeof(int64_t) == sizeof(long long unsigned));
|
||||
+ return safe_atollu_full(s, 16, (long long unsigned*) ret);
|
||||
+}
|
||||
+
|
||||
#if LONG_MAX == INT_MAX
|
||||
static inline int safe_atolu(const char *s, unsigned long *ret_u) {
|
||||
assert_cc(sizeof(unsigned long) == sizeof(unsigned));
|
||||
diff --git a/src/test/test-parse-util.c b/src/test/test-parse-util.c
|
||||
index d732f402f0..1627bc747d 100644
|
||||
--- a/src/test/test-parse-util.c
|
||||
+++ b/src/test/test-parse-util.c
|
||||
@@ -561,6 +561,44 @@ static void test_safe_atoi64(void) {
|
||||
assert_se(r == -EINVAL);
|
||||
}
|
||||
|
||||
+static void test_safe_atoux64(void) {
|
||||
+ int r;
|
||||
+ uint64_t l;
|
||||
+
|
||||
+ r = safe_atoux64("12345", &l);
|
||||
+ assert_se(r == 0);
|
||||
+ assert_se(l == 0x12345);
|
||||
+
|
||||
+ r = safe_atoux64(" 12345", &l);
|
||||
+ assert_se(r == 0);
|
||||
+ assert_se(l == 0x12345);
|
||||
+
|
||||
+ r = safe_atoux64("0x12345", &l);
|
||||
+ assert_se(r == 0);
|
||||
+ assert_se(l == 0x12345);
|
||||
+
|
||||
+ r = safe_atoux64("18446744073709551617", &l);
|
||||
+ assert_se(r == -ERANGE);
|
||||
+
|
||||
+ r = safe_atoux64("-1", &l);
|
||||
+ assert_se(r == -ERANGE);
|
||||
+
|
||||
+ r = safe_atoux64(" -1", &l);
|
||||
+ assert_se(r == -ERANGE);
|
||||
+
|
||||
+ r = safe_atoux64("junk", &l);
|
||||
+ assert_se(r == -EINVAL);
|
||||
+
|
||||
+ r = safe_atoux64("123x", &l);
|
||||
+ assert_se(r == -EINVAL);
|
||||
+
|
||||
+ r = safe_atoux64("12.3", &l);
|
||||
+ assert_se(r == -EINVAL);
|
||||
+
|
||||
+ r = safe_atoux64("", &l);
|
||||
+ assert_se(r == -EINVAL);
|
||||
+}
|
||||
+
|
||||
static void test_safe_atod(void) {
|
||||
int r;
|
||||
double d;
|
||||
@@ -838,6 +876,7 @@ int main(int argc, char *argv[]) {
|
||||
test_safe_atoux16();
|
||||
test_safe_atou64();
|
||||
test_safe_atoi64();
|
||||
+ test_safe_atoux64();
|
||||
test_safe_atod();
|
||||
test_parse_percent();
|
||||
test_parse_percent_unbounded();
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,155 @@
|
||||
From 707e93aff8f358f8a62117e54b857530d6594e4b Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Mon, 1 Jun 2020 17:06:19 +0200
|
||||
Subject: [PATCH] parse-util: allow tweaking how to parse integers
|
||||
|
||||
This allows disabling a few alternative ways to decode integers
|
||||
formatted as strings, for safety reasons.
|
||||
|
||||
See: #15991
|
||||
Reference: https://github.com/systemd/systemd/commit/707e93aff8f358f8a62117e54b857530d6594e4b
|
||||
Conflict: Add inline function safe_atou32_full.
|
||||
---
|
||||
src/basic/parse-util.c | 65 +++++++++++++++++++++++++++++++++---------
|
||||
src/basic/parse-util.h | 13 ++++++++-
|
||||
2 files changed, 64 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
|
||||
index 59f8a31cec..15818958e4 100644
|
||||
--- a/src/basic/parse-util.c
|
||||
+++ b/src/basic/parse-util.c
|
||||
@@ -359,20 +359,35 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
||||
unsigned long l;
|
||||
|
||||
assert(s);
|
||||
- assert(base <= 16);
|
||||
+ assert(SAFE_ATO_MASK_FLAGS(base) <= 16);
|
||||
|
||||
- /* strtoul() is happy to parse negative values, and silently
|
||||
- * converts them to unsigned values without generating an
|
||||
- * error. We want a clean error, hence let's look for the "-"
|
||||
- * prefix on our own, and generate an error. But let's do so
|
||||
- * only after strtoul() validated that the string is clean
|
||||
- * otherwise, so that we return EINVAL preferably over
|
||||
- * ERANGE. */
|
||||
+ /* strtoul() is happy to parse negative values, and silently converts them to unsigned values without
|
||||
+ * generating an error. We want a clean error, hence let's look for the "-" prefix on our own, and
|
||||
+ * generate an error. But let's do so only after strtoul() validated that the string is clean
|
||||
+ * otherwise, so that we return EINVAL preferably over ERANGE. */
|
||||
+
|
||||
+ if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_WHITESPACE) &&
|
||||
+ strchr(WHITESPACE, s[0]))
|
||||
+ return -EINVAL;
|
||||
|
||||
s += strspn(s, WHITESPACE);
|
||||
|
||||
+ if (FLAGS_SET(base, SAFE_ATO_REFUSE_PLUS_MINUS) &&
|
||||
+ IN_SET(s[0], '+', '-'))
|
||||
+ return -EINVAL; /* Note that we check the "-" prefix again a second time below, but return a
|
||||
+ * different error. I.e. if the SAFE_ATO_REFUSE_PLUS_MINUS flag is set we
|
||||
+ * blanket refuse +/- prefixed integers, while if it is missing we'll just
|
||||
+ * return ERANGE, because the string actually parses correctly, but doesn't
|
||||
+ * fit in the return type. */
|
||||
+
|
||||
+ if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_ZERO) &&
|
||||
+ s[0] == '0' && !streq(s, "0"))
|
||||
+ return -EINVAL; /* This is particularly useful to avoid ambiguities between C's octal
|
||||
+ * notation and assumed-to-be-decimal integers with a leading zero. */
|
||||
+
|
||||
errno = 0;
|
||||
- l = strtoul(s, &x, base);
|
||||
+ l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base) /* Let's mask off the flags bits so that only the actual
|
||||
+ * base is left */);
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
if (!x || x == s || *x != 0)
|
||||
@@ -414,11 +429,24 @@ int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu)
|
||||
unsigned long long l;
|
||||
|
||||
assert(s);
|
||||
+ assert(SAFE_ATO_MASK_FLAGS(base) <= 16);
|
||||
+
|
||||
+ if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_WHITESPACE) &&
|
||||
+ strchr(WHITESPACE, s[0]))
|
||||
+ return -EINVAL;
|
||||
|
||||
s += strspn(s, WHITESPACE);
|
||||
|
||||
+ if (FLAGS_SET(base, SAFE_ATO_REFUSE_PLUS_MINUS) &&
|
||||
+ IN_SET(s[0], '+', '-'))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_ZERO) &&
|
||||
+ s[0] == '0' && s[1] != 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
errno = 0;
|
||||
- l = strtoull(s, &x, base);
|
||||
+ l = strtoull(s, &x, SAFE_ATO_MASK_FLAGS(base));
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
if (!x || x == s || *x != 0)
|
||||
@@ -480,13 +508,24 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
|
||||
unsigned long l;
|
||||
|
||||
assert(s);
|
||||
- assert(ret);
|
||||
- assert(base <= 16);
|
||||
+ assert(SAFE_ATO_MASK_FLAGS(base) <= 16);
|
||||
+
|
||||
+ if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_WHITESPACE) &&
|
||||
+ strchr(WHITESPACE, s[0]))
|
||||
+ return -EINVAL;
|
||||
|
||||
s += strspn(s, WHITESPACE);
|
||||
|
||||
+ if (FLAGS_SET(base, SAFE_ATO_REFUSE_PLUS_MINUS) &&
|
||||
+ IN_SET(s[0], '+', '-'))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (FLAGS_SET(base, SAFE_ATO_REFUSE_LEADING_ZERO) &&
|
||||
+ s[0] == '0' && s[1] != 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
errno = 0;
|
||||
- l = strtoul(s, &x, base);
|
||||
+ l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base));
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
if (!x || x == s || *x != 0)
|
||||
diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h
|
||||
index 84a2c8a..ae7fca7 100644
|
||||
--- a/src/basic/parse-util.h
|
||||
+++ b/src/basic/parse-util.h
|
||||
@@ -22,6 +22,12 @@ int parse_range(const char *t, unsigned *lower, unsigned *upper);
|
||||
int parse_errno(const char *t);
|
||||
int parse_syscall_and_errno(const char *in, char **name, int *error);
|
||||
|
||||
+#define SAFE_ATO_REFUSE_PLUS_MINUS (1U << 30)
|
||||
+#define SAFE_ATO_REFUSE_LEADING_ZERO (1U << 29)
|
||||
+#define SAFE_ATO_REFUSE_LEADING_WHITESPACE (1U << 28)
|
||||
+#define SAFE_ATO_ALL_FLAGS (SAFE_ATO_REFUSE_PLUS_MINUS|SAFE_ATO_REFUSE_LEADING_ZERO|SAFE_ATO_REFUSE_LEADING_WHITESPACE)
|
||||
+#define SAFE_ATO_MASK_FLAGS(base) ((base) & ~SAFE_ATO_ALL_FLAGS)
|
||||
+
|
||||
int safe_atou_full(const char *s, unsigned base, unsigned *ret_u);
|
||||
|
||||
static inline int safe_atou(const char *s, unsigned *ret_u) {
|
||||
@@ -45,9 +51,14 @@ static inline int safe_atoux16(const char *s, uint16_t *ret) {
|
||||
|
||||
int safe_atoi16(const char *s, int16_t *ret);
|
||||
|
||||
+static inline int safe_atou32_full(const char *s, unsigned base, uint32_t *ret_u) {
|
||||
+ assert_cc(sizeof(uint32_t) == sizeof(unsigned));
|
||||
+ return safe_atou_full(s, base, (unsigned*) ret_u);
|
||||
+}
|
||||
+
|
||||
static inline int safe_atou32(const char *s, uint32_t *ret_u) {
|
||||
assert_cc(sizeof(uint32_t) == sizeof(unsigned));
|
||||
- return safe_atou(s, (unsigned*) ret_u);
|
||||
+ return safe_atou32_full(s, 0, (unsigned*) ret_u);
|
||||
}
|
||||
|
||||
static inline int safe_atoi32(const char *s, int32_t *ret_i) {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
From c78eefc13562a8fc0c22c00a6d3001af89860258 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Mon, 1 Jun 2020 17:08:38 +0200
|
||||
Subject: [PATCH] parse-util: allow '-0' as alternative to '0' and '+0'
|
||||
|
||||
Let's allow "-0" as alternative to "+0" and "0" when parsing integers,
|
||||
unless the new SAFE_ATO_REFUSE_PLUS_MINUS flag is specified.
|
||||
|
||||
In cases where allowing the +/- syntax shall not be allowed
|
||||
SAFE_ATO_REFUSE_PLUS_MINUS is the right flag to use, but this also means
|
||||
that -0 as only negative integer that fits into an unsigned value should
|
||||
be acceptable if the flag is not specified.
|
||||
Reference: https://github.com/systemd/systemd/commit/c78eefc13562a8fc0c22c00a6d3001af89860258
|
||||
Conflict: NA
|
||||
---
|
||||
src/basic/parse-util.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
|
||||
index 15818958e4..7344dc4311 100644
|
||||
--- a/src/basic/parse-util.c
|
||||
+++ b/src/basic/parse-util.c
|
||||
@@ -392,7 +392,7 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
||||
return -errno;
|
||||
if (!x || x == s || *x != 0)
|
||||
return -EINVAL;
|
||||
- if (s[0] == '-')
|
||||
+ if (l != 0 && s[0] == '-')
|
||||
return -ERANGE;
|
||||
if ((unsigned long) (unsigned) l != l)
|
||||
return -ERANGE;
|
||||
@@ -451,7 +451,7 @@ int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu)
|
||||
return -errno;
|
||||
if (!x || x == s || *x != 0)
|
||||
return -EINVAL;
|
||||
- if (*s == '-')
|
||||
+ if (l != 0 && s[0] == '-')
|
||||
return -ERANGE;
|
||||
|
||||
if (ret_llu)
|
||||
@@ -493,7 +493,7 @@ int safe_atou8(const char *s, uint8_t *ret) {
|
||||
return -errno;
|
||||
if (!x || x == s || *x != 0)
|
||||
return -EINVAL;
|
||||
- if (s[0] == '-')
|
||||
+ if (l != 0 && s[0] == '-')
|
||||
return -ERANGE;
|
||||
if ((unsigned long) (uint8_t) l != l)
|
||||
return -ERANGE;
|
||||
@@ -530,7 +530,7 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
|
||||
return -errno;
|
||||
if (!x || x == s || *x != 0)
|
||||
return -EINVAL;
|
||||
- if (s[0] == '-')
|
||||
+ if (l != 0 && s[0] == '-')
|
||||
return -ERANGE;
|
||||
if ((unsigned long) (uint16_t) l != l)
|
||||
return -ERANGE;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
From aa85e4d3cef8ca8436e480bce9fa4ce72876b636 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Mon, 1 Jun 2020 17:10:27 +0200
|
||||
Subject: [PATCH] parse-util: make return parameter optional in
|
||||
safe_atou16_full()
|
||||
|
||||
All other safe_atoXYZ_full() functions have the parameter optional,
|
||||
let's make it optoinal here, too.
|
||||
Reference: https://github.com/systemd/systemd/commit/aa85e4d3cef8ca8436e480bce9fa4ce72876b636
|
||||
Conflict: NA
|
||||
---
|
||||
src/basic/parse-util.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
|
||||
index 7344dc4311..c58f2cdda1 100644
|
||||
--- a/src/basic/parse-util.c
|
||||
+++ b/src/basic/parse-util.c
|
||||
@@ -535,7 +535,9 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
|
||||
if ((unsigned long) (uint16_t) l != l)
|
||||
return -ERANGE;
|
||||
|
||||
- *ret = (uint16_t) l;
|
||||
+ if (ret)
|
||||
+ *ret = (uint16_t) l;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
From c44702a8bd8cc8b7f2f1df21db9308d9af7dda5b Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Mon, 1 Jun 2020 17:16:04 +0200
|
||||
Subject: [PATCH] parse-util: rewrite parse_mode() on top of safe_atou_full()
|
||||
|
||||
Parsing is hard, hence let's use our own careful wrappers wherever
|
||||
possible.
|
||||
Reference: https://github.com/systemd/systemd/commit/c44702a8bd8cc8b7f2f1df21db9308d9af7dda5b
|
||||
Conflict: NA
|
||||
---
|
||||
src/basic/parse-util.c | 28 +++++++++++++---------------
|
||||
1 file changed, 13 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
|
||||
index c58f2cdda1..0f6d24f590 100644
|
||||
--- a/src/basic/parse-util.c
|
||||
+++ b/src/basic/parse-util.c
|
||||
@@ -70,26 +70,24 @@ int parse_pid(const char *s, pid_t* ret_pid) {
|
||||
}
|
||||
|
||||
int parse_mode(const char *s, mode_t *ret) {
|
||||
- char *x;
|
||||
- long l;
|
||||
+ unsigned m;
|
||||
+ int r;
|
||||
|
||||
assert(s);
|
||||
- assert(ret);
|
||||
|
||||
- s += strspn(s, WHITESPACE);
|
||||
- if (s[0] == '-')
|
||||
- return -ERANGE;
|
||||
-
|
||||
- errno = 0;
|
||||
- l = strtol(s, &x, 8);
|
||||
- if (errno > 0)
|
||||
- return -errno;
|
||||
- if (!x || x == s || *x != 0)
|
||||
- return -EINVAL;
|
||||
- if (l < 0 || l > 07777)
|
||||
+ r = safe_atou_full(s, 8 |
|
||||
+ SAFE_ATO_REFUSE_PLUS_MINUS, /* Leading '+' or even '-' char? that's just weird,
|
||||
+ * refuse. User might have wanted to add mode flags or
|
||||
+ * so, but this parser doesn't allow that, so let's
|
||||
+ * better be safe. */
|
||||
+ &m);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ if (m > 07777)
|
||||
return -ERANGE;
|
||||
|
||||
- *ret = (mode_t) l;
|
||||
+ if (ret)
|
||||
+ *ret = m;
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,79 @@
|
||||
From f5979b63cc305ba217dfd174b1bf0583bcf75a73 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Mon, 1 Jun 2020 17:16:46 +0200
|
||||
Subject: [PATCH] user-util: be stricter in parse_uid()
|
||||
|
||||
Let's refuse "+" and "-" prefixed UIDs. Let's refuse whitespace-prefixed
|
||||
UIDS, Let's refuse zero-prefixed UIDs. Let's be safe than sorry.
|
||||
Reference: https://github.com/systemd/systemd/commit/f5979b63cc305ba217dfd174b1bf0583bcf75a73
|
||||
Conflict: NA
|
||||
---
|
||||
src/basic/user-util.c | 10 +++++++++-
|
||||
src/test/test-user-util.c | 26 +++++++++++++++++++++++---
|
||||
2 files changed, 32 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
|
||||
index 2db8ef6abf..4d087b1d3e 100644
|
||||
--- a/src/basic/user-util.c
|
||||
+++ b/src/basic/user-util.c
|
||||
@@ -49,7 +49,15 @@ int parse_uid(const char *s, uid_t *ret) {
|
||||
assert(s);
|
||||
|
||||
assert_cc(sizeof(uid_t) == sizeof(uint32_t));
|
||||
- r = safe_atou32_full(s, 10, &uid);
|
||||
+
|
||||
+ /* We are very strict when parsing UIDs, and prohibit +/- as prefix, leading zero as prefix, and
|
||||
+ * whitespace. We do this, since this call is often used in a context where we parse things as UID
|
||||
+ * first, and if that doesn't work we fall back to NSS. Thus we really want to make sure that UIDs
|
||||
+ * are parsed as UIDs only if they really really look like UIDs. */
|
||||
+ r = safe_atou32_full(s, 10
|
||||
+ | SAFE_ATO_REFUSE_PLUS_MINUS
|
||||
+ | SAFE_ATO_REFUSE_LEADING_ZERO
|
||||
+ | SAFE_ATO_REFUSE_LEADING_WHITESPACE, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c
|
||||
index 3165232fef..7d2efc8c59 100644
|
||||
--- a/src/test/test-user-util.c
|
||||
+++ b/src/test/test-user-util.c
|
||||
@@ -54,13 +54,33 @@ static void test_parse_uid(void) {
|
||||
assert_se(r == -EINVAL);
|
||||
assert_se(uid == 100);
|
||||
|
||||
+ r = parse_uid("+1234", &uid);
|
||||
+ assert_se(r == -EINVAL);
|
||||
+ assert_se(uid == 100);
|
||||
+
|
||||
+ r = parse_uid("-1234", &uid);
|
||||
+ assert_se(r == -EINVAL);
|
||||
+ assert_se(uid == 100);
|
||||
+
|
||||
+ r = parse_uid(" 1234", &uid);
|
||||
+ assert_se(r == -EINVAL);
|
||||
+ assert_se(uid == 100);
|
||||
+
|
||||
r = parse_uid("01234", &uid);
|
||||
- assert_se(r == 0);
|
||||
- assert_se(uid == 1234);
|
||||
+ assert_se(r == -EINVAL);
|
||||
+ assert_se(uid == 100);
|
||||
+
|
||||
+ r = parse_uid("-0", &uid);
|
||||
+ assert_se(r == -EINVAL);
|
||||
+ assert_se(uid == 100);
|
||||
+
|
||||
+ r = parse_uid("+0", &uid);
|
||||
+ assert_se(r == -EINVAL);
|
||||
+ assert_se(uid == 100);
|
||||
|
||||
r = parse_uid("asdsdas", &uid);
|
||||
assert_se(r == -EINVAL);
|
||||
- assert_se(uid == 1234);
|
||||
+ assert_se(uid == 100);
|
||||
}
|
||||
|
||||
static void test_uid_ptr(void) {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,165 @@
|
||||
From fc80cabcf584a8b486bdff5be0c074fec4059cdc Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Mon, 1 Jun 2020 17:31:51 +0200
|
||||
Subject: [PATCH] parse-util: also parse integers prefixed with 0b and 0o
|
||||
|
||||
Let's adopt Python 3 style 0b and 0x syntaxes, because it makes a ton of
|
||||
sense, in particular in bitmask settings.
|
||||
Reference: https://github.com/systemd/systemd/commit/fc80cabcf584a8b486bdff5be0c074fec4059cdc
|
||||
Conflict: Also include strv.h.
|
||||
---
|
||||
src/basic/parse-util.c | 57 ++++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 52 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
|
||||
index b4c7f0d..bf56410 100644
|
||||
--- a/src/basic/parse-util.c
|
||||
+++ b/src/basic/parse-util.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "process-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "string-util.h"
|
||||
+#include "strv.h"
|
||||
|
||||
int parse_boolean(const char *v) {
|
||||
if (!v)
|
||||
@@ -360,6 +361,32 @@ int parse_syscall_and_errno(const char *in, char **name, int *error) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const char *mangle_base(const char *s, unsigned *base) {
|
||||
+ const char *k;
|
||||
+
|
||||
+ assert(s);
|
||||
+ assert(base);
|
||||
+
|
||||
+ /* Base already explicitly specified, then don't do anything. */
|
||||
+ if (SAFE_ATO_MASK_FLAGS(*base) != 0)
|
||||
+ return s;
|
||||
+
|
||||
+ /* Support Python 3 style "0b" and 0x" prefixes, because they truly make sense, much more than C's "0" prefix for octal. */
|
||||
+ k = STARTSWITH_SET(s, "0b", "0B");
|
||||
+ if (k) {
|
||||
+ *base = 2 | (*base & SAFE_ATO_ALL_FLAGS);
|
||||
+ return k;
|
||||
+ }
|
||||
+
|
||||
+ k = STARTSWITH_SET(s, "0o", "0O");
|
||||
+ if (k) {
|
||||
+ *base = 8 | (*base & SAFE_ATO_ALL_FLAGS);
|
||||
+ return k;
|
||||
+ }
|
||||
+
|
||||
+ return s;
|
||||
+}
|
||||
+
|
||||
int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
||||
char *x = NULL;
|
||||
unsigned long l;
|
||||
@@ -391,6 +418,8 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
||||
return -EINVAL; /* This is particularly useful to avoid ambiguities between C's octal
|
||||
* notation and assumed-to-be-decimal integers with a leading zero. */
|
||||
|
||||
+ s = mangle_base(s, &base);
|
||||
+
|
||||
errno = 0;
|
||||
l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base) /* Let's mask off the flags bits so that only the actual
|
||||
* base is left */);
|
||||
@@ -410,13 +439,17 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
||||
}
|
||||
|
||||
int safe_atoi(const char *s, int *ret_i) {
|
||||
+ unsigned base = 0;
|
||||
char *x = NULL;
|
||||
long l;
|
||||
|
||||
assert(s);
|
||||
|
||||
+ s += strspn(s, WHITESPACE);
|
||||
+ s = mangle_base(s, &base);
|
||||
+
|
||||
errno = 0;
|
||||
- l = strtol(s, &x, 0);
|
||||
+ l = strtol(s, &x, base);
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
if (!x || x == s || *x != 0)
|
||||
@@ -451,6 +484,8 @@ int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu)
|
||||
s[0] == '0' && s[1] != 0)
|
||||
return -EINVAL;
|
||||
|
||||
+ s = mangle_base(s, &base);
|
||||
+
|
||||
errno = 0;
|
||||
l = strtoull(s, &x, SAFE_ATO_MASK_FLAGS(base));
|
||||
if (errno > 0)
|
||||
@@ -467,13 +502,17 @@ int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu)
|
||||
}
|
||||
|
||||
int safe_atolli(const char *s, long long int *ret_lli) {
|
||||
+ unsigned base = 0;
|
||||
char *x = NULL;
|
||||
long long l;
|
||||
|
||||
assert(s);
|
||||
|
||||
+ s += strspn(s, WHITESPACE);
|
||||
+ s = mangle_base(s, &base);
|
||||
+
|
||||
errno = 0;
|
||||
- l = strtoll(s, &x, 0);
|
||||
+ l = strtoll(s, &x, base);
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
if (!x || x == s || *x != 0)
|
||||
@@ -486,15 +525,17 @@ int safe_atolli(const char *s, long long int *ret_lli) {
|
||||
}
|
||||
|
||||
int safe_atou8(const char *s, uint8_t *ret) {
|
||||
- char *x = NULL;
|
||||
+ unsigned base = 0;
|
||||
unsigned long l;
|
||||
+ char *x = NULL;
|
||||
|
||||
assert(s);
|
||||
|
||||
s += strspn(s, WHITESPACE);
|
||||
+ s = mangle_base(s, &base);
|
||||
|
||||
errno = 0;
|
||||
- l = strtoul(s, &x, 0);
|
||||
+ l = strtoul(s, &x, base);
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
if (!x || x == s || *x != 0)
|
||||
@@ -530,6 +571,8 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
|
||||
s[0] == '0' && s[1] != 0)
|
||||
return -EINVAL;
|
||||
|
||||
+ s = mangle_base(s, &base);
|
||||
+
|
||||
errno = 0;
|
||||
l = strtoul(s, &x, SAFE_ATO_MASK_FLAGS(base));
|
||||
if (errno > 0)
|
||||
@@ -548,13 +591,17 @@ int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
|
||||
}
|
||||
|
||||
int safe_atoi16(const char *s, int16_t *ret) {
|
||||
+ unsigned base = 0;
|
||||
char *x = NULL;
|
||||
long l;
|
||||
|
||||
assert(s);
|
||||
|
||||
+ s += strspn(s, WHITESPACE);
|
||||
+ s = mangle_base(s, &base);
|
||||
+
|
||||
errno = 0;
|
||||
- l = strtol(s, &x, 0);
|
||||
+ l = strtol(s, &x, base);
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
if (!x || x == s || *x != 0)
|
||||
--
|
||||
2.23.0
|
||||
|
||||
21
systemd.spec
21
systemd.spec
@ -16,7 +16,7 @@
|
||||
Name: systemd
|
||||
Url: https://www.freedesktop.org/wiki/Software/systemd
|
||||
Version: 243
|
||||
Release: 53
|
||||
Release: 54
|
||||
License: MIT and LGPLv2+ and GPLv2+
|
||||
Summary: System and Service Manager
|
||||
|
||||
@ -156,6 +156,22 @@ Patch0108: backport-udevadm-fix-tag-match-help-description.patch
|
||||
Patch0109: backport-fix-ConditionDirectoryNotEmpty-when-it-comes-to-a-No.patch
|
||||
Patch0110: backport-fix-ConditionPathIsReadWrite-when-path-does-not-exis.patch
|
||||
Patch0111: backport-fix-DirectoryNotEmpty-when-it-comes-to-a-Non-directo.patch
|
||||
Patch0112: backport-0001-CVE-2020-13776-user-util-Allow-names-starting-with-a-digit.patch
|
||||
Patch0113: backport-0002-CVE-2020-13776-user-util-switch-order-of-checks-in-valid_user_group.patch
|
||||
Patch0114: backport-0003-CVE-2020-13776-user-util-rework-how-we-validate-user-names.patch
|
||||
Patch0115: backport-0004-CVE-2020-13776-docs-add-a-longer-document-explaining-our-rules-on-u.patch
|
||||
Patch0116: backport-0005-CVE-2020-13776-docs-hook-up-the-new-USER_NAMES-document-everywhere.patch
|
||||
Patch0117: backport-0006-CVE-2020-13776-catalog-add-entry-for-SD_MESSAGE_UNSAFE_USER_NAME.patch
|
||||
Patch0118: backport-0007-CVE-2020-13776-basic-user-util-always-use-base-10-for-user-group-nu.patch
|
||||
Patch0119: backport-0008-CVE-2020-13776-parse-util-sometimes-it-is-useful-to-check-if-a-stri.patch
|
||||
Patch0120: backport-0009-CVE-2020-13776-basic-parse-util-add-safe_atoux64.patch
|
||||
Patch0121: backport-0010-CVE-2020-13776-parse-util-allow-tweaking-how-to-parse-integers.patch
|
||||
Patch0122: backport-0011-CVE-2020-13776-parse-util-allow-0-as-alternative-to-0-and-0.patch
|
||||
Patch0123: backport-0012-CVE-2020-13776-parse-util-make-return-parameter-optional-in-safe_at.patch
|
||||
Patch0124: backport-0013-CVE-2020-13776-parse-util-rewrite-parse_mode-on-top-of-safe_atou_fu.patch
|
||||
Patch0125: backport-0014-CVE-2020-13776-user-util-be-stricter-in-parse_uid.patch
|
||||
Patch0126: backport-0015-CVE-2020-13776-parse-util-also-parse-integers-prefixed-with-0b-and-.patch
|
||||
|
||||
|
||||
#openEuler
|
||||
Patch9002: 1509-fix-journal-file-descriptors-leak-problems.patch
|
||||
@ -1544,6 +1560,9 @@ fi
|
||||
%exclude /usr/share/man/man3/*
|
||||
|
||||
%changelog
|
||||
* Wed Feb 16 2021 yangmingtai <yangmingtai@huawei.com> - 243-54
|
||||
- fix CVE-2020-13776
|
||||
|
||||
* Wed Jan 26 2021 yangmingtai <yangmingtai@huawei.com> - 243-53
|
||||
- fix ConditionDirectoryNotEmpty,ConditionPathIsReadWrite and DirectoryNotEmpty
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user