1
0
mirror of https://github.com/systemd/systemd synced 2025-10-03 02:34:45 +02:00

Compare commits

...

12 Commits

Author SHA1 Message Date
Yu Watanabe
f6b54e5280 format-table: fix potentail memleak and invalid-free 2021-03-06 09:23:38 +01:00
Yu Watanabe
5a12d1ca1a fstab-generator: fix typo 2021-03-06 08:52:43 +01:00
Michal Sekletar
996c83903d udev: run link_update() with increased retry count in second invocation
In PR #17431 we have introduced retry loop in link_update() in order to
maximize the chance that we end up with correct target when there are
multiple contenders for given symlink.

Number of iterations in retry loop is either 1 or
LINK_UPDATE_MAX_RETRIES, depending on the value of 'initialized' db
flag. When device appears for the first time we need to set the
flag before calling link_update() via update_devnode() for the second
time to make sure we run the second invocation with higher retry loop
counter.
2021-03-06 15:33:05 +09:00
Yu Watanabe
c2cbe05708
Merge pull request #18896 from poettering/no-localhost-ipv6
if ipv6 is turned off, don't synthesize localhost as ::1 ever
2021-03-06 11:28:38 +09:00
Frantisek Sumsal
3b5fc147d6 test: disable at_exit LSan check for dbus.service
When running integration tests under sanitizers D-Bus fails to
shutdown cleanly, causing unnecessary noise in the logs:

```
dbus-daemon[272]: ==272==LeakSanitizer has encountered a fatal error.
dbus-daemon[272]: ==272==HINT: For debugging, try setting environment variable LSAN_OPTIONS=verbosity=1:log_threads=1
dbus-daemon[272]: ==272==HINT: LeakSanitizer does not work under ptrace (strace, gdb, etc)
```

Since we're not "sanitizing" D-Bus anyway let's disable LSan's at_exit
check for the dbus.service to get rid of this error.
2021-03-06 11:27:04 +09:00
Luca Boccassi
4f67a5d923 dissect: avoid overflow access by NULLSTR_FOREACH
NULLSTR_FOREACH expects two terminating NULs, but the joined string
for extension-release.d only had the canonical one.
Use a placeholder when joining and fix it manually.
2021-03-06 11:26:41 +09:00
Lennart Poettering
07a7441a1c socket-util: refuse "all" and "default" as valid ifnames
Let's avoid collisions with special sysctls.
2021-03-06 11:26:18 +09:00
Lennart Poettering
747b596ff8 resolved: never return ::1 when localhost or local hostname is resolved while IPv6 is off in the kernel
Fixes: #18812
2021-03-05 20:51:43 +01:00
Lennart Poettering
83e03c4fc2 socket-util: add helper for checking if IPv6 is enabled 2021-03-05 20:51:43 +01:00
Lennart Poettering
571ec995fe socket-util: cache result of socket_ipv6_is_supported()
And while we are at it, log about unexpected errors.
2021-03-05 20:51:43 +01:00
Lennart Poettering
b0ffd2760c basic: move shared/sysctl-util.[ch] → basic/
This is self-contained ans allows us later to use the provided APIs from
other code in src/basic/
2021-03-05 20:41:07 +01:00
Lennart Poettering
4b30f2e135 sysctl-util: use read_full_virtual_file() for reading sysctls
Given these files are part of procfs, let's use the correct API calls
for reading them.

This changes one occasion of read_one_line_file() to
read_full_virtual_file(), which superficially is a different thing, but
shouldn't actually be a difference, since sysctls can't be longer than
4K anyway, and the piecemeal logic behind read_one_line_file() cannot
work with the special semantics of procfs anyway.
2021-03-05 20:38:51 +01:00
13 changed files with 81 additions and 22 deletions

View File

