summaryrefslogtreecommitdiffstats
path: root/src/libsystemd
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/libsystemd-network/dhcp-option.c55
-rw-r--r--src/libsystemd-network/dhcp-option.h1
-rw-r--r--src/libsystemd-network/sd-dhcp-lease.c10
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c14
-rw-r--r--src/libsystemd/sd-bus/bus-error.c6
-rw-r--r--src/libsystemd/sd-device/device-private.h5
-rw-r--r--src/libsystemd/sd-device/sd-device.c4
-rw-r--r--src/libsystemd/sd-event/sd-event.c19
-rw-r--r--src/libsystemd/sd-event/test-event.c18
-rw-r--r--src/libsystemd/sd-id128/id128-util.c4
-rw-r--r--src/libsystemd/sd-journal/journal-file.c11
-rw-r--r--src/libsystemd/sd-journal/journal-verify.c2
-rw-r--r--src/libsystemd/sd-journal/sd-journal.c2
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;
}