Merge pull request #8576 from keszybz/oss-fuzz
oss-fuzz adjustments and other cleanups
This commit is contained in:
commit
1700f4f42c
11
README
11
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
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"); \
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -91,6 +91,19 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
|
|||
int (*compar) (const void *, const void *, void *),
|
||||
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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue