diff options
Diffstat (limited to '')
-rw-r--r-- | src/libsystemd-network/dhcp-option.c | 55 | ||||
-rw-r--r-- | src/libsystemd-network/dhcp-option.h | 1 | ||||
-rw-r--r-- | src/libsystemd-network/sd-dhcp-lease.c | 10 | ||||
-rw-r--r-- | src/libsystemd-network/sd-dhcp-server.c | 14 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-error.c | 6 | ||||
-rw-r--r-- | src/libsystemd/sd-device/device-private.h | 5 | ||||
-rw-r--r-- | src/libsystemd/sd-device/sd-device.c | 4 | ||||
-rw-r--r-- | src/libsystemd/sd-event/sd-event.c | 19 | ||||
-rw-r--r-- | src/libsystemd/sd-event/test-event.c | 18 | ||||
-rw-r--r-- | src/libsystemd/sd-id128/id128-util.c | 4 | ||||
-rw-r--r-- | src/libsystemd/sd-journal/journal-file.c | 11 | ||||
-rw-r--r-- | src/libsystemd/sd-journal/journal-verify.c | 2 | ||||
-rw-r--r-- | src/libsystemd/sd-journal/sd-journal.c | 2 |
13 files changed, 106 insertions, 45 deletions
diff --git a/src/libsystemd-network/dhcp-option.c b/src/libsystemd-network/dhcp-option.c index 5e216c5..5679091 100644 --- a/src/libsystemd-network/dhcp-option.c +++ b/src/libsystemd-network/dhcp-option.c @@ -10,6 +10,8 @@ #include "alloc-util.h" #include "dhcp-option.h" #include "dhcp-server-internal.h" +#include "dns-domain.h" +#include "hostname-util.h" #include "memory-util.h" #include "ordered-set.h" #include "strv.h" @@ -396,27 +398,56 @@ int dhcp_option_parse(DHCPMessage *message, size_t len, dhcp_option_callback_t c } int dhcp_option_parse_string(const uint8_t *option, size_t len, char **ret) { + _cleanup_free_ char *string = NULL; int r; assert(option); assert(ret); - if (len <= 0) - *ret = mfree(*ret); - else { - char *string; + if (len <= 0) { + *ret = NULL; + return 0; + } - /* - * One trailing NUL byte is OK, we don't mind. See: - * https://github.com/systemd/systemd/issues/1337 - */ - r = make_cstring((const char *) option, len, MAKE_CSTRING_ALLOW_TRAILING_NUL, &string); - if (r < 0) - return r; + /* One trailing NUL byte is OK, we don't mind. See: + * https://github.com/systemd/systemd/issues/1337 */ + r = make_cstring((const char *) option, len, MAKE_CSTRING_ALLOW_TRAILING_NUL, &string); + if (r < 0) + return r; + + if (!string_is_safe(string) || !utf8_is_valid(string)) + return -EINVAL; + + *ret = TAKE_PTR(string); + return 0; +} + +int dhcp_option_parse_hostname(const uint8_t *option, size_t len, char **ret) { + _cleanup_free_ char *hostname = NULL; + int r; - free_and_replace(*ret, string); + assert(option); + assert(ret); + + r = dhcp_option_parse_string(option, len, &hostname); + if (r < 0) + return r; + + if (!hostname) { + *ret = NULL; + return 0; } + if (!hostname_is_valid(hostname, 0)) + return -EINVAL; + + r = dns_name_is_valid(hostname); + if (r < 0) + return r; + if (r == 0) + return -EINVAL; + + *ret = TAKE_PTR(hostname); return 0; } diff --git a/src/libsystemd-network/dhcp-option.h b/src/libsystemd-network/dhcp-option.h index 425f5b5..aaa8f84 100644 --- a/src/libsystemd-network/dhcp-option.h +++ b/src/libsystemd-network/dhcp-option.h @@ -44,3 +44,4 @@ int dhcp_option_parse( char **ret_error_message); int dhcp_option_parse_string(const uint8_t *option, size_t len, char **ret); +int dhcp_option_parse_hostname(const uint8_t *option, size_t len, char **ret); diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 4e3be98..202d75f 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -833,12 +833,16 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void break; - case SD_DHCP_OPTION_ROOT_PATH: - r = dhcp_option_parse_string(option, len, &lease->root_path); + case SD_DHCP_OPTION_ROOT_PATH: { + _cleanup_free_ char *p = NULL; + + r = dhcp_option_parse_string(option, len, &p); if (r < 0) log_debug_errno(r, "Failed to parse root path, ignoring: %m"); - break; + free_and_replace(lease->root_path, p); + break; + } case SD_DHCP_OPTION_RENEWAL_TIME: r = lease_parse_be32_seconds(option, len, /* max_as_infinity = */ true, &lease->t1); if (r < 0) diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index fcc5b74..b87e4d6 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -808,14 +808,16 @@ static int parse_request(uint8_t code, uint8_t len, const void *option, void *us req->agent_info_option = (uint8_t*)option - 2; break; - case SD_DHCP_OPTION_HOST_NAME: - r = dhcp_option_parse_string(option, len, &req->hostname); - if (r < 0) { - log_debug_errno(r, "Failed to parse hostname, ignoring: %m"); - return 0; - } + case SD_DHCP_OPTION_HOST_NAME: { + _cleanup_free_ char *p = NULL; + r = dhcp_option_parse_hostname(option, len, &p); + if (r < 0) + log_debug_errno(r, "Failed to parse hostname, ignoring: %m"); + else + free_and_replace(req->hostname, p); break; + } case SD_DHCP_OPTION_PARAMETER_REQUEST_LIST: req->parameter_request_list = option; req->parameter_request_list_len = len; diff --git a/src/libsystemd/sd-bus/bus-error.c b/src/libsystemd/sd-bus/bus-error.c index 77b2e1a..f415797 100644 --- a/src/libsystemd/sd-bus/bus-error.c +++ b/src/libsystemd/sd-bus/bus-error.c @@ -277,14 +277,16 @@ _public_ int sd_bus_error_setf(sd_bus_error *e, const char *name, const char *fo va_start(ap, format); r = sd_bus_error_setfv(e, name, format, ap); - assert(!name || r < 0); + if (name) + assert(r < 0); va_end(ap); return r; } r = sd_bus_error_set(e, name, NULL); - assert(!name || r < 0); + if (name) + assert(r < 0); return r; } diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h index b903d1a..e8a6d52 100644 --- a/src/libsystemd/sd-device/device-private.h +++ b/src/libsystemd/sd-device/device-private.h @@ -20,7 +20,10 @@ int device_opendir(sd_device *device, const char *subdir, DIR **ret); int device_get_property_bool(sd_device *device, const char *key); int device_get_property_int(sd_device *device, const char *key, int *ret); int device_get_sysattr_int(sd_device *device, const char *sysattr, int *ret_value); -int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value); +int device_get_sysattr_unsigned_full(sd_device *device, const char *sysattr, unsigned base, unsigned *ret_value); +static inline int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value) { + return device_get_sysattr_unsigned_full(device, sysattr, 0, ret_value); +} int device_get_sysattr_bool(sd_device *device, const char *sysattr); int device_get_device_id(sd_device *device, const char **ret); int device_get_devlink_priority(sd_device *device, int *ret); diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 2fbc619..01e66b4 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -2435,7 +2435,7 @@ int device_get_sysattr_int(sd_device *device, const char *sysattr, int *ret_valu return v > 0; } -int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value) { +int device_get_sysattr_unsigned_full(sd_device *device, const char *sysattr, unsigned base, unsigned *ret_value) { const char *value; int r; @@ -2444,7 +2444,7 @@ int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned return r; unsigned v; - r = safe_atou(value, &v); + r = safe_atou_full(value, base, &v); if (r < 0) return log_device_debug_errno(device, r, "Failed to parse '%s' attribute: %m", sysattr); diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index 288798a..b6899df 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -2415,7 +2415,7 @@ static int inode_data_realize_watch(sd_event *e, struct inode_data *d) { wd = inotify_add_watch_fd(d->inotify_data->fd, d->fd, combined_mask); if (wd < 0) - return -errno; + return wd; if (d->wd < 0) { r = hashmap_put(d->inotify_data->wd, INT_TO_PTR(wd), d); @@ -2637,7 +2637,7 @@ _public_ int sd_event_source_get_io_fd(sd_event_source *s) { } _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) { - int r; + int saved_fd, r; assert_return(s, -EINVAL); assert_return(fd >= 0, -EBADF); @@ -2647,16 +2647,12 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) { if (s->io.fd == fd) return 0; - if (event_source_is_offline(s)) { - s->io.fd = fd; - s->io.registered = false; - } else { - int saved_fd; + saved_fd = s->io.fd; + s->io.fd = fd; - saved_fd = s->io.fd; - assert(s->io.registered); + assert(event_source_is_offline(s) == !s->io.registered); - s->io.fd = fd; + if (s->io.registered) { s->io.registered = false; r = source_io_register(s, s->enabled, s->io.events); @@ -2669,6 +2665,9 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) { (void) epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, saved_fd, NULL); } + if (s->io.owned) + safe_close(saved_fd); + return 0; } diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c index 63d3ee7..cc3d84e 100644 --- a/src/libsystemd/sd-event/test-event.c +++ b/src/libsystemd/sd-event/test-event.c @@ -828,6 +828,24 @@ TEST(fork) { assert_se(r >= 0); } +TEST(sd_event_source_set_io_fd) { + _cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL; + _cleanup_(sd_event_unrefp) sd_event *e = NULL; + _cleanup_close_pair_ int pfd_a[2] = EBADF_PAIR, pfd_b[2] = EBADF_PAIR; + + assert_se(sd_event_default(&e) >= 0); + + assert_se(pipe2(pfd_a, O_CLOEXEC) >= 0); + assert_se(pipe2(pfd_b, O_CLOEXEC) >= 0); + + assert_se(sd_event_add_io(e, &s, pfd_a[0], EPOLLIN, NULL, INT_TO_PTR(-ENOANO)) >= 0); + assert_se(sd_event_source_set_io_fd_own(s, true) >= 0); + TAKE_FD(pfd_a[0]); + + assert_se(sd_event_source_set_io_fd(s, pfd_b[0]) >= 0); + TAKE_FD(pfd_b[0]); +} + static int hup_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) { unsigned *c = userdata; diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c index 94bfd70..b9714ee 100644 --- a/src/libsystemd/sd-id128/id128-util.c +++ b/src/libsystemd/sd-id128/id128-util.c @@ -138,7 +138,7 @@ int id128_read_at(int dir_fd, const char *path, Id128Flag f, sd_id128_t *ret) { assert(dir_fd >= 0 || dir_fd == AT_FDCWD); assert(path); - fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NOCTTY, /* xopen_flags = */ 0, /* mode = */ 0); + fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NOCTTY); if (fd < 0) return fd; @@ -184,7 +184,7 @@ int id128_write_at(int dir_fd, const char *path, Id128Flag f, sd_id128_t id) { assert(dir_fd >= 0 || dir_fd == AT_FDCWD); assert(path); - fd = xopenat(dir_fd, path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_TRUNC, /* xopen_flags = */ 0, 0444); + fd = xopenat_full(dir_fd, path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_TRUNC, /* xopen_flags = */ 0, 0444); if (fd < 0) return fd; diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c index d2493a0..08cbf86 100644 --- a/src/libsystemd/sd-journal/journal-file.c +++ b/src/libsystemd/sd-journal/journal-file.c @@ -639,7 +639,7 @@ static int journal_file_verify_header(JournalFile *f) { return -ENODATA; if (!VALID_REALTIME(le64toh(f->header->tail_entry_realtime))) return -ENODATA; - if (!VALID_MONOTONIC(le64toh(f->header->tail_entry_realtime))) + if (!VALID_MONOTONIC(le64toh(f->header->tail_entry_monotonic))) return -ENODATA; } else { /* Otherwise, the fields must be zero. */ @@ -650,7 +650,7 @@ static int journal_file_verify_header(JournalFile *f) { return -ENODATA; if (f->header->tail_entry_realtime != 0) return -ENODATA; - if (f->header->tail_entry_realtime != 0) + if (f->header->tail_entry_monotonic != 0) return -ENODATA; } } @@ -736,8 +736,9 @@ int journal_file_fstat(JournalFile *f) { return r; /* Refuse appending to files that are already deleted */ - if (f->last_stat.st_nlink <= 0) - return -EIDRM; + r = stat_verify_linked(&f->last_stat); + if (r < 0) + return r; return 0; } @@ -2532,7 +2533,7 @@ int journal_file_append_entry( ts->realtime); if (!VALID_MONOTONIC(ts->monotonic)) return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), - "Invalid monotomic timestamp %" PRIu64 ", refusing entry.", + "Invalid monotonic timestamp %" PRIu64 ", refusing entry.", ts->monotonic); } else { dual_timestamp_now(&_ts); diff --git a/src/libsystemd/sd-journal/journal-verify.c b/src/libsystemd/sd-journal/journal-verify.c index bdaa01d..b5ce55a 100644 --- a/src/libsystemd/sd-journal/journal-verify.c +++ b/src/libsystemd/sd-journal/journal-verify.c @@ -162,7 +162,7 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o int r; if (le64toh(o->data.entry_offset) == 0) - warning(offset, "Unused data (entry_offset==0)"); + debug(offset, "Unused data (entry_offset==0)"); if ((le64toh(o->data.entry_offset) == 0) ^ (le64toh(o->data.n_entries) == 0)) { error(offset, "Bad n_entries: %"PRIu64, le64toh(o->data.n_entries)); diff --git a/src/libsystemd/sd-journal/sd-journal.c b/src/libsystemd/sd-journal/sd-journal.c index 6b9ff0a..ca1ef0c 100644 --- a/src/libsystemd/sd-journal/sd-journal.c +++ b/src/libsystemd/sd-journal/sd-journal.c @@ -1720,7 +1720,7 @@ static void directory_watch(sd_journal *j, Directory *m, int fd, uint32_t mask) m->wd = inotify_add_watch_fd(j->inotify_fd, fd, mask); if (m->wd < 0) { - log_debug_errno(errno, "Failed to watch journal directory '%s', ignoring: %m", m->path); + log_debug_errno(m->wd, "Failed to watch journal directory '%s', ignoring: %m", m->path); return; } |