New upstream version 246.2

This commit is contained in:
Michael Biebl 2020-08-17 21:43:29 +02:00
parent bfa1f358a2
commit e80c5e5371
12 changed files with 104 additions and 25 deletions

View File

@ -8778,7 +8778,7 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
<refsect1> <refsect1>
<title>Scope Unit Objects</title> <title>Scope Unit Objects</title>
<para>All slice unit objects implement the <interfacename>org.freedesktop.systemd1.Scope</interfacename> <para>All scope unit objects implement the <interfacename>org.freedesktop.systemd1.Scope</interfacename>
interface (described here) in addition to the generic interface (described here) in addition to the generic
<interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para> <interfacename>org.freedesktop.systemd1.Unit</interfacename> interface (see above).</para>

View File

@ -217,7 +217,7 @@
this notification message has been sent. If this option is used, <varname>NotifyAccess=</varname> (see this notification message has been sent. If this option is used, <varname>NotifyAccess=</varname> (see
below) should be set to open access to the notification socket provided by systemd. If below) should be set to open access to the notification socket provided by systemd. If
<varname>NotifyAccess=</varname> is missing or set to <option>none</option>, it will be forcibly set to <varname>NotifyAccess=</varname> is missing or set to <option>none</option>, it will be forcibly set to
<option>main</option></para></listitem>. <option>main</option>.</para></listitem>
<listitem><para>Behavior of <option>idle</option> is very similar to <option>simple</option>; however, <listitem><para>Behavior of <option>idle</option> is very similar to <option>simple</option>; however,
actual execution of the service program is delayed until all active jobs are dispatched. This may be used actual execution of the service program is delayed until all active jobs are dispatched. This may be used

View File

