summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-12-07 09:06:48 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-12-09 04:55:47 +0900
commit7d34567444304ea0acec7ed3c44c09bb65cea32c (patch)
tree00c2f45ef012593b645706577d969128fd7fcae3
parent45655e776f3a4deaf68cc21a7716eba5181cbd49 (diff)
downloadsystemd-7d34567444304ea0acec7ed3c44c09bb65cea32c.tar.gz
hexdecoct: fix NULL pointer dereferences in hexmem()
Fixes oss-fuzz#54090 (https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54090). Fixes #25655.
-rw-r--r--src/basic/hexdecoct.c4
-rw-r--r--src/test/test-hexdecoct.c19
-rw-r--r--test/fuzz/fuzz-resource-record/oss-fuzz-54090bin0 -> 110 bytes
3 files changed, 22 insertions, 1 deletions
diff --git a/src/basic/hexdecoct.c b/src/basic/hexdecoct.c
index b9de5bfcda..0ff8eb3256 100644
--- a/src/basic/hexdecoct.c
+++ b/src/basic/hexdecoct.c
@@ -59,11 +59,13 @@ char *hexmem(const void *p, size_t l) {
const uint8_t *x;
char *r, *z;
+ assert(p || l == 0);
+
z = r = new(char, l * 2 + 1);
if (!r)
return NULL;
- for (x = p; x < (const uint8_t*) p + l; x++) {
+ for (x = p; x && x < (const uint8_t*) p + l; x++) {
*(z++) = hexchar(*x >> 4);
*(z++) = hexchar(*x & 15);
}
diff --git a/src/test/test-hexdecoct.c b/src/test/test-hexdecoct.c
index 4657307580..afdc3b5436 100644
--- a/src/test/test-hexdecoct.c
+++ b/src/test/test-hexdecoct.c
@@ -73,6 +73,25 @@ TEST(undecchar) {
assert_se(undecchar('9') == 9);
}
+static void test_hexmem_one(const char *in, const char *expected) {
+ _cleanup_free_ char *result = NULL;
+ _cleanup_free_ void *mem = NULL;
+ size_t len;
+
+ assert_se(result = hexmem(in, strlen_ptr(in)));
+ log_debug("hexmem(\"%s\") → \"%s\" (expected: \"%s\")", strnull(in), result, expected);
+ assert_se(streq(result, expected));
+
+ assert_se(unhexmem(result, SIZE_MAX, &mem, &len) >= 0);
+ assert_se(memcmp_safe(mem, in, len) == 0);
+}
+
+TEST(hexmem) {
+ test_hexmem_one(NULL, "");
+ test_hexmem_one("", "");
+ test_hexmem_one("foo", "666f6f");
+}
+
static void test_unhexmem_one(const char *s, size_t l, int retval) {
_cleanup_free_ char *hex = NULL;
_cleanup_free_ void *mem = NULL;
diff --git a/test/fuzz/fuzz-resource-record/oss-fuzz-54090 b/test/fuzz/fuzz-resource-record/oss-fuzz-54090
new file mode 100644
index 0000000000..994d908d0f
--- /dev/null
+++ b/test/fuzz/fuzz-resource-record/oss-fuzz-54090
Binary files differ