summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README11
-rw-r--r--README.md2
-rw-r--r--src/basic/cgroup-util.c2
-rw-r--r--src/basic/macro.h11
-rw-r--r--src/basic/strbuf.c65
-rw-r--r--src/basic/util.h13
-rw-r--r--src/fuzz/fuzz-unit-file.c6
-rw-r--r--src/hwdb/hwdb.c2
-rw-r--r--src/journal/catalog.c5
-rw-r--r--src/test/test-strbuf.c10
-rw-r--r--src/udev/udevadm-hwdb.c4
11 files changed, 84 insertions, 47 deletions
diff --git a/README b/README
index 8807e5cfe4..b735214e2e 100644
--- a/README
+++ b/README
@@ -314,6 +314,17 @@ WARNINGS:
nice output only on exit(), hence on shutdown we don't execve()
systemd-shutdown.
+STABLE BRANCHES AND BACKPORTS
+
+ Stable branches with backported patches are available in the
+ systemd-stable repo at https://github.com/systemd/systemd-stable.
+
+ Stable branches are started for certain releases of systemd and named
+ after them, e.g. v238-stable. Stable branches are managed by
+ distribution maintainers on an as needed basis. See
+ https://www.freedesktop.org/wiki/Software/systemd/Backports/ for some
+ more information and examples.
+
ENGINEERING AND CONSULTING SERVICES:
Kinvolk (https://kinvolk.io) offers professional engineering
and consulting services for systemd. Please contact Chris Kühl
diff --git a/README.md b/README.md
index 4b017faf1b..c122d01731 100644
--- a/README.md
+++ b/README.md
@@ -21,3 +21,5 @@ Please see our [Contribution Guidelines](../master/.github/CONTRIBUTING.md) for
When preparing patches for systemd, please follow our [Coding Style Guidelines](../master/doc/CODING_STYLE).
If you are looking for support, please contact our [mailing list](https://lists.freedesktop.org/mailman/listinfo/systemd-devel) or join our [IRC channel](irc://irc.freenode.org/%23systemd).
+
+Stable branches with backported patches are available in the [stable repo](https://github.com/systemd/systemd-stable).
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index 5934ee6e8a..67e690d6f5 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -1976,7 +1976,7 @@ int cg_slice_to_path(const char *unit, char **ret) {
_cleanup_free_ char *escaped = NULL;
char n[dash - p + sizeof(".slice")];
-#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+#if HAS_FEATURE_MEMORY_SANITIZER
/* msan doesn't instrument stpncpy, so it thinks
* n is later used unitialized:
* https://github.com/google/sanitizers/issues/926
diff --git a/src/basic/macro.h b/src/basic/macro.h
index 8911edfc4b..8e61ff0685 100644
--- a/src/basic/macro.h
+++ b/src/basic/macro.h
@@ -63,6 +63,17 @@
#endif
#endif
+#if !defined(HAS_FEATURE_MEMORY_SANITIZER)
+# if defined(__has_feature)
+# if __has_feature(memory_sanitizer)
+# define HAS_FEATURE_MEMORY_SANITIZER 1
+# endif
+# endif
+# if !defined(HAS_FEATURE_MEMORY_SANITIZER)
+# define HAS_FEATURE_MEMORY_SANITIZER 0
+# endif
+#endif
+
/* Temporarily disable some warnings */
#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT \
_Pragma("GCC diagnostic push"); \
diff --git a/src/basic/strbuf.c b/src/basic/strbuf.c
index bc3e56cf71..8b8281bb3b 100644
--- a/src/basic/strbuf.c
+++ b/src/basic/strbuf.c
@@ -24,6 +24,7 @@
#include "alloc-util.h"
#include "strbuf.h"
+#include "util.h"
/*
* Strbuf stores given strings in a single continuous allocated memory
@@ -46,33 +47,31 @@
struct strbuf *strbuf_new(void) {
struct strbuf *str;
- str = new0(struct strbuf, 1);
+ str = new(struct strbuf, 1);
if (!str)
return NULL;
+ *str = (struct strbuf) {
+ .buf = new0(char, 1),
+ .root = new0(struct strbuf_node, 1),
+ .len = 1,
+ .nodes_count = 1,
+ };
+ if (!str->buf || !str->root) {
+ free(str->buf);
+ free(str->root);
+ return mfree(str);
+ }
- str->buf = new0(char, 1);
- if (!str->buf)
- goto err;
- str->len = 1;
-
- str->root = new0(struct strbuf_node, 1);
- if (!str->root)
- goto err;
- str->nodes_count = 1;
return str;
-err:
- free(str->buf);
- free(str->root);
- return mfree(str);
}
-static void strbuf_node_cleanup(struct strbuf_node *node) {
+static struct strbuf_node* strbuf_node_cleanup(struct strbuf_node *node) {
size_t i;
for (i = 0; i < node->children_count; i++)
strbuf_node_cleanup(node->children[i].child);
free(node->children);
- free(node);
+ return mfree(node);
}
/* clean up trie data, leave only the string buffer */
@@ -80,16 +79,12 @@ void strbuf_complete(struct strbuf *str) {
if (!str)
return;
if (str->root)
- strbuf_node_cleanup(str->root);
- str->root = NULL;
+ str->root = strbuf_node_cleanup(str->root);
}
/* clean up everything */
void strbuf_cleanup(struct strbuf *str) {
- if (!str)
- return;
- if (str->root)
- strbuf_node_cleanup(str->root);
+ strbuf_complete(str);
free(str->buf);
free(str);
}
@@ -138,13 +133,15 @@ ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len) {
return -EINVAL;
/* search string; start from last character to find possibly matching tails */
- if (len == 0)
- return 0;
+
str->in_count++;
+ if (len == 0) {
+ str->dedup_count++;
+ return 0;
+ }
str->in_len += len;
node = str->root;
- c = s[len-1];
for (depth = 0; depth <= len; depth++) {
struct strbuf_child_entry search;
@@ -158,15 +155,11 @@ ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len) {
c = s[len - 1 - depth];
- /* bsearch is not allowed on a NULL sequence */
- if (node->children_count == 0)
- break;
-
/* lookup child node */
search.c = c;
- child = bsearch(&search, node->children, node->children_count,
- sizeof(struct strbuf_child_entry),
- (__compar_fn_t) strbuf_children_cmp);
+ child = bsearch_safe(&search, node->children, node->children_count,
+ sizeof(struct strbuf_child_entry),
+ (__compar_fn_t) strbuf_children_cmp);
if (!child)
break;
node = child->child;
@@ -183,11 +176,13 @@ ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len) {
str->buf[str->len++] = '\0';
/* new node */
- node_child = new0(struct strbuf_node, 1);
+ node_child = new(struct strbuf_node, 1);
if (!node_child)
return -ENOMEM;
- node_child->value_off = off;
- node_child->value_len = len;
+ *node_child = (struct strbuf_node) {
+ .value_off = off,
+ .value_len = len,
+ };
/* extend array, add new entry, sort for bisection */
child = reallocarray(node->children, node->children_count + 1, sizeof(struct strbuf_child_entry));
diff --git a/src/basic/util.h b/src/basic/util.h
index 6f8d8bef34..19e9eae126 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -92,6 +92,19 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
void *arg);
/**
+ * Normal bsearch requires base to be nonnull. Here were require
+ * that only if nmemb > 0.
+ */
+static inline void* bsearch_safe(const void *key, const void *base,
+ size_t nmemb, size_t size, comparison_fn_t compar) {
+ if (nmemb <= 0)
+ return NULL;
+
+ assert(base);
+ return bsearch(key, base, nmemb, size, compar);
+}
+
+/**
* Normal qsort requires base to be nonnull. Here were require
* that only if nmemb > 0.
*/
diff --git a/src/fuzz/fuzz-unit-file.c b/src/fuzz/fuzz-unit-file.c
index 4865653f5b..17da776ae3 100644
--- a/src/fuzz/fuzz-unit-file.c
+++ b/src/fuzz/fuzz-unit-file.c
@@ -43,15 +43,17 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
_cleanup_free_ char *l = NULL;
const char *ll;
- if (read_line(f, LINE_MAX, &l) <= 0)
+ if (read_line(f, LONG_LINE_MAX, &l) <= 0)
break;
ll = l + strspn(l, WHITESPACE);
- if (startswith(ll, "ListenNetlink="))
+ if (HAS_FEATURE_MEMORY_SANITIZER && startswith(ll, "ListenNetlink=")) {
/* ListenNetlink causes a false positive in msan,
* let's skip this for now. */
+ log_notice("Skipping test because ListenNetlink= is present");
return 0;
+ }
}
assert_se(fseek(f, offset, SEEK_SET) == 0);
diff --git a/src/hwdb/hwdb.c b/src/hwdb/hwdb.c
index a60809ca65..958ccd4ca8 100644
--- a/src/hwdb/hwdb.c
+++ b/src/hwdb/hwdb.c
@@ -123,7 +123,7 @@ static struct trie_node *node_lookup(const struct trie_node *node, uint8_t c) {
struct trie_child_entry search;
search.c = c;
- child = bsearch(&search, node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp);
+ child = bsearch_safe(&search, node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp);
if (child)
return child->child;
return NULL;
diff --git a/src/journal/catalog.c b/src/journal/catalog.c
index 6775535b17..03d386cc64 100644
--- a/src/journal/catalog.c
+++ b/src/journal/catalog.c
@@ -592,13 +592,10 @@ static int open_mmap(const char *database, int *_fd, struct stat *_st, void **_p
}
static const char *find_id(void *p, sd_id128_t id) {
- CatalogItem key, *f = NULL;
+ CatalogItem *f = NULL, key = { .id = id };
const CatalogHeader *h = p;
const char *loc;
- zero(key);
- key.id = id;
-
loc = setlocale(LC_MESSAGES, NULL);
if (loc && loc[0] && !streq(loc, "C") && !streq(loc, "POSIX")) {
strncpy(key.language, loc, sizeof(key.language));
diff --git a/src/test/test-strbuf.c b/src/test/test-strbuf.c
index 891d7b1d42..e7395ff96c 100644
--- a/src/test/test-strbuf.c
+++ b/src/test/test-strbuf.c
@@ -33,7 +33,7 @@ static ssize_t add_string(struct strbuf *sb, const char *s) {
static void test_strbuf(void) {
struct strbuf *sb;
_cleanup_strv_free_ char **l;
- ssize_t a, b, c, d, e, f, g;
+ ssize_t a, b, c, d, e, f, g, h;
sb = strbuf_new();
@@ -44,6 +44,7 @@ static void test_strbuf(void) {
e = add_string(sb, "aldo"); /* duplicate */
f = add_string(sb, "do"); /* duplicate */
g = add_string(sb, "waldorf"); /* not a duplicate: matches from tail */
+ h = add_string(sb, "");
/* check the content of the buffer directly */
l = strv_parse_nulstr(sb->buf, sb->len);
@@ -53,10 +54,11 @@ static void test_strbuf(void) {
assert_se(streq(l[2], "foo"));
assert_se(streq(l[3], "bar"));
assert_se(streq(l[4], "waldorf"));
+ assert_se(l[5] == NULL);
assert_se(sb->nodes_count == 5); /* root + 4 non-duplicates */
- assert_se(sb->dedup_count == 3);
- assert_se(sb->in_count == 7);
+ assert_se(sb->dedup_count == 4);
+ assert_se(sb->in_count == 8);
assert_se(sb->in_len == 29); /* length of all strings added */
assert_se(sb->dedup_len == 11); /* length of all strings duplicated */
@@ -70,6 +72,7 @@ static void test_strbuf(void) {
assert_se(e == 2);
assert_se(f == 4);
assert_se(g == 15);
+ assert_se(h == 0);
assert_se(streq(sb->buf + a, "waldo"));
assert_se(streq(sb->buf + b, "foo"));
@@ -78,6 +81,7 @@ static void test_strbuf(void) {
assert_se(streq(sb->buf + e, "aldo"));
assert_se(streq(sb->buf + f, "do"));
assert_se(streq(sb->buf + g, "waldorf"));
+ assert_se(streq(sb->buf + h, ""));
strbuf_complete(sb);
assert_se(sb->root == NULL);
diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c
index 3a5b138b31..f17e0d7946 100644
--- a/src/udev/udevadm-hwdb.c
+++ b/src/udev/udevadm-hwdb.c
@@ -114,7 +114,9 @@ static struct trie_node *node_lookup(const struct trie_node *node, uint8_t c) {
struct trie_child_entry search;
search.c = c;
- child = bsearch(&search, node->children, node->children_count, sizeof(struct trie_child_entry), trie_children_cmp);
+ child = bsearch_safe(&search,
+ node->children, node->children_count, sizeof(struct trie_child_entry),
+ trie_children_cmp);
if (child)
return child->child;
return NULL;