diff options
author | Thomas Haller <thaller@redhat.com> | 2019-09-24 21:57:06 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-09-25 09:09:39 +0200 |
commit | 503b5f441e7b696fb8e7b077d0e7b4c9e2991b6e (patch) | |
tree | 8d77cf1b5bebbd966dded5651838b146a52bb862 | |
parent | 6a325673cf194accecb48722d810dad39fc266e1 (diff) | |
download | NetworkManager-503b5f441e7b696fb8e7b077d0e7b4c9e2991b6e.tar.gz |
systemd: update code from upstream (2019-09-24)
This is a direct dump from systemd git.
======
SYSTEMD_DIR=../systemd
COMMIT=a007d6fc2a2b9c19bafd6465fb4f00910b824c36
(
cd "$SYSTEMD_DIR"
git checkout "$COMMIT"
git reset --hard
git clean -fdx
)
git ls-files -z :/src/systemd/src/ \
:/shared/systemd/src/ \
:/shared/nm-utils/unaligned.h | \
xargs -0 rm -f
nm_copy_sd_shared() {
mkdir -p "./shared/systemd/$(dirname "$1")"
cp "$SYSTEMD_DIR/$1" "./shared/systemd/$1"
}
nm_copy_sd_core() {
mkdir -p "./src/systemd/$(dirname "$1")"
cp "$SYSTEMD_DIR/$1" "./src/systemd/$1"
}
nm_copy_sd_nmutils() {
mkdir -p "./shared/nm-utils/"
cp "$SYSTEMD_DIR/$1" "./shared/nm-utils/${1##*/}"
}
nm_copy_sd_core "src/libsystemd-network/arp-util.c"
nm_copy_sd_core "src/libsystemd-network/arp-util.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-lease-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp-network.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-option.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-packet.c"
nm_copy_sd_core "src/libsystemd-network/dhcp-protocol.h"
nm_copy_sd_core "src/libsystemd-network/dhcp6-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp6-lease-internal.h"
nm_copy_sd_core "src/libsystemd-network/dhcp6-network.c"
nm_copy_sd_core "src/libsystemd-network/dhcp6-option.c"
nm_copy_sd_core "src/libsystemd-network/dhcp6-protocol.h"
nm_copy_sd_core "src/libsystemd-network/lldp-internal.h"
nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.c"
nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.h"
nm_copy_sd_core "src/libsystemd-network/lldp-network.c"
nm_copy_sd_core "src/libsystemd-network/lldp-network.h"
nm_copy_sd_core "src/libsystemd-network/network-internal.c"
nm_copy_sd_core "src/libsystemd-network/network-internal.h"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp-client.c"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp-lease.c"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-client.c"
nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-lease.c"
nm_copy_sd_core "src/libsystemd-network/sd-ipv4acd.c"
nm_copy_sd_core "src/libsystemd-network/sd-ipv4ll.c"
nm_copy_sd_core "src/libsystemd-network/sd-lldp.c"
nm_copy_sd_core "src/libsystemd/sd-event/event-source.h"
nm_copy_sd_core "src/libsystemd/sd-event/event-util.c"
nm_copy_sd_core "src/libsystemd/sd-event/event-util.h"
nm_copy_sd_core "src/libsystemd/sd-event/sd-event.c"
nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.c"
nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.h"
nm_copy_sd_core "src/libsystemd/sd-id128/sd-id128.c"
nm_copy_sd_core "src/systemd/_sd-common.h"
nm_copy_sd_core "src/systemd/sd-dhcp-client.h"
nm_copy_sd_core "src/systemd/sd-dhcp-lease.h"
nm_copy_sd_core "src/systemd/sd-dhcp6-client.h"
nm_copy_sd_core "src/systemd/sd-dhcp6-lease.h"
nm_copy_sd_core "src/systemd/sd-event.h"
nm_copy_sd_core "src/systemd/sd-id128.h"
nm_copy_sd_core "src/systemd/sd-ipv4acd.h"
nm_copy_sd_core "src/systemd/sd-ipv4ll.h"
nm_copy_sd_core "src/systemd/sd-lldp.h"
nm_copy_sd_core "src/systemd/sd-ndisc.h"
nm_copy_sd_nmutils "src/basic/unaligned.h"
nm_copy_sd_shared "src/basic/alloc-util.c"
nm_copy_sd_shared "src/basic/alloc-util.h"
nm_copy_sd_shared "src/basic/async.h"
nm_copy_sd_shared "src/basic/env-file.c"
nm_copy_sd_shared "src/basic/env-file.h"
nm_copy_sd_shared "src/basic/env-util.c"
nm_copy_sd_shared "src/basic/env-util.h"
nm_copy_sd_shared "src/basic/errno-util.h"
nm_copy_sd_shared "src/basic/escape.c"
nm_copy_sd_shared "src/basic/escape.h"
nm_copy_sd_shared "src/basic/ether-addr-util.c"
nm_copy_sd_shared "src/basic/ether-addr-util.h"
nm_copy_sd_shared "src/basic/extract-word.c"
nm_copy_sd_shared "src/basic/extract-word.h"
nm_copy_sd_shared "src/basic/fd-util.c"
nm_copy_sd_shared "src/basic/fd-util.h"
nm_copy_sd_shared "src/basic/fileio.c"
nm_copy_sd_shared "src/basic/fileio.h"
nm_copy_sd_shared "src/basic/format-util.c"
nm_copy_sd_shared "src/basic/format-util.h"
nm_copy_sd_shared "src/basic/fs-util.c"
nm_copy_sd_shared "src/basic/fs-util.h"
nm_copy_sd_shared "src/basic/hash-funcs.c"
nm_copy_sd_shared "src/basic/hash-funcs.h"
nm_copy_sd_shared "src/basic/hashmap.c"
nm_copy_sd_shared "src/basic/hashmap.h"
nm_copy_sd_shared "src/basic/hexdecoct.c"
nm_copy_sd_shared "src/basic/hexdecoct.h"
nm_copy_sd_shared "src/basic/hostname-util.c"
nm_copy_sd_shared "src/basic/hostname-util.h"
nm_copy_sd_shared "src/basic/in-addr-util.c"
nm_copy_sd_shared "src/basic/in-addr-util.h"
nm_copy_sd_shared "src/basic/io-util.c"
nm_copy_sd_shared "src/basic/io-util.h"
nm_copy_sd_shared "src/basic/list.h"
nm_copy_sd_shared "src/basic/log.h"
nm_copy_sd_shared "src/basic/macro.h"
nm_copy_sd_shared "src/basic/memory-util.c"
nm_copy_sd_shared "src/basic/memory-util.h"
nm_copy_sd_shared "src/basic/mempool.c"
nm_copy_sd_shared "src/basic/mempool.h"
nm_copy_sd_shared "src/basic/missing_fcntl.h"
nm_copy_sd_shared "src/basic/missing_socket.h"
nm_copy_sd_shared "src/basic/missing_stat.h"
nm_copy_sd_shared "src/basic/missing_type.h"
nm_copy_sd_shared "src/basic/parse-util.c"
nm_copy_sd_shared "src/basic/parse-util.h"
nm_copy_sd_shared "src/basic/path-util.c"
nm_copy_sd_shared "src/basic/path-util.h"
nm_copy_sd_shared "src/basic/prioq.c"
nm_copy_sd_shared "src/basic/prioq.h"
nm_copy_sd_shared "src/basic/process-util.c"
nm_copy_sd_shared "src/basic/process-util.h"
nm_copy_sd_shared "src/basic/random-util.c"
nm_copy_sd_shared "src/basic/random-util.h"
nm_copy_sd_shared "src/basic/set.h"
nm_copy_sd_shared "src/basic/signal-util.h"
nm_copy_sd_shared "src/basic/siphash24.h"
nm_copy_sd_shared "src/basic/socket-util.c"
nm_copy_sd_shared "src/basic/socket-util.h"
nm_copy_sd_shared "src/basic/sort-util.h"
nm_copy_sd_shared "src/basic/sparse-endian.h"
nm_copy_sd_shared "src/basic/stat-util.c"
nm_copy_sd_shared "src/basic/stat-util.h"
nm_copy_sd_shared "src/basic/stdio-util.h"
nm_copy_sd_shared "src/basic/string-table.c"
nm_copy_sd_shared "src/basic/string-table.h"
nm_copy_sd_shared "src/basic/string-util.c"
nm_copy_sd_shared "src/basic/string-util.h"
nm_copy_sd_shared "src/basic/strv.c"
nm_copy_sd_shared "src/basic/strv.h"
nm_copy_sd_shared "src/basic/strxcpyx.c"
nm_copy_sd_shared "src/basic/strxcpyx.h"
nm_copy_sd_shared "src/basic/time-util.c"
nm_copy_sd_shared "src/basic/time-util.h"
nm_copy_sd_shared "src/basic/tmpfile-util.c"
nm_copy_sd_shared "src/basic/tmpfile-util.h"
nm_copy_sd_shared "src/basic/umask-util.h"
nm_copy_sd_shared "src/basic/utf8.c"
nm_copy_sd_shared "src/basic/utf8.h"
nm_copy_sd_shared "src/basic/util.c"
nm_copy_sd_shared "src/basic/util.h"
nm_copy_sd_shared "src/shared/dns-domain.c"
nm_copy_sd_shared "src/shared/dns-domain.h"
22 files changed, 261 insertions, 61 deletions
diff --git a/shared/systemd/src/basic/alloc-util.c b/shared/systemd/src/basic/alloc-util.c index a16db6824f..5951e8c3d5 100644 --- a/shared/systemd/src/basic/alloc-util.c +++ b/shared/systemd/src/basic/alloc-util.c @@ -78,7 +78,7 @@ void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) { * take possession of the extra space. This should be cheap, since libc doesn't have to move * the memory for this. */ - qq = realloc(q, bn * size); + qq = reallocarray(q, bn, size); if (_likely_(qq)) { *p = qq; *allocated = bn; diff --git a/shared/systemd/src/basic/env-file.c b/shared/systemd/src/basic/env-file.c index 83767b0a24..26470796eb 100644 --- a/shared/systemd/src/basic/env-file.c +++ b/shared/systemd/src/basic/env-file.c @@ -485,6 +485,8 @@ static int merge_env_file_push( free_and_replace(value, expanded_value); + log_debug("%s:%u: setting %s=%s", filename, line, key, value); + return load_env_file_push(filename, line, key, value, env, n_pushed); } diff --git a/shared/systemd/src/basic/errno-util.h b/shared/systemd/src/basic/errno-util.h index 34859d6d8a..6053cde62d 100644 --- a/shared/systemd/src/basic/errno-util.h +++ b/shared/systemd/src/basic/errno-util.h @@ -31,7 +31,7 @@ static inline int negative_errno(void) { return -errno; } -static inline char *strerror_safe(int error) { +static inline const char *strerror_safe(int error) { /* 'safe' here does NOT mean thread safety. */ return strerror(abs(error)); } diff --git a/shared/systemd/src/basic/extract-word.c b/shared/systemd/src/basic/extract-word.c index b7ae2ed1cd..34cfb36a4a 100644 --- a/shared/systemd/src/basic/extract-word.c +++ b/shared/systemd/src/basic/extract-word.c @@ -28,8 +28,6 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra assert(p); assert(ret); - /* Those two don't make sense together. */ - assert(!FLAGS_SET(flags, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE)); /* Bail early if called after last value or with no input */ if (!*p) diff --git a/shared/systemd/src/basic/fileio.c b/shared/systemd/src/basic/fileio.c index 623e43e4ca..a9c0fd20e1 100644 --- a/shared/systemd/src/basic/fileio.c +++ b/shared/systemd/src/basic/fileio.c @@ -930,10 +930,10 @@ int warn_file_is_world_accessible(const char *filename, struct stat *st, const c if (unit) log_syntax(unit, LOG_WARNING, filename, line, 0, - "%s has %04o mode that is too permissive, please adjust the access mode.", + "%s has %04o mode that is too permissive, please adjust the ownership and access mode.", filename, st->st_mode & 07777); else - log_warning("%s has %04o mode that is too permissive, please adjust the access mode.", + log_warning("%s has %04o mode that is too permissive, please adjust the ownership and access mode.", filename, st->st_mode & 07777); return 0; } diff --git a/shared/systemd/src/basic/fs-util.c b/shared/systemd/src/basic/fs-util.c index 3ed8e2c8a9..b2ac648838 100644 --- a/shared/systemd/src/basic/fs-util.c +++ b/shared/systemd/src/basic/fs-util.c @@ -732,7 +732,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, * process. On each iteration, we move one component from "todo" to "done", processing it's special meaning * each time. The "todo" path always starts with at least one slash, the "done" path always ends in no * slash. We always keep an O_PATH fd to the component we are currently processing, thus keeping lookup races - * at a minimum. + * to a minimum. * * Suggested usage: whenever you want to canonicalize a path, use this function. Pass the absolute path you got * as-is: fully qualified and relative to your host's root. Optionally, specify the root parameter to tell this @@ -742,9 +742,9 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, * There are three ways to invoke this function: * * 1. Without CHASE_STEP or CHASE_OPEN: in this case the path is resolved and the normalized path is returned - * in `ret`. The return value is < 0 on error. If CHASE_NONEXISTENT is also set 0 is returned if the file - * doesn't exist, > 0 otherwise. If CHASE_NONEXISTENT is not set >= 0 is returned if the destination was - * found, -ENOENT if it doesn't. + * in `ret`. The return value is < 0 on error. If CHASE_NONEXISTENT is also set, 0 is returned if the file + * doesn't exist, > 0 otherwise. If CHASE_NONEXISTENT is not set, >= 0 is returned if the destination was + * found, -ENOENT if it wasn't. * * 2. With CHASE_OPEN: in this case the destination is opened after chasing it as O_PATH and this file * descriptor is returned as return value. This is useful to open files relative to some root @@ -760,13 +760,13 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, * * 4. With CHASE_SAFE: in this case the path must not contain unsafe transitions, i.e. transitions from * unprivileged to privileged files or directories. In such cases the return value is -ENOLINK. If - * CHASE_WARN is also set a warning describing the unsafe transition is emitted. + * CHASE_WARN is also set, a warning describing the unsafe transition is emitted. * - * 5. With CHASE_NO_AUTOFS: in this case if an autofs mount point is encountered, the path normalization is - * aborted and -EREMOTE is returned. If CHASE_WARN is also set a warning showing the path of the mount point - * is emitted. + * 5. With CHASE_NO_AUTOFS: in this case if an autofs mount point is encountered, path normalization + * is aborted and -EREMOTE is returned. If CHASE_WARN is also set, a warning showing the path of + * the mount point is emitted. * - * */ + */ /* A root directory of "/" or "" is identical to none */ if (empty_or_root(original_root)) @@ -1298,6 +1298,17 @@ int fsync_directory_of_file(int fd) { return 0; } +int fsync_full(int fd) { + int r, q; + + /* Sync both the file and the directory */ + + r = fsync(fd) < 0 ? -errno : 0; + q = fsync_directory_of_file(fd); + + return r < 0 ? r : q; +} + int fsync_path_at(int at_fd, const char *path) { _cleanup_close_ int opened_fd = -1; int fd; diff --git a/shared/systemd/src/basic/fs-util.h b/shared/systemd/src/basic/fs-util.h index c5527cc44f..1f0bdd95b3 100644 --- a/shared/systemd/src/basic/fs-util.h +++ b/shared/systemd/src/basic/fs-util.h @@ -74,14 +74,16 @@ union inotify_event_buffer { int inotify_add_watch_fd(int fd, int what, uint32_t mask); enum { - CHASE_PREFIX_ROOT = 1 << 0, /* If set, the specified path will be prefixed by the specified root before beginning the iteration */ - CHASE_NONEXISTENT = 1 << 1, /* If set, it's OK if the path doesn't actually exist. */ - CHASE_NO_AUTOFS = 1 << 2, /* If set, return -EREMOTE if autofs mount point found */ - CHASE_SAFE = 1 << 3, /* If set, return EPERM if we ever traverse from unprivileged to privileged files or directories */ - CHASE_OPEN = 1 << 4, /* If set, return an O_PATH object to the final component */ - CHASE_TRAIL_SLASH = 1 << 5, /* If set, any trailing slash will be preserved */ - CHASE_STEP = 1 << 6, /* If set, just execute a single step of the normalization */ - CHASE_NOFOLLOW = 1 << 7, /* Only valid with CHASE_OPEN: when the path's right-most component refers to symlink return O_PATH fd of the symlink, rather than following it. */ + CHASE_PREFIX_ROOT = 1 << 0, /* The specified path will be prefixed by the specified root before beginning the iteration */ + CHASE_NONEXISTENT = 1 << 1, /* It's OK if the path doesn't actually exist. */ + CHASE_NO_AUTOFS = 1 << 2, /* Return -EREMOTE if autofs mount point found */ + CHASE_SAFE = 1 << 3, /* Return EPERM if we ever traverse from unprivileged to privileged files or directories */ + CHASE_OPEN = 1 << 4, /* Return an O_PATH object to the final component */ + CHASE_TRAIL_SLASH = 1 << 5, /* Any trailing slash will be preserved */ + CHASE_STEP = 1 << 6, /* Just execute a single step of the normalization */ + CHASE_NOFOLLOW = 1 << 7, /* Do not follow the path's right-most compontent. With CHASE_OPEN, when + * the path's right-most component refers to symlink, return O_PATH fd of + * the symlink. */ CHASE_WARN = 1 << 8, /* Emit an appropriate warning when an error is encountered */ }; @@ -114,6 +116,7 @@ void unlink_tempfilep(char (*p)[]); int unlinkat_deallocate(int fd, const char *name, int flags); int fsync_directory_of_file(int fd); +int fsync_full(int fd); int fsync_path_at(int at_fd, const char *path); int syncfs_path(int atfd, const char *path); diff --git a/shared/systemd/src/basic/path-util.h b/shared/systemd/src/basic/path-util.h index 1f46cd65c9..71fb7041a3 100644 --- a/shared/systemd/src/basic/path-util.h +++ b/shared/systemd/src/basic/path-util.h @@ -11,30 +11,38 @@ #include "time-util.h" #define PATH_SPLIT_SBIN_BIN(x) x "sbin:" x "bin" +#define PATH_SPLIT_BIN_SBIN(x) x "bin:" x "sbin" #define PATH_SPLIT_SBIN_BIN_NULSTR(x) x "sbin\0" x "bin\0" #define PATH_NORMAL_SBIN_BIN(x) x "bin" +#define PATH_NORMAL_BIN_SBIN(x) x "bin" #define PATH_NORMAL_SBIN_BIN_NULSTR(x) x "bin\0" #if HAVE_SPLIT_BIN # define PATH_SBIN_BIN(x) PATH_SPLIT_SBIN_BIN(x) +# define PATH_BIN_SBIN(x) PATH_SPLIT_BIN_SBIN(x) # define PATH_SBIN_BIN_NULSTR(x) PATH_SPLIT_SBIN_BIN_NULSTR(x) #else # define PATH_SBIN_BIN(x) PATH_NORMAL_SBIN_BIN(x) +# define PATH_BIN_SBIN(x) PATH_NORMAL_BIN_SBIN(x) # define PATH_SBIN_BIN_NULSTR(x) PATH_NORMAL_SBIN_BIN_NULSTR(x) #endif #define DEFAULT_PATH_NORMAL PATH_SBIN_BIN("/usr/local/") ":" PATH_SBIN_BIN("/usr/") +#define DEFAULT_USER_PATH_NORMAL PATH_BIN_SBIN("/usr/local/") ":" PATH_BIN_SBIN("/usr/") #define DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/usr/local/") PATH_SBIN_BIN_NULSTR("/usr/") #define DEFAULT_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_SBIN_BIN("/") +#define DEFAULT_USER_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_BIN_SBIN("/") #define DEFAULT_PATH_SPLIT_USR_NULSTR DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/") #define DEFAULT_PATH_COMPAT PATH_SPLIT_SBIN_BIN("/usr/local/") ":" PATH_SPLIT_SBIN_BIN("/usr/") ":" PATH_SPLIT_SBIN_BIN("/") #if HAVE_SPLIT_USR # define DEFAULT_PATH DEFAULT_PATH_SPLIT_USR +# define DEFAULT_USER_PATH DEFAULT_USER_PATH_SPLIT_USR # define DEFAULT_PATH_NULSTR DEFAULT_PATH_SPLIT_USR_NULSTR #else # define DEFAULT_PATH DEFAULT_PATH_NORMAL +# define DEFAULT_USER_PATH DEFAULT_USER_PATH_NORMAL # define DEFAULT_PATH_NULSTR DEFAULT_PATH_NORMAL_NULSTR #endif diff --git a/shared/systemd/src/basic/random-util.c b/shared/systemd/src/basic/random-util.c index 3af6f271f0..b6a9ad4060 100644 --- a/shared/systemd/src/basic/random-util.c +++ b/shared/systemd/src/basic/random-util.c @@ -25,8 +25,10 @@ #include "alloc-util.h" #include "fd-util.h" +#include "fileio.h" #include "io-util.h" #include "missing.h" +#include "parse-util.h" #include "random-util.h" #include "siphash24.h" #include "time-util.h" @@ -389,3 +391,26 @@ void random_bytes(void *p, size_t n) { /* If for some reason some user made /dev/urandom unavailable to us, or the kernel has no entropy, use a PRNG instead. */ pseudo_random_bytes(p, n); } + +size_t random_pool_size(void) { + _cleanup_free_ char *s = NULL; + int r; + + /* Read pool size, if possible */ + r = read_one_line_file("/proc/sys/kernel/random/poolsize", &s); + if (r < 0) + log_debug_errno(r, "Failed to read pool size from kernel: %m"); + else { + unsigned sz; + + r = safe_atou(s, &sz); + if (r < 0) + log_debug_errno(r, "Failed to parse pool size: %s", s); + else + /* poolsize is in bits on 2.6, but we want bytes */ + return CLAMP(sz / 8, RANDOM_POOL_SIZE_MIN, RANDOM_POOL_SIZE_MAX); + } + + /* Use the minimum as default, if we can't retrieve the correct value */ + return RANDOM_POOL_SIZE_MIN; +} diff --git a/shared/systemd/src/basic/random-util.h b/shared/systemd/src/basic/random-util.h index 148b6c7813..facc11b976 100644 --- a/shared/systemd/src/basic/random-util.h +++ b/shared/systemd/src/basic/random-util.h @@ -31,3 +31,9 @@ static inline uint32_t random_u32(void) { } int rdrand(unsigned long *ret); + +/* Some limits on the pool sizes when we deal with the kernel random pool */ +#define RANDOM_POOL_SIZE_MIN 512U +#define RANDOM_POOL_SIZE_MAX (10U*1024U*1024U) + +size_t random_pool_size(void); diff --git a/shared/systemd/src/basic/strv.h b/shared/systemd/src/basic/strv.h index e80964acd1..fbfa96a566 100644 --- a/shared/systemd/src/basic/strv.h +++ b/shared/systemd/src/basic/strv.h @@ -157,6 +157,18 @@ void strv_print(char **l); _found; \ }) +#define ENDSWITH_SET(p, ...) \ + ({ \ + const char *_p = (p); \ + char *_found = NULL, **_i; \ + STRV_FOREACH(_i, STRV_MAKE(__VA_ARGS__)) { \ + _found = endswith(_p, *_i); \ + if (_found) \ + break; \ + } \ + _found; \ + }) + #define FOREACH_STRING(x, y, ...) \ for (char **_l = STRV_MAKE(({ x = y; }), ##__VA_ARGS__); \ x; \ diff --git a/shared/systemd/src/basic/time-util.c b/shared/systemd/src/basic/time-util.c index 434159f41c..3018e81acb 100644 --- a/shared/systemd/src/basic/time-util.c +++ b/shared/systemd/src/basic/time-util.c @@ -1191,7 +1191,10 @@ bool ntp_synced(void) { if (adjtimex(&txc) < 0) return false; - if (txc.status & STA_UNSYNC) + /* Consider the system clock synchronized if the reported maximum error is smaller than the maximum + * value (16 seconds). Ignore the STA_UNSYNC flag as it may have been set to prevent the kernel from + * touching the RTC. */ + if (txc.maxerror >= 16000000) return false; return true; @@ -1414,8 +1417,8 @@ struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc) { return utc ? gmtime_r(t, tm) : localtime_r(t, tm); } -unsigned long usec_to_jiffies(usec_t u) { - static thread_local unsigned long hz = 0; +static uint32_t sysconf_clock_ticks_cached(void) { + static thread_local uint32_t hz = 0; long r; if (hz == 0) { @@ -1425,7 +1428,17 @@ unsigned long usec_to_jiffies(usec_t u) { hz = r; } - return DIV_ROUND_UP(u , USEC_PER_SEC / hz); + return hz; +} + +uint32_t usec_to_jiffies(usec_t u) { + uint32_t hz = sysconf_clock_ticks_cached(); + return DIV_ROUND_UP(u, USEC_PER_SEC / hz); +} + +usec_t jiffies_to_usec(uint32_t j) { + uint32_t hz = sysconf_clock_ticks_cached(); + return DIV_ROUND_UP(j * USEC_PER_SEC, hz); } usec_t usec_shift_clock(usec_t x, clockid_t from, clockid_t to) { diff --git a/shared/systemd/src/basic/time-util.h b/shared/systemd/src/basic/time-util.h index e3a529d970..4c371257e3 100644 --- a/shared/systemd/src/basic/time-util.h +++ b/shared/systemd/src/basic/time-util.h @@ -136,7 +136,8 @@ int get_timezone(char **timezone); time_t mktime_or_timegm(struct tm *tm, bool utc); struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc); -unsigned long usec_to_jiffies(usec_t usec); +uint32_t usec_to_jiffies(usec_t usec); +usec_t jiffies_to_usec(uint32_t jiffies); bool in_utc_timezone(void); diff --git a/src/systemd/src/libsystemd-network/dhcp-lease-internal.h b/src/systemd/src/libsystemd-network/dhcp-lease-internal.h index 122042ab58..a2d0f8bd5e 100644 --- a/src/systemd/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/systemd/src/libsystemd-network/dhcp-lease-internal.h @@ -58,6 +58,9 @@ struct sd_dhcp_lease { struct in_addr *ntp; size_t ntp_size; + struct in_addr *sip; + size_t sip_size; + struct sd_dhcp_route *static_route; size_t static_route_size, static_route_allocated; diff --git a/src/systemd/src/libsystemd-network/dhcp-option.c b/src/systemd/src/libsystemd-network/dhcp-option.c index 0abb8fdef0..d2f1f5d806 100644 --- a/src/systemd/src/libsystemd-network/dhcp-option.c +++ b/src/systemd/src/libsystemd-network/dhcp-option.c @@ -27,7 +27,7 @@ static int option_append(uint8_t options[], size_t size, size_t *offset, case SD_DHCP_OPTION_PAD: case SD_DHCP_OPTION_END: - if (size < *offset + 1) + if (*offset + 1 > size) return -ENOBUFS; options[*offset] = code; @@ -35,42 +35,57 @@ static int option_append(uint8_t options[], size_t size, size_t *offset, break; case SD_DHCP_OPTION_USER_CLASS: { - size_t len = 0; + size_t total = 0; char **s; - STRV_FOREACH(s, (char **) optval) - len += strlen(*s) + 1; + STRV_FOREACH(s, (char **) optval) { + size_t len = strlen(*s); + + if (len > 255) + return -ENAMETOOLONG; + + total += 1 + len; + } - if (size < *offset + len + 2) + if (*offset + 2 + total > size) return -ENOBUFS; options[*offset] = code; - options[*offset + 1] = len; + options[*offset + 1] = total; *offset += 2; STRV_FOREACH(s, (char **) optval) { - len = strlen(*s); - - if (len > 255) - return -ENAMETOOLONG; + size_t len = strlen(*s); options[*offset] = len; - memcpy_safe(&options[*offset + 1], *s, len); - *offset += len + 1; + memcpy(&options[*offset + 1], *s, len); + *offset += 1 + len; } break; } + case SD_DHCP_OPTION_SIP_SERVER: + if (*offset + 3 + optlen > size) + return -ENOBUFS; + + options[*offset] = code; + options[*offset + 1] = optlen + 1; + options[*offset + 2] = 1; + + memcpy_safe(&options[*offset + 3], optval, optlen); + *offset += 3 + optlen; + + break; default: - if (size < *offset + optlen + 2) + if (*offset + 2 + optlen > size) return -ENOBUFS; options[*offset] = code; options[*offset + 1] = optlen; memcpy_safe(&options[*offset + 2], optval, optlen); - *offset += optlen + 2; + *offset += 2 + optlen; break; } @@ -81,22 +96,25 @@ static int option_append(uint8_t options[], size_t size, size_t *offset, int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, uint8_t overload, uint8_t code, size_t optlen, const void *optval) { - size_t file_offset = 0, sname_offset =0; - bool file, sname; + const bool use_file = overload & DHCP_OVERLOAD_FILE; + const bool use_sname = overload & DHCP_OVERLOAD_SNAME; int r; assert(message); assert(offset); - file = overload & DHCP_OVERLOAD_FILE; - sname = overload & DHCP_OVERLOAD_SNAME; + /* If *offset is in range [0, size), we are writing to ->options, + * if *offset is in range [size, size + sizeof(message->file)) and use_file, we are writing to ->file, + * if *offset is in range [size + use_file*sizeof(message->file), size + use_file*sizeof(message->file) + sizeof(message->sname)) + * and use_sname, we are writing to ->sname. + */ if (*offset < size) { /* still space in the options array */ r = option_append(message->options, size, offset, code, optlen, optval); if (r >= 0) return 0; - else if (r == -ENOBUFS && (file || sname)) { + else if (r == -ENOBUFS && (use_file || use_sname)) { /* did not fit, but we have more buffers to try close the options array and move the offset to its end */ r = option_append(message->options, size, offset, SD_DHCP_OPTION_END, 0, NULL); @@ -108,8 +126,8 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, return r; } - if (overload & DHCP_OVERLOAD_FILE) { - file_offset = *offset - size; + if (use_file) { + size_t file_offset = *offset - size; if (file_offset < sizeof(message->file)) { /* still space in the 'file' array */ @@ -117,7 +135,7 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, if (r >= 0) { *offset = size + file_offset; return 0; - } else if (r == -ENOBUFS && sname) { + } else if (r == -ENOBUFS && use_sname) { /* did not fit, but we have more buffers to try close the file array and move the offset to its end */ r = option_append(message->options, size, offset, SD_DHCP_OPTION_END, 0, NULL); @@ -130,19 +148,18 @@ int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, } } - if (overload & DHCP_OVERLOAD_SNAME) { - sname_offset = *offset - size - (file ? sizeof(message->file) : 0); + if (use_sname) { + size_t sname_offset = *offset - size - use_file*sizeof(message->file); if (sname_offset < sizeof(message->sname)) { /* still space in the 'sname' array */ r = option_append(message->sname, sizeof(message->sname), &sname_offset, code, optlen, optval); if (r >= 0) { - *offset = size + (file ? sizeof(message->file) : 0) + sname_offset; + *offset = size + use_file*sizeof(message->file) + sname_offset; return 0; - } else { + } else /* no space, or other error, give up */ return r; - } } } diff --git a/src/systemd/src/libsystemd-network/network-internal.c b/src/systemd/src/libsystemd-network/network-internal.c index f18ec88300..1f2e5c7e65 100644 --- a/src/systemd/src/libsystemd-network/network-internal.c +++ b/src/systemd/src/libsystemd-network/network-internal.c @@ -254,7 +254,7 @@ int config_parse_match_strv( for (;;) { _cleanup_free_ char *word = NULL, *k = NULL; - r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE); + r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE); if (r == 0) return 0; if (r == -ENOMEM) diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c index 85238c21d1..cadacc24d4 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c @@ -995,15 +995,14 @@ static int client_send_request(sd_dhcp_client *client) { if (r < 0) return r; - if (client->state == DHCP_STATE_RENEWING) { + if (client->state == DHCP_STATE_RENEWING) r = dhcp_network_send_udp_socket(client->fd, client->lease->server_address, DHCP_PORT_SERVER, &request->dhcp, sizeof(DHCPMessage) + optoffset); - } else { + else r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset); - } if (r < 0) return r; @@ -1211,7 +1210,7 @@ static int client_initialize_time_events(sd_dhcp_client *client) { assert(client); assert(client->event); - if (client->start_delay) { + if (client->start_delay > 0) { assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0); usec += client->start_delay; } @@ -1882,6 +1881,17 @@ static int client_receive_message_raw( return client_handle_message(client, &packet->dhcp, len); } +int sd_dhcp_client_send_renew(sd_dhcp_client *client) { + assert_return(client, -EINVAL); + assert_return(client->fd >= 0, -EINVAL); + + client->start_delay = 0; + client->attempt = 1; + client->state = DHCP_STATE_RENEWING; + + return client_initialize_time_events(client); +} + int sd_dhcp_client_start(sd_dhcp_client *client) { int r; diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c index 17b2bb7aa4..800caec841 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c @@ -120,6 +120,17 @@ int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) { return (int) lease->ntp_size; } +int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + + if (lease->sip_size <= 0) + return -ENODATA; + + *addr = lease->sip; + return (int) lease->sip_size; +} + int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) { assert_return(lease, -EINVAL); assert_return(domainname, -EINVAL); @@ -269,6 +280,7 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) { free(lease->domainname); free(lease->dns); free(lease->ntp); + free(lease->sip); free(lease->static_route); free(lease->client_id); free(lease->vendor_specific); @@ -402,6 +414,36 @@ static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_add return 0; } +static int lease_parse_sip_server(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) { + assert(option); + assert(ret); + assert(n_ret); + + if (len <= 0) { + *ret = mfree(*ret); + *n_ret = 0; + } else { + size_t n_addresses; + struct in_addr *addresses; + int l = len - 1; + + if (l % 4 != 0) + return -EINVAL; + + n_addresses = l / 4; + + addresses = newdup(struct in_addr, option + 1, n_addresses); + if (!addresses) + return -ENOMEM; + + free(*ret); + *ret = addresses; + *n_ret = n_addresses; + } + + return 0; +} + static int lease_parse_routes( const uint8_t *option, size_t len, struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) { @@ -555,6 +597,12 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void log_debug_errno(r, "Failed to parse NTP server, ignoring: %m"); break; + case SD_DHCP_OPTION_SIP_SERVER: + r = lease_parse_sip_server(option, len, &lease->sip, &lease->sip_size); + if (r < 0) + log_debug_errno(r, "Failed to parse SIP server, ignoring: %m"); + break; + case SD_DHCP_OPTION_STATIC_ROUTE: r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated); if (r < 0) @@ -893,6 +941,13 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { fputc('\n', f); } + r = sd_dhcp_lease_get_sip(lease, &addresses); + if (r > 0) { + fputs("SIP=", f); + serialize_in_addrs(f, addresses, r, false, NULL); + fputc('\n', f); + } + r = sd_dhcp_lease_get_domainname(lease, &string); if (r >= 0) fprintf(f, "DOMAINNAME=%s\n", string); @@ -983,6 +1038,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { *broadcast = NULL, *dns = NULL, *ntp = NULL, + *sip = NULL, *mtu = NULL, *routes = NULL, *domains = NULL, @@ -1011,6 +1067,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { "BROADCAST", &broadcast, "DNS", &dns, "NTP", &ntp, + "SIP", &sip, "MTU", &mtu, "DOMAINNAME", &lease->domainname, "HOSTNAME", &lease->hostname, @@ -1115,6 +1172,14 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { lease->ntp_size = r; } + if (sip) { + r = deserialize_in_addrs(&lease->sip, sip); + if (r < 0) + log_debug_errno(r, "Failed to deserialize SIP servers %s, ignoring: %m", sip); + else + lease->ntp_size = r; + } + if (mtu) { r = safe_atou16(mtu, &lease->mtu); if (r < 0) diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c index d7a5349c70..9773a067d5 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c @@ -29,6 +29,9 @@ #define MAX_MAC_ADDR_LEN INFINIBAND_ALEN +#define IRT_DEFAULT (1 * USEC_PER_DAY) +#define IRT_MINIMUM (600 * USEC_PER_SEC) + /* what to request from the server, addresses (IA_NA) and/or prefixes (IA_PD) */ enum { DHCP6_REQUEST_IA_NA = 1, @@ -71,6 +74,8 @@ struct sd_dhcp6_client { void *userdata; struct duid duid; size_t duid_len; + usec_t information_request_time_usec; + usec_t information_refresh_time_usec; }; static const uint16_t default_req_opts[] = { @@ -820,6 +825,7 @@ static int client_parse_message( uint32_t lt_t1 = ~0, lt_t2 = ~0; bool clientid = false; size_t pos = 0; + usec_t irt = IRT_DEFAULT; int r; assert(client); @@ -994,6 +1000,13 @@ static int client_parse_message( return r; break; + + case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME: + if (optlen != 4) + return -EINVAL; + + irt = unaligned_read_be32((be32_t *) optval) * USEC_PER_SEC; + break; } pos += offsetof(DHCP6Option, data) + optlen; @@ -1025,6 +1038,8 @@ static int client_parse_message( } } + client->information_refresh_time_usec = MAX(irt, IRT_MINIMUM); + return 0; } @@ -1425,8 +1440,15 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) { client->fd = r; } - if (client->information_request) + if (client->information_request) { + usec_t t = now(CLOCK_MONOTONIC); + + if (t < usec_add(client->information_request_time_usec, client->information_refresh_time_usec)) + return 0; + + client->information_request_time_usec = t; state = DHCP6_STATE_INFORMATION_REQUEST; + } log_dhcp6_client(client, "Started in %s mode", client->information_request? "Information request": diff --git a/src/systemd/src/systemd/sd-dhcp-client.h b/src/systemd/src/systemd/sd-dhcp-client.h index ab62368e9c..d2d74b2b4c 100644 --- a/src/systemd/src/systemd/sd-dhcp-client.h +++ b/src/systemd/src/systemd/sd-dhcp-client.h @@ -87,6 +87,7 @@ enum { SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100, SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101, SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119, + SD_DHCP_OPTION_SIP_SERVER = 120, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121, SD_DHCP_OPTION_PRIVATE_BASE = 224, /* Windows 10 option to send when Anonymize=true */ @@ -177,6 +178,7 @@ int sd_dhcp_client_get_lease( int sd_dhcp_client_stop(sd_dhcp_client *client); int sd_dhcp_client_start(sd_dhcp_client *client); int sd_dhcp_client_send_release(sd_dhcp_client *client); +int sd_dhcp_client_send_renew(sd_dhcp_client *client); sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client); sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client); diff --git a/src/systemd/src/systemd/sd-dhcp-lease.h b/src/systemd/src/systemd/sd-dhcp-lease.h index d299c79121..b80d607fea 100644 --- a/src/systemd/src/systemd/sd-dhcp-lease.h +++ b/src/systemd/src/systemd/sd-dhcp-lease.h @@ -44,6 +44,7 @@ int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr); int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr); int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr); +int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu); int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname); int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains); diff --git a/src/systemd/src/systemd/sd-dhcp6-client.h b/src/systemd/src/systemd/sd-dhcp6-client.h index 43d38f5c7d..3aac3f14fe 100644 --- a/src/systemd/src/systemd/sd-dhcp6-client.h +++ b/src/systemd/src/systemd/sd-dhcp6-client.h @@ -66,6 +66,7 @@ enum { SD_DHCP6_OPTION_IA_PD_PREFIX = 26, /* RFC 3633, prefix delegation */ SD_DHCP6_OPTION_SNTP_SERVERS = 31, /* RFC 4075, deprecated */ + SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME = 32, /* RFC 8415, sec. 21.23 */ /* option code 35 is unassigned */ |