@ -235,6 +235,8 @@ basic_sources = files('''
strv.h strv.h
strxcpyx.c strxcpyx.c
strxcpyx.h strxcpyx.h
sysctl-util.c
sysctl-util.h
syslog-util.c syslog-util.c
syslog-util.h syslog-util.h
terminal-util.c terminal-util.c

View File

@ -31,6 +31,7 @@
#include "string-table.h" #include "string-table.h"
#include "string-util.h" #include "string-util.h"
#include "strv.h" #include "strv.h"
#include "sysctl-util.h"
#include "user-util.h" #include "user-util.h"
#include "utf8.h" #include "utf8.h"
@ -277,10 +278,48 @@ const char* socket_address_get_path(const SocketAddress *a) {
} }
bool socket_ipv6_is_supported(void) { bool socket_ipv6_is_supported(void) {
if (access("/proc/net/if_inet6", F_OK) != 0) static int cached = -1;
if (cached < 0) {
if (access("/proc/net/if_inet6", F_OK) < 0) {
if (errno != ENOENT) {
log_debug_errno(errno, "Unexpected error when checking whether /proc/net/if_inet6 exists: %m");
return false;
}
cached = false;
} else
cached = true;
}
return cached;
}
bool socket_ipv6_is_enabled(void) {
_cleanup_free_ char *v;
int r;
/* Much like socket_ipv6_is_supported(), but also checks that the sysctl that disables IPv6 on all
* interfaces isn't turned on */
if (!socket_ipv6_is_supported())
return false; return false;
r = sysctl_read_ip_property(AF_INET6, "all", "disable_ipv6", &v);
if (r < 0) {
log_debug_errno(r, "Unexpected error reading 'net.ipv6.conf.all.disable_ipv6' sysctl: %m");
return true; return true;
}
r = parse_boolean(v);
if (r < 0) {
log_debug_errno(r, "Failed to pare 'net.ipv6.conf.all.disable_ipv6' sysctl: %m");
return true;
}
return !r;
} }
bool socket_address_matches_fd(const SocketAddress *a, int fd) { bool socket_address_matches_fd(const SocketAddress *a, int fd) {
@ -736,6 +775,11 @@ bool ifname_valid_full(const char *p, IfnameValidFlags flags) {
if (dot_or_dot_dot(p)) if (dot_or_dot_dot(p))
return false; return false;
/* Let's refuse "all" and "default" as interface name, to avoid collisions with the special sysctl
* directories /proc/sys/net/{ipv4,ipv6}/conf/{all,default} */
if (STR_IN_SET(p, "all", "default"))
return false;
for (const char *t = p; *t; t++) { for (const char *t = p; *t; t++) {
if ((unsigned char) *t >= 127U) if ((unsigned char) *t >= 127U)
return false; return false;

View File

@ -101,6 +101,7 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) _pure_
const char* socket_address_get_path(const SocketAddress *a); const char* socket_address_get_path(const SocketAddress *a);
bool socket_ipv6_is_supported(void); bool socket_ipv6_is_supported(void);
bool socket_ipv6_is_enabled(void);
int sockaddr_port(const struct sockaddr *_sa, unsigned *port); int sockaddr_port(const struct sockaddr *_sa, unsigned *port);
const union in_addr_union *sockaddr_in_addr(const struct sockaddr *sa); const union in_addr_union *sockaddr_in_addr(const struct sockaddr *sa);

View File

@ -96,14 +96,14 @@ int sysctl_write_ip_property(int af, const char *ifname, const char *property, c
return write_string_file(p, value, WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER); return write_string_file(p, value, WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER);
} }
int sysctl_read(const char *property, char **content) { int sysctl_read(const char *property, char **ret) {
char *p; char *p;
assert(property); assert(property);
assert(content); assert(ret);
p = strjoina("/proc/sys/", property); p = strjoina("/proc/sys/", property);
return read_full_file(p, content, NULL); return read_full_virtual_file(p, ret, NULL);
} }
int sysctl_read_ip_property(int af, const char *ifname, const char *property, char **ret) { int sysctl_read_ip_property(int af, const char *ifname, const char *property, char **ret) {
@ -118,7 +118,7 @@ int sysctl_read_ip_property(int af, const char *ifname, const char *property, ch
ifname ? "/conf/" : "", strempty(ifname), ifname ? "/conf/" : "", strempty(ifname),
property[0] == '/' ? "" : "/", property); property[0] == '/' ? "" : "/", property);
r = read_one_line_file(p, &value); r = read_full_virtual_file(p, &value, NULL);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -423,7 +423,7 @@ static int add_mount(
* mount.nfs (so systemd can manage the job-control aspects of 'bg'), * mount.nfs (so systemd can manage the job-control aspects of 'bg'),
* we need to explicitly preserve that default, and also ensure * we need to explicitly preserve that default, and also ensure
* the systemd mount-timeout doesn't interfere. * the systemd mount-timeout doesn't interfere.
* By placing these options first, they can be over-ridden by * By placing these options first, they can be overridden by
* settings in /etc/fstab. */ * settings in /etc/fstab. */
opts = strjoina("x-systemd.mount-timeout=infinity,retry=10000,nofail,", opts, ",fg"); opts = strjoina("x-systemd.mount-timeout=infinity,retry=10000,nofail,", opts, ",fg");
SET_FLAG(flags, NOFAIL, true); SET_FLAG(flags, NOFAIL, true);
@ -699,9 +699,9 @@ static int add_sysroot_mount(void) {
if (!what) if (!what)
return log_oom(); return log_oom();
fstype = arg_root_fstype ?: "tmpfs"; /* tmpfs, unless overriden */ fstype = arg_root_fstype ?: "tmpfs"; /* tmpfs, unless overridden */
default_rw = true; /* writable, unless overriden */; default_rw = true; /* writable, unless overridden */;
} else { } else {
what = fstab_node_to_udev_node(arg_root_what); what = fstab_node_to_udev_node(arg_root_what);
@ -710,7 +710,7 @@ static int add_sysroot_mount(void) {
fstype = arg_root_fstype; /* if not specified explicitly, don't default to anything here */ fstype = arg_root_fstype; /* if not specified explicitly, don't default to anything here */
default_rw = false; /* read-only, unless overriden */ default_rw = false; /* read-only, unless overridden */
} }
if (!arg_root_options) if (!arg_root_options)

View File

@ -81,7 +81,7 @@ static int synthesize_localhost_rr(Manager *m, const DnsResourceKey *key, int if
return r; return r;
} }
if (IN_SET(key->type, DNS_TYPE_AAAA, DNS_TYPE_ANY)) { if (IN_SET(key->type, DNS_TYPE_AAAA, DNS_TYPE_ANY) && socket_ipv6_is_enabled()) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL; _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_AAAA, dns_resource_key_name(key)); rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_AAAA, dns_resource_key_name(key));
@ -234,7 +234,7 @@ static int synthesize_system_hostname_rr(Manager *m, const DnsResourceKey *key,
.address.in.s_addr = htobe32(0x7F000002), .address.in.s_addr = htobe32(0x7F000002),
}; };
if (IN_SET(af, AF_INET6, AF_UNSPEC)) if (IN_SET(af, AF_INET6, AF_UNSPEC) && socket_ipv6_is_enabled())
buffer[n++] = (struct local_address) { buffer[n++] = (struct local_address) {
.family = AF_INET6, .family = AF_INET6,
.ifindex = dns_synthesize_ifindex(ifindex), .ifindex = dns_synthesize_ifindex(ifindex),

View File

@ -2270,9 +2270,11 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
/* As per the os-release spec, if the image is an extension it will have a file /* As per the os-release spec, if the image is an extension it will have a file
* named after the image name in extension-release.d/ */ * named after the image name in extension-release.d/ */
if (m->image_name) if (m->image_name) {
paths[META_EXTENSION_RELEASE] = strjoina("/usr/lib/extension-release.d/extension-release.", m->image_name); char *ext = strjoina("/usr/lib/extension-release.d/extension-release.", m->image_name, "0");
else ext[strlen(ext) - 1] = '\0'; /* Extra \0 for NULSTR_FOREACH using placeholder from above */
paths[META_EXTENSION_RELEASE] = ext;
} else
log_debug("No image name available, will skip extension-release metadata"); log_debug("No image name available, will skip extension-release metadata");
for (; n_meta_initialized < _META_MAX; n_meta_initialized ++) { for (; n_meta_initialized < _META_MAX; n_meta_initialized ++) {

View File

@ -1317,9 +1317,9 @@ static int table_data_compare(const size_t *a, const size_t *b, Table *t) {
} }
static char* format_strv_width(char **strv, size_t column_width) { static char* format_strv_width(char **strv, size_t column_width) {
_cleanup_free_ char *buf = NULL; /* buf must be freed after f */
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
size_t sz = 0; size_t sz = 0;
_cleanup_free_ char *buf = NULL;
f = open_memstream_unlocked(&buf, &sz); f = open_memstream_unlocked(&buf, &sz);
if (!f) if (!f)
@ -2320,8 +2320,8 @@ int table_print(Table *t, FILE *f) {
} }
int table_format(Table *t, char **ret) { int table_format(Table *t, char **ret) {
_cleanup_free_ char *buf = NULL;
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
char *buf = NULL;
size_t sz = 0; size_t sz = 0;
int r; int r;
@ -2335,7 +2335,7 @@ int table_format(Table *t, char **ret) {
f = safe_fclose(f); f = safe_fclose(f);
*ret = buf; *ret = TAKE_PTR(buf);
return 0; return 0;
} }

View File

@ -244,8 +244,6 @@ shared_sources = files('''
specifier.h specifier.h
switch-root.c switch-root.c
switch-root.h switch-root.h
sysctl-util.c
sysctl-util.h
tmpfile-util-label.c tmpfile-util-label.c
tmpfile-util-label.h tmpfile-util-label.h
tomoyo-util.c tomoyo-util.c

View File

@ -504,6 +504,11 @@ static void test_flush_accept(void) {
assert_se(flush_accept(listen_seqpacket) >= 0); assert_se(flush_accept(listen_seqpacket) >= 0);
} }
static void test_ipv6_enabled(void) {
log_info("IPv6 supported: %s", yes_no(socket_ipv6_is_supported()));
log_info("IPv6 enabled: %s", yes_no(socket_ipv6_is_enabled()));
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
test_setup_logging(LOG_DEBUG); test_setup_logging(LOG_DEBUG);
@ -519,6 +524,7 @@ int main(int argc, char *argv[]) {
test_send_nodata_nofd(); test_send_nodata_nofd();
test_send_emptydata(); test_send_emptydata();
test_flush_accept(); test_flush_accept();
test_ipv6_enabled();
return 0; return 0;
} }