@ -863,6 +863,37 @@ bool valid_gecos(const char *d) {
return true; return true;
} }
char *mangle_gecos(const char *d) {
char *mangled;
/* Makes sure the provided string becomes valid as a GEGOS field, by dropping bad chars. glibc's
* putwent() only changes \n and : to spaces. We do more: replace all CC too, and remove invalid
* UTF-8 */
mangled = strdup(d);
if (!mangled)
return NULL;
for (char *i = mangled; *i; i++) {
int len;
if ((uint8_t) *i < (uint8_t) ' ' || *i == ':') {
*i = ' ';
continue;
}
len = utf8_encoded_valid_unichar(i, (size_t) -1);
if (len < 0) {
*i = ' ';
continue;
}
i += len - 1;
}
return mangled;
}
bool valid_home(const char *p) { bool valid_home(const char *p) {
/* Note that this function is also called by valid_shell(), any /* Note that this function is also called by valid_shell(), any
* changes must account for that. */ * changes must account for that. */

View File

@ -105,6 +105,7 @@ typedef enum ValidUserFlags {
bool valid_user_group_name(const char *u, ValidUserFlags flags); bool valid_user_group_name(const char *u, ValidUserFlags flags);
bool valid_gecos(const char *d); bool valid_gecos(const char *d);
char *mangle_gecos(const char *d);
bool valid_home(const char *p); bool valid_home(const char *p);
static inline bool valid_shell(const char *p) { static inline bool valid_shell(const char *p) {

View File

@ -34,6 +34,7 @@ static int help(int argc, char *argv[], void *userdata) {
printf("%s [OPTIONS...] COMMAND\n" printf("%s [OPTIONS...] COMMAND\n"
"\n%sMark the boot process as good or bad.%s\n" "\n%sMark the boot process as good or bad.%s\n"
"\nCommands:\n" "\nCommands:\n"
" status Show status of current boot loader entry\n"
" good Mark this boot as good\n" " good Mark this boot as good\n"
" bad Mark this boot as bad\n" " bad Mark this boot as bad\n"
" indeterminate Undo any marking as good or bad\n" " indeterminate Undo any marking as good or bad\n"

View File

@ -1830,11 +1830,11 @@ static int make_tmp_prefix(const char *prefix) {
static int make_tmp_subdir(const char *parent, char **ret) { static int make_tmp_subdir(const char *parent, char **ret) {
_cleanup_free_ char *y = NULL; _cleanup_free_ char *y = NULL;
RUN_WITH_UMASK(0000) { y = path_join(parent, "/tmp");
y = strjoin(parent, "/tmp"); if (!y)
if (!y) return -ENOMEM;
return -ENOMEM;
RUN_WITH_UMASK(0000) {
if (mkdir(y, 0777 | S_ISVTX) < 0) if (mkdir(y, 0777 | S_ISVTX) < 0)
return -errno; return -errno;
} }
@ -1890,9 +1890,9 @@ static int setup_one_tmp_dir(const char *id, const char *prefix, char **path, ch
if (r < 0) if (r < 0)
return r; return r;
x = strdup(RUN_SYSTEMD_EMPTY); r = free_and_strdup(&x, RUN_SYSTEMD_EMPTY);
if (!x) if (r < 0)
return -ENOMEM; return r;
} }
*path = TAKE_PTR(x); *path = TAKE_PTR(x);

View File

@ -402,6 +402,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
"close\0" "close\0"
"creat\0" "creat\0"
"faccessat\0" "faccessat\0"
"faccessat2\0"
"fallocate\0" "fallocate\0"
"fchdir\0" "fchdir\0"
"fchmod\0" "fchmod\0"

View File

@ -5,6 +5,7 @@
#include "libcrypt-util.h" #include "libcrypt-util.h"
#include "strv.h" #include "strv.h"
#include "user-record-nss.h" #include "user-record-nss.h"
#include "user-util.h"
#define SET_IF(field, condition, value, fallback) \ #define SET_IF(field, condition, value, fallback) \
field = (condition) ? (value) : (fallback) field = (condition) ? (value) : (fallback)
@ -34,10 +35,25 @@ int nss_passwd_to_user_record(
if (r < 0) if (r < 0)
return r; return r;
r = free_and_strdup(&hr->real_name, /* Some bad NSS modules synthesize GECOS fields with embedded ":" or "\n" characters, which are not
streq_ptr(pwd->pw_gecos, hr->user_name) ? NULL : empty_to_null(pwd->pw_gecos)); * something we can output in /etc/passwd compatible format, since these are record separators
if (r < 0) * there. We normally refuse that, but we need to maintain compatibility with arbitrary NSS modules,
return r; * hence let's do what glibc does: mangle the data to fit the format. */
if (isempty(pwd->pw_gecos) || streq_ptr(pwd->pw_gecos, hr->user_name))
hr->real_name = mfree(hr->real_name);
else if (valid_gecos(pwd->pw_gecos)) {
r = free_and_strdup(&hr->real_name, pwd->pw_gecos);
if (r < 0)
return r;
} else {
_cleanup_free_ char *mangled = NULL;
mangled = mangle_gecos(pwd->pw_gecos);
if (!mangled)
return -ENOMEM;
free_and_replace(hr->real_name, mangled);
}
r = free_and_strdup(&hr->home_directory, empty_to_null(pwd->pw_dir)); r = free_and_strdup(&hr->home_directory, empty_to_null(pwd->pw_dir));
if (r < 0) if (r < 0)

View File

@ -206,7 +206,6 @@ int json_dispatch_realm(const char *name, JsonVariant *variant, JsonDispatchFlag
static int json_dispatch_gecos(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) { static int json_dispatch_gecos(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
char **s = userdata; char **s = userdata;
const char *n; const char *n;
int r;
if (json_variant_is_null(variant)) { if (json_variant_is_null(variant)) {
*s = mfree(*s); *s = mfree(*s);
@ -217,12 +216,20 @@ static int json_dispatch_gecos(const char *name, JsonVariant *variant, JsonDispa
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name)); return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
n = json_variant_string(variant); n = json_variant_string(variant);
if (!valid_gecos(n)) if (valid_gecos(n)) {
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a valid GECOS compatible real name.", strna(name)); if (free_and_strdup(s, n) < 0)
return json_log_oom(variant, flags);
} else {
_cleanup_free_ char *m = NULL;
r = free_and_strdup(s, n); json_log(variant, flags|JSON_DEBUG, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a valid GECOS compatible string, mangling.", strna(name));
if (r < 0)
return json_log(variant, flags, r, "Failed to allocate string: %m"); m = mangle_gecos(n);
if (!m)
return json_log_oom(variant, flags);
free_and_replace(*s, m);
}
return 0; return 0;
} }

View File

@ -850,11 +850,12 @@ static void test_path_is_encrypted_one(const char *p, int expect) {
int r; int r;
r = path_is_encrypted(p); r = path_is_encrypted(p);
if (r == -ENOENT) /* This might fail, if btrfs is used and we run in a container. In that case we if (r == -ENOENT || ERRNO_IS_PRIVILEGE(r)) /* This might fail, if btrfs is used and we run in a
* cannot resolve the device node paths that BTRFS_IOC_DEV_INFO returns, because * container. In that case we cannot resolve the device node paths that
* the device nodes are unlikely to exist in the container. But if we can't stat() * BTRFS_IOC_DEV_INFO returns, because the device nodes are unlikely to exist in
* them we cannot determine the dev_t of them, and thus cannot figure out if they * the container. But if we can't stat() them we cannot determine the dev_t of
* are enrypted. Hence let's just ignore ENOENT here. */ * them, and thus cannot figure out if they are enrypted. Hence let's just ignore
* ENOENT here. Also skip the test if we lack privileges. */
return; return;
assert_se(r >= 0); assert_se(r >= 0);

View File

@ -452,6 +452,25 @@ static void test_parse_uid_range(void) {
assert_se(parse_uid_range(" 01", &a, &b) == -EINVAL && a == 4 && b == 5); assert_se(parse_uid_range(" 01", &a, &b) == -EINVAL && a == 4 && b == 5);
} }
static void test_mangle_gecos_one(const char *input, const char *expected) {
_cleanup_free_ char *p = NULL;
assert_se(p = mangle_gecos(input));
assert_se(streq(p, expected));
assert_se(valid_gecos(p));
}
static void test_mangle_gecos(void) {
test_mangle_gecos_one("", "");
test_mangle_gecos_one("root", "root");
test_mangle_gecos_one("wuff\nwuff", "wuff wuff");
test_mangle_gecos_one("wuff:wuff", "wuff wuff");
test_mangle_gecos_one("wuff\r\n:wuff", "wuff wuff");
test_mangle_gecos_one("\n--wüff-wäff-wöff::", " --wüff-wäff-wöff ");
test_mangle_gecos_one("\xc3\x28", " (");
test_mangle_gecos_one("\xe2\x28\xa1", " ( ");
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
test_uid_to_name_one(0, "root"); test_uid_to_name_one(0, "root");
test_uid_to_name_one(UID_NOBODY, NOBODY_USER_NAME); test_uid_to_name_one(UID_NOBODY, NOBODY_USER_NAME);
@ -482,6 +501,7 @@ int main(int argc, char *argv[]) {
test_valid_user_group_name_or_numeric_relaxed(); test_valid_user_group_name_or_numeric_relaxed();
test_valid_user_group_name_or_numeric(); test_valid_user_group_name_or_numeric();
test_valid_gecos(); test_valid_gecos();
test_mangle_gecos();
test_valid_home(); test_valid_home();
test_make_salt(); test_make_salt();

View File

@ -55,7 +55,8 @@ def make_index(pages):
check_id(p, t) check_id(p, t)
section = t.find('./refmeta/manvolnum').text section = t.find('./refmeta/manvolnum').text
refname = t.find('./refnamediv/refname').text refname = t.find('./refnamediv/refname').text
purpose = ' '.join(t.find('./refnamediv/refpurpose').text.split()) purpose_text = ' '.join(t.find('./refnamediv/refpurpose').itertext())
purpose = ' '.join(purpose_text.split())
for f in t.findall('./refnamediv/refname'): for f in t.findall('./refnamediv/refname'):
infos = (f.text, section, purpose, refname) infos = (f.text, section, purpose, refname)
index[f.text[0].upper()].append(infos) index[f.text[0].upper()].append(infos)