View File

@ -1043,6 +1043,8 @@ int udev_event_execute_rules(UdevEvent *event,
if (r < 0) if (r < 0)
return log_device_debug_errno(dev, r, "Failed to update database under /run/udev/data/: %m"); return log_device_debug_errno(dev, r, "Failed to update database under /run/udev/data/: %m");
device_set_is_initialized(dev);
/* Yes, we run update_devnode() twice, because in the first invocation, that is before update of udev database, /* Yes, we run update_devnode() twice, because in the first invocation, that is before update of udev database,
* it could happen that two contenders are replacing each other's symlink. Hence we run it again to make sure * it could happen that two contenders are replacing each other's symlink. Hence we run it again to make sure
* symlinks point to devices that claim them with the highest priority. */ * symlinks point to devices that claim them with the highest priority. */
@ -1050,8 +1052,6 @@ int udev_event_execute_rules(UdevEvent *event,
if (r < 0) if (r < 0)
return r; return r;
device_set_is_initialized(dev);
return 0; return 0;
} }

View File

@ -725,6 +725,12 @@ printf "[Unit]\nConditionVirtualization=container\n\n[Service]\nTimeoutSec=240s\
mkdir -p /etc/systemd/system/systemd-journal-flush.service.d mkdir -p /etc/systemd/system/systemd-journal-flush.service.d
printf "[Service]\nTimeoutSec=180s\n" >/etc/systemd/system/systemd-journal-flush.service.d/timeout.conf printf "[Service]\nTimeoutSec=180s\n" >/etc/systemd/system/systemd-journal-flush.service.d/timeout.conf
# D-Bus has troubles during system shutdown causing it to fail. Although it's
# harmless, it causes unnecessary noise in the logs, so let's disable LSan's
# at_exit check just for the dbus.service
mkdir -p /etc/systemd/system/dbus.service.d
printf "[Service]\nEnvironment=ASAN_OPTIONS=leak_check_at_exit=false\n" >/etc/systemd/system/dbus.service.d/disable-lsan.conf
# The 'mount' utility doesn't behave well under libasan, causing unexpected # The 'mount' utility doesn't behave well under libasan, causing unexpected
# fails during boot and subsequent test results check: # fails during boot and subsequent test results check:
# bash-5.0# mount -o remount,rw -v / # bash-5.0# mount -o remount,rw -v /