mirror of
https://github.com/systemd/systemd
synced 2024-10-07 00:30:59 +00:00
commit
c3281539da
30
meson.build
30
meson.build
|
@ -781,6 +781,7 @@ conf.set10('ENABLE_DEBUG_HASHMAP', enable_debug_hashmap)
|
|||
conf.set10('ENABLE_DEBUG_MMAP_CACHE', enable_debug_mmap_cache)
|
||||
|
||||
conf.set10('VALGRIND', get_option('valgrind'))
|
||||
conf.set10('LOG_TRACE', get_option('log-trace'))
|
||||
|
||||
#####################################################################
|
||||
|
||||
|
@ -1476,7 +1477,7 @@ foreach tuple : [['myhostname', 'ENABLE_NSS_MYHOSTNAME'],
|
|||
module = tuple[0]
|
||||
|
||||
sym = 'src/nss-@0@/nss-@0@.sym'.format(module)
|
||||
version_script_arg = join_paths(meson.current_source_dir(), sym)
|
||||
version_script_arg = join_paths(meson.source_root(), sym)
|
||||
|
||||
nss = shared_library(
|
||||
'nss_' + module,
|
||||
|
@ -1731,7 +1732,7 @@ if conf.get('ENABLE_LOGIND') == 1
|
|||
public_programs += exe
|
||||
|
||||
if conf.get('HAVE_PAM') == 1
|
||||
version_script_arg = join_paths(meson.current_source_dir(), pam_systemd_sym)
|
||||
version_script_arg = join_paths(meson.source_root(), pam_systemd_sym)
|
||||
pam_systemd = shared_library(
|
||||
'pam_systemd',
|
||||
pam_systemd_c,
|
||||
|
@ -2847,9 +2848,7 @@ foreach tuple : sanitizers
|
|||
test('@0@:@1@:@2@'.format(b, c, sanitizer),
|
||||
env,
|
||||
args : [exe.full_path(),
|
||||
join_paths(meson.source_root(),
|
||||
'test/fuzz-regressions',
|
||||
p)])
|
||||
join_paths(meson.source_root(), p)])
|
||||
endif
|
||||
endforeach
|
||||
endif
|
||||
|
@ -2861,7 +2860,7 @@ endforeach
|
|||
if git.found()
|
||||
all_files = run_command(
|
||||
git,
|
||||
['--git-dir=@0@/.git'.format(meson.current_source_dir()),
|
||||
['--git-dir=@0@/.git'.format(meson.source_root()),
|
||||
'ls-files',
|
||||
':/*.[ch]'])
|
||||
all_files = files(all_files.stdout().split())
|
||||
|
@ -2869,10 +2868,10 @@ if git.found()
|
|||
custom_target(
|
||||
'tags',
|
||||
output : 'tags',
|
||||
command : [env, 'etags', '-o', '@0@/TAGS'.format(meson.current_source_dir())] + all_files)
|
||||
command : [env, 'etags', '-o', '@0@/TAGS'.format(meson.source_root())] + all_files)
|
||||
run_target(
|
||||
'ctags',
|
||||
command : [env, 'ctags', '-o', '@0@/tags'.format(meson.current_source_dir())] + all_files)
|
||||
command : [env, 'ctags', '-o', '@0@/tags'.format(meson.source_root())] + all_files)
|
||||
endif
|
||||
|
||||
if git.found()
|
||||
|
@ -2885,17 +2884,17 @@ endif
|
|||
if git.found()
|
||||
git_head = run_command(
|
||||
git,
|
||||
['--git-dir=@0@/.git'.format(meson.current_source_dir()),
|
||||
['--git-dir=@0@/.git'.format(meson.source_root()),
|
||||
'rev-parse', 'HEAD']).stdout().strip()
|
||||
git_head_short = run_command(
|
||||
git,
|
||||
['--git-dir=@0@/.git'.format(meson.current_source_dir()),
|
||||
['--git-dir=@0@/.git'.format(meson.source_root()),
|
||||
'rev-parse', '--short=7', 'HEAD']).stdout().strip()
|
||||
|
||||
run_target(
|
||||
'git-snapshot',
|
||||
command : ['git', 'archive',
|
||||
'-o', '@0@/systemd-@1@.tar.gz'.format(meson.current_source_dir(),
|
||||
'-o', '@0@/systemd-@1@.tar.gz'.format(meson.source_root(),
|
||||
git_head_short),
|
||||
'--prefix', 'systemd-@0@/'.format(git_head),
|
||||
'HEAD'])
|
||||
|
@ -3053,10 +3052,10 @@ foreach tuple : [
|
|||
['blkid'],
|
||||
['dbus'],
|
||||
['glib'],
|
||||
['nss-myhostname', conf.get('ENABLE_NSS_MYHOSTNAME') == 1],
|
||||
['nss-mymachines', conf.get('ENABLE_NSS_MYMACHINES') == 1],
|
||||
['nss-resolve', conf.get('ENABLE_NSS_RESOLVE') == 1],
|
||||
['nss-systemd', conf.get('ENABLE_NSS_SYSTEMD') == 1],
|
||||
['nss-myhostname'],
|
||||
['nss-mymachines'],
|
||||
['nss-resolve'],
|
||||
['nss-systemd'],
|
||||
['hwdb'],
|
||||
['tpm'],
|
||||
['man pages', want_man],
|
||||
|
@ -3072,6 +3071,7 @@ foreach tuple : [
|
|||
['debug hashmap'],
|
||||
['debug mmap cache'],
|
||||
['valgrind', conf.get('VALGRIND') == 1],
|
||||
['trace logging', conf.get('LOG_TRACE') == 1],
|
||||
]
|
||||
|
||||
if tuple.length() >= 2
|
||||
|
|
|
@ -51,6 +51,8 @@ option('memory-accounting-default', type : 'boolean',
|
|||
description : 'enable MemoryAccounting= by default')
|
||||
option('valgrind', type : 'boolean', value : false,
|
||||
description : 'do extra operations to avoid valgrind warnings')
|
||||
option('log-trace', type : 'boolean', value : false,
|
||||
description : 'enable low level debug logging')
|
||||
|
||||
option('utmp', type : 'boolean',
|
||||
description : 'support for utmp/wtmp log handling')
|
||||
|
|
|
@ -1004,7 +1004,7 @@ int free_and_strdup(char **p, const char *s) {
|
|||
|
||||
assert(p);
|
||||
|
||||
/* Replaces a string pointer with an strdup()ed new string,
|
||||
/* Replaces a string pointer with a strdup()ed new string,
|
||||
* possibly freeing the old one. */
|
||||
|
||||
if (streq_ptr(*p, s))
|
||||
|
@ -1023,6 +1023,32 @@ int free_and_strdup(char **p, const char *s) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int free_and_strndup(char **p, const char *s, size_t l) {
|
||||
char *t;
|
||||
|
||||
assert(p);
|
||||
assert(s || l == 0);
|
||||
|
||||
/* Replaces a string pointer with a strndup()ed new string,
|
||||
* freeing the old one. */
|
||||
|
||||
if (!*p && !s)
|
||||
return 0;
|
||||
|
||||
if (*p && s && strneq(*p, s, l) && (l > strlen(*p) || (*p)[l] == '\0'))
|
||||
return 0;
|
||||
|
||||
if (s) {
|
||||
t = strndup(s, l);
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
} else
|
||||
t = NULL;
|
||||
|
||||
free_and_replace(*p, t);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if !HAVE_EXPLICIT_BZERO
|
||||
/*
|
||||
* Pointer to memset is volatile so that compiler must de-reference
|
||||
|
|
|
@ -176,6 +176,7 @@ char *strrep(const char *s, unsigned n);
|
|||
int split_pair(const char *s, const char *sep, char **l, char **r);
|
||||
|
||||
int free_and_strdup(char **p, const char *s);
|
||||
int free_and_strndup(char **p, const char *s, size_t l);
|
||||
|
||||
/* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */
|
||||
static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
|
||||
|
|
47
src/fuzz/fuzz-bus-message.c
Normal file
47
src/fuzz/fuzz-bus-message.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "bus-dump.h"
|
||||
#include "bus-message.h"
|
||||
#include "env-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fuzz.h"
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
_cleanup_free_ char *out = NULL; /* out should be freed after g */
|
||||
size_t out_size;
|
||||
_cleanup_fclose_ FILE *g = NULL;
|
||||
_cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
|
||||
_cleanup_free_ void *buffer = NULL;
|
||||
int r;
|
||||
|
||||
/* We don't want to fill the logs with messages about parse errors.
|
||||
* Disable most logging if not running standalone */
|
||||
if (!getenv("SYSTEMD_LOG_LEVEL"))
|
||||
log_set_max_level(LOG_CRIT);
|
||||
|
||||
r = sd_bus_new(&bus);
|
||||
assert_se(r >= 0);
|
||||
|
||||
assert_se(buffer = memdup(data, size));
|
||||
|
||||
r = bus_message_from_malloc(bus, buffer, size, NULL, 0, NULL, &m);
|
||||
if (r == -EBADMSG)
|
||||
return 0;
|
||||
assert_se(r >= 0);
|
||||
TAKE_PTR(buffer);
|
||||
|
||||
if (getenv_bool("SYSTEMD_FUZZ_OUTPUT") <= 0)
|
||||
assert_se(g = open_memstream(&out, &out_size));
|
||||
|
||||
bus_message_dump(m, g ?: stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
|
||||
|
||||
r = sd_bus_message_rewind(m, true);
|
||||
assert_se(r >= 0);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
|
||||
fuzzers += [
|
||||
[['src/fuzz/fuzz-bus-message.c'],
|
||||
[libshared],
|
||||
[]],
|
||||
|
||||
[['src/fuzz/fuzz-dns-packet.c',
|
||||
dns_type_headers],
|
||||
[libsystemd_resolve_core,
|
||||
|
|
|
@ -57,8 +57,14 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
|
|||
"%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%"PRIi64,
|
||||
m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
|
||||
m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() :
|
||||
m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", special_glyph(TRIANGULAR_BULLET), ansi_normal(),
|
||||
ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_normal(),
|
||||
m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "",
|
||||
special_glyph(TRIANGULAR_BULLET),
|
||||
ansi_normal(),
|
||||
|
||||
ansi_highlight(),
|
||||
bus_message_type_to_string(m->header->type) ?: "(unknown)",
|
||||
ansi_normal(),
|
||||
|
||||
m->header->endian,
|
||||
m->header->flags,
|
||||
m->header->version,
|
||||
|
|
|
@ -75,19 +75,38 @@ static void message_reset_parts(sd_bus_message *m) {
|
|||
m->cached_rindex_part_begin = 0;
|
||||
}
|
||||
|
||||
static void message_reset_containers(sd_bus_message *m) {
|
||||
unsigned i;
|
||||
|
||||
static struct bus_container *message_get_last_container(sd_bus_message *m) {
|
||||
assert(m);
|
||||
|
||||
for (i = 0; i < m->n_containers; i++) {
|
||||
free(m->containers[i].signature);
|
||||
free(m->containers[i].offsets);
|
||||
}
|
||||
if (m->n_containers == 0)
|
||||
return &m->root_container;
|
||||
|
||||
assert(m->containers);
|
||||
return m->containers + m->n_containers - 1;
|
||||
}
|
||||
|
||||
static void message_free_last_container(sd_bus_message *m) {
|
||||
struct bus_container *c;
|
||||
|
||||
c = message_get_last_container(m);
|
||||
|
||||
free(c->signature);
|
||||
free(c->peeked_signature);
|
||||
free(c->offsets);
|
||||
|
||||
/* Move to previous container, but not if we are on root container */
|
||||
if (m->n_containers > 0)
|
||||
m->n_containers--;
|
||||
}
|
||||
|
||||
static void message_reset_containers(sd_bus_message *m) {
|
||||
assert(m);
|
||||
|
||||
while (m->n_containers > 0)
|
||||
message_free_last_container(m);
|
||||
|
||||
m->containers = mfree(m->containers);
|
||||
|
||||
m->n_containers = m->containers_allocated = 0;
|
||||
m->containers_allocated = 0;
|
||||
m->root_container.index = 0;
|
||||
}
|
||||
|
||||
|
@ -110,10 +129,8 @@ static sd_bus_message* message_free(sd_bus_message *m) {
|
|||
free(m->iovec);
|
||||
|
||||
message_reset_containers(m);
|
||||
free(m->root_container.signature);
|
||||
free(m->root_container.offsets);
|
||||
|
||||
free(m->root_container.peeked_signature);
|
||||
assert(m->n_containers == 0);
|
||||
message_free_last_container(m);
|
||||
|
||||
bus_creds_done(&m->creds);
|
||||
return mfree(m);
|
||||
|
@ -208,7 +225,7 @@ static int message_append_field_string(
|
|||
/* dbus1 doesn't allow strings over 32bit, let's enforce this
|
||||
* globally, to not risk convertability */
|
||||
l = strlen(s);
|
||||
if (l > (size_t) (uint32_t) -1)
|
||||
if (l > UINT32_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
/* Signature "(yv)" where the variant contains "s" */
|
||||
|
@ -1088,16 +1105,6 @@ _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct bus_container *message_get_container(sd_bus_message *m) {
|
||||
assert(m);
|
||||
|
||||
if (m->n_containers == 0)
|
||||
return &m->root_container;
|
||||
|
||||
assert(m->containers);
|
||||
return m->containers + m->n_containers - 1;
|
||||
}
|
||||
|
||||
struct bus_body_part *message_append_part(sd_bus_message *m) {
|
||||
struct bus_body_part *part;
|
||||
|
||||
|
@ -1188,7 +1195,7 @@ static int message_add_offset(sd_bus_message *m, size_t offset) {
|
|||
/* Add offset to current container, unless this is the first
|
||||
* item in it, which will have the 0 offset, which we can
|
||||
* ignore. */
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
|
||||
if (!c->need_offsets)
|
||||
return 0;
|
||||
|
@ -1360,7 +1367,7 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void
|
|||
assert_return(bus_type_is_basic(type), -EINVAL);
|
||||
assert_return(!m->poisoned, -ESTALE);
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
|
||||
if (c->signature && c->signature[c->index]) {
|
||||
/* Container signature is already set */
|
||||
|
@ -1553,7 +1560,7 @@ _public_ int sd_bus_message_append_string_space(
|
|||
assert_return(!m->sealed, -EPERM);
|
||||
assert_return(!m->poisoned, -ESTALE);
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
|
||||
if (c->signature && c->signature[c->index]) {
|
||||
/* Container signature is already set */
|
||||
|
@ -1924,7 +1931,7 @@ _public_ int sd_bus_message_open_container(
|
|||
char type,
|
||||
const char *contents) {
|
||||
|
||||
struct bus_container *c, *w;
|
||||
struct bus_container *c;
|
||||
uint32_t *array_size = NULL;
|
||||
_cleanup_free_ char *signature = NULL;
|
||||
size_t before, begin = 0;
|
||||
|
@ -1942,7 +1949,7 @@ _public_ int sd_bus_message_open_container(
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
|
||||
signature = strdup(contents);
|
||||
if (!signature) {
|
||||
|
@ -1969,16 +1976,14 @@ _public_ int sd_bus_message_open_container(
|
|||
return r;
|
||||
|
||||
/* OK, let's fill it in */
|
||||
w = m->containers + m->n_containers++;
|
||||
w->enclosing = type;
|
||||
w->signature = TAKE_PTR(signature);
|
||||
w->index = 0;
|
||||
w->array_size = array_size;
|
||||
w->before = before;
|
||||
w->begin = begin;
|
||||
w->n_offsets = w->offsets_allocated = 0;
|
||||
w->offsets = NULL;
|
||||
w->need_offsets = need_offsets;
|
||||
m->containers[m->n_containers++] = (struct bus_container) {
|
||||
.enclosing = type,
|
||||
.signature = TAKE_PTR(signature),
|
||||
.array_size = array_size,
|
||||
.before = before,
|
||||
.begin = begin,
|
||||
.need_offsets = need_offsets,
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2169,7 +2174,7 @@ _public_ int sd_bus_message_close_container(sd_bus_message *m) {
|
|||
assert_return(m->n_containers > 0, -EINVAL);
|
||||
assert_return(!m->poisoned, -ESTALE);
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
|
||||
if (c->enclosing != SD_BUS_TYPE_ARRAY)
|
||||
if (c->signature && c->signature[c->index] != 0)
|
||||
|
@ -2439,11 +2444,6 @@ _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
|
|||
va_list ap;
|
||||
int r;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(types, -EINVAL);
|
||||
assert_return(!m->sealed, -EPERM);
|
||||
assert_return(!m->poisoned, -ESTALE);
|
||||
|
||||
va_start(ap, types);
|
||||
r = sd_bus_message_appendv(m, types, ap);
|
||||
va_end(ap);
|
||||
|
@ -2673,7 +2673,7 @@ _public_ int sd_bus_message_append_string_memfd(
|
|||
if (size > (uint64_t) (uint32_t) -1)
|
||||
return -EINVAL;
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
if (c->signature && c->signature[c->index]) {
|
||||
/* Container signature is already set */
|
||||
|
||||
|
@ -3006,7 +3006,7 @@ static bool message_end_of_signature(sd_bus_message *m) {
|
|||
|
||||
assert(m);
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
return !c->signature || c->signature[c->index] == 0;
|
||||
}
|
||||
|
||||
|
@ -3015,7 +3015,7 @@ static bool message_end_of_array(sd_bus_message *m, size_t index) {
|
|||
|
||||
assert(m);
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
if (c->enclosing != SD_BUS_TYPE_ARRAY)
|
||||
return false;
|
||||
|
||||
|
@ -3110,6 +3110,7 @@ static int container_next_item(sd_bus_message *m, struct bus_container *c, size_
|
|||
assert(alignment > 0);
|
||||
|
||||
*rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
|
||||
assert(c->offsets[c->offset_index+1] >= *rindex);
|
||||
c->item_size = c->offsets[c->offset_index+1] - *rindex;
|
||||
} else {
|
||||
|
||||
|
@ -3149,6 +3150,7 @@ static int container_next_item(sd_bus_message *m, struct bus_container *c, size_
|
|||
assert(alignment > 0);
|
||||
|
||||
*rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
|
||||
assert(c->offsets[c->offset_index+1] >= *rindex);
|
||||
c->item_size = c->offsets[c->offset_index+1] - *rindex;
|
||||
|
||||
c->offset_index++;
|
||||
|
@ -3276,7 +3278,7 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
|
|||
if (message_end_of_array(m, m->rindex))
|
||||
return 0;
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
if (c->signature[c->index] != type)
|
||||
return -ENXIO;
|
||||
|
||||
|
@ -3287,6 +3289,12 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
|
|||
if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
|
||||
bool ok;
|
||||
|
||||
/* D-Bus spec: The marshalling formats for the string-like types all end
|
||||
* with a single zero (NUL) byte, but that byte is not considered to be part
|
||||
* of the text. */
|
||||
if (c->item_size == 0)
|
||||
return -EBADMSG;
|
||||
|
||||
r = message_peek_body(m, &rindex, 1, c->item_size, &q);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -3381,6 +3389,10 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
|
|||
return r;
|
||||
|
||||
l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
|
||||
if (l == UINT32_MAX)
|
||||
/* avoid overflow right below */
|
||||
return -EBADMSG;
|
||||
|
||||
r = message_peek_body(m, &rindex, 1, l+1, &q);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -3403,6 +3415,10 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
|
|||
return r;
|
||||
|
||||
l = *(uint8_t*) q;
|
||||
if (l == UINT8_MAX)
|
||||
/* avoid overflow right below */
|
||||
return -EBADMSG;
|
||||
|
||||
r = message_peek_body(m, &rindex, 1, l+1, &q);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -3494,7 +3510,7 @@ static int bus_message_enter_array(
|
|||
|
||||
size_t rindex;
|
||||
void *q;
|
||||
int r, alignment;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(c);
|
||||
|
@ -3520,6 +3536,7 @@ static int bus_message_enter_array(
|
|||
|
||||
if (!BUS_MESSAGE_IS_GVARIANT(m)) {
|
||||
/* dbus1 */
|
||||
int alignment;
|
||||
|
||||
r = message_peek_body(m, &rindex, 4, 4, &q);
|
||||
if (r < 0)
|
||||
|
@ -3553,7 +3570,8 @@ static int bus_message_enter_array(
|
|||
*n_offsets = 0;
|
||||
|
||||
} else {
|
||||
size_t where, p = 0, framing, sz;
|
||||
size_t where, previous = 0, framing, sz;
|
||||
int alignment;
|
||||
unsigned i;
|
||||
|
||||
/* gvariant: variable length array */
|
||||
|
@ -3581,17 +3599,22 @@ static int bus_message_enter_array(
|
|||
if (!*offsets)
|
||||
return -ENOMEM;
|
||||
|
||||
alignment = bus_gvariant_get_alignment(c->signature);
|
||||
assert(alignment > 0);
|
||||
|
||||
for (i = 0; i < *n_offsets; i++) {
|
||||
size_t x;
|
||||
size_t x, start;
|
||||
|
||||
start = ALIGN_TO(previous, alignment);
|
||||
|
||||
x = bus_gvariant_read_word_le((uint8_t*) q + i * sz, sz);
|
||||
if (x > c->item_size - sz)
|
||||
return -EBADMSG;
|
||||
if (x < p)
|
||||
if (x < start)
|
||||
return -EBADMSG;
|
||||
|
||||
(*offsets)[i] = rindex + x;
|
||||
p = x;
|
||||
previous = x;
|
||||
}
|
||||
|
||||
*item_size = (*offsets)[0] - rindex;
|
||||
|
@ -3661,6 +3684,10 @@ static int bus_message_enter_variant(
|
|||
return r;
|
||||
|
||||
l = *(uint8_t*) q;
|
||||
if (l == UINT8_MAX)
|
||||
/* avoid overflow right below */
|
||||
return -EBADMSG;
|
||||
|
||||
r = message_peek_body(m, &rindex, 1, l+1, &q);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -3689,7 +3716,7 @@ static int build_struct_offsets(
|
|||
size_t *n_offsets) {
|
||||
|
||||
unsigned n_variable = 0, n_total = 0, v;
|
||||
size_t previous = 0, where;
|
||||
size_t previous, where;
|
||||
const char *p;
|
||||
size_t sz;
|
||||
void *q;
|
||||
|
@ -3768,6 +3795,7 @@ static int build_struct_offsets(
|
|||
|
||||
/* Second, loop again and build an offset table */
|
||||
p = signature;
|
||||
previous = m->rindex;
|
||||
while (*p != 0) {
|
||||
size_t n, offset;
|
||||
int k;
|
||||
|
@ -3781,37 +3809,37 @@ static int build_struct_offsets(
|
|||
memcpy(t, p, n);
|
||||
t[n] = 0;
|
||||
|
||||
size_t align = bus_gvariant_get_alignment(t);
|
||||
assert(align > 0);
|
||||
|
||||
/* The possible start of this member after including alignment */
|
||||
size_t start = ALIGN_TO(previous, align);
|
||||
|
||||
k = bus_gvariant_get_size(t);
|
||||
if (k < 0) {
|
||||
size_t x;
|
||||
|
||||
/* variable size */
|
||||
/* Variable size */
|
||||
if (v > 0) {
|
||||
v--;
|
||||
|
||||
x = bus_gvariant_read_word_le((uint8_t*) q + v*sz, sz);
|
||||
if (x >= size)
|
||||
return -EBADMSG;
|
||||
if (m->rindex + x < previous)
|
||||
return -EBADMSG;
|
||||
} else
|
||||
/* The last item's end
|
||||
* is determined from
|
||||
* the start of the
|
||||
* offset array */
|
||||
/* The last item's end is determined
|
||||
* from the start of the offset array */
|
||||
x = size - (n_variable * sz);
|
||||
|
||||
offset = m->rindex + x;
|
||||
|
||||
} else {
|
||||
size_t align;
|
||||
|
||||
/* fixed size */
|
||||
align = bus_gvariant_get_alignment(t);
|
||||
assert(align > 0);
|
||||
|
||||
offset = (*n_offsets == 0 ? m->rindex : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
|
||||
}
|
||||
if (offset < start) {
|
||||
log_debug("For type %s with alignment %zu, message specifies offset %zu which is smaller than previous end %zu + alignment = %zu",
|
||||
t, align, offset, previous, start);
|
||||
return -EBADMSG;
|
||||
}
|
||||
} else
|
||||
/* Fixed size */
|
||||
offset = start + k;
|
||||
}
|
||||
|
||||
previous = (*offsets)[(*n_offsets)++] = offset;
|
||||
|
@ -3941,10 +3969,10 @@ static int bus_message_enter_dict_entry(
|
|||
_public_ int sd_bus_message_enter_container(sd_bus_message *m,
|
||||
char type,
|
||||
const char *contents) {
|
||||
struct bus_container *c, *w;
|
||||
struct bus_container *c;
|
||||
uint32_t *array_size = NULL;
|
||||
_cleanup_free_ char *signature = NULL;
|
||||
size_t before;
|
||||
size_t before, end;
|
||||
_cleanup_free_ size_t *offsets = NULL;
|
||||
size_t n_offsets = 0, item_size = 0;
|
||||
int r;
|
||||
|
@ -4000,7 +4028,7 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m,
|
|||
if (message_end_of_array(m, m->rindex))
|
||||
return 0;
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
|
||||
signature = strdup(contents);
|
||||
if (!signature)
|
||||
|
@ -4023,28 +4051,26 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m,
|
|||
return r;
|
||||
|
||||
/* OK, let's fill it in */
|
||||
w = m->containers + m->n_containers++;
|
||||
w->enclosing = type;
|
||||
w->signature = TAKE_PTR(signature);
|
||||
w->peeked_signature = NULL;
|
||||
w->index = 0;
|
||||
|
||||
w->before = before;
|
||||
w->begin = m->rindex;
|
||||
|
||||
/* Unary type has fixed size of 1, but virtual size of 0 */
|
||||
if (BUS_MESSAGE_IS_GVARIANT(m) &&
|
||||
type == SD_BUS_TYPE_STRUCT &&
|
||||
isempty(signature))
|
||||
w->end = m->rindex + 0;
|
||||
end = m->rindex + 0;
|
||||
else
|
||||
w->end = m->rindex + c->item_size;
|
||||
end = m->rindex + c->item_size;
|
||||
|
||||
m->containers[m->n_containers++] = (struct bus_container) {
|
||||
.enclosing = type,
|
||||
.signature = TAKE_PTR(signature),
|
||||
|
||||
w->array_size = array_size;
|
||||
w->item_size = item_size;
|
||||
w->offsets = TAKE_PTR(offsets);
|
||||
w->n_offsets = n_offsets;
|
||||
w->offset_index = 0;
|
||||
.before = before,
|
||||
.begin = m->rindex,
|
||||
/* Unary type has fixed size of 1, but virtual size of 0 */
|
||||
.end = end,
|
||||
.array_size = array_size,
|
||||
.item_size = item_size,
|
||||
.offsets = TAKE_PTR(offsets),
|
||||
.n_offsets = n_offsets,
|
||||
};
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -4058,7 +4084,7 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
|
|||
assert_return(m->sealed, -EPERM);
|
||||
assert_return(m->n_containers > 0, -ENXIO);
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
|
||||
if (c->enclosing != SD_BUS_TYPE_ARRAY) {
|
||||
if (c->signature && c->signature[c->index] != 0)
|
||||
|
@ -4077,13 +4103,9 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
free(c->signature);
|
||||
free(c->peeked_signature);
|
||||
free(c->offsets);
|
||||
m->n_containers--;
|
||||
|
||||
c = message_get_container(m);
|
||||
message_free_last_container(m);
|
||||
|
||||
c = message_get_last_container(m);
|
||||
saved = c->index;
|
||||
c->index = c->saved_index;
|
||||
r = container_next_item(m, c, &m->rindex);
|
||||
|
@ -4101,19 +4123,16 @@ static void message_quit_container(sd_bus_message *m) {
|
|||
assert(m->sealed);
|
||||
assert(m->n_containers > 0);
|
||||
|
||||
c = message_get_container(m);
|
||||
|
||||
/* Undo seeks */
|
||||
c = message_get_last_container(m);
|
||||
assert(m->rindex >= c->before);
|
||||
m->rindex = c->before;
|
||||
|
||||
/* Free container */
|
||||
free(c->signature);
|
||||
free(c->offsets);
|
||||
m->n_containers--;
|
||||
message_free_last_container(m);
|
||||
|
||||
/* Correct index of new top-level container */
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
c->index = c->saved_index;
|
||||
}
|
||||
|
||||
|
@ -4130,7 +4149,7 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
|
|||
if (message_end_of_array(m, m->rindex))
|
||||
goto eof;
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
|
||||
if (bus_type_is_basic(c->signature[c->index])) {
|
||||
if (contents)
|
||||
|
@ -4144,20 +4163,20 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
|
|||
|
||||
if (contents) {
|
||||
size_t l;
|
||||
char *sig;
|
||||
|
||||
r = signature_element_length(c->signature+c->index+1, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
assert(l >= 1);
|
||||
/* signature_element_length does verification internally */
|
||||
|
||||
sig = strndup(c->signature + c->index + 1, l);
|
||||
if (!sig)
|
||||
/* The array element must not be empty */
|
||||
assert(l >= 1);
|
||||
if (free_and_strndup(&c->peeked_signature,
|
||||
c->signature + c->index + 1, l) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
free(c->peeked_signature);
|
||||
*contents = c->peeked_signature = sig;
|
||||
*contents = c->peeked_signature;
|
||||
}
|
||||
|
||||
if (type)
|
||||
|
@ -4170,19 +4189,17 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
|
|||
|
||||
if (contents) {
|
||||
size_t l;
|
||||
char *sig;
|
||||
|
||||
r = signature_element_length(c->signature+c->index, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
assert(l >= 2);
|
||||
sig = strndup(c->signature + c->index + 1, l - 2);
|
||||
if (!sig)
|
||||
assert(l >= 3);
|
||||
if (free_and_strndup(&c->peeked_signature,
|
||||
c->signature + c->index + 1, l - 2) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
free(c->peeked_signature);
|
||||
*contents = c->peeked_signature = sig;
|
||||
*contents = c->peeked_signature;
|
||||
}
|
||||
|
||||
if (type)
|
||||
|
@ -4222,9 +4239,8 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
|
|||
if (k > c->item_size)
|
||||
return -EBADMSG;
|
||||
|
||||
free(c->peeked_signature);
|
||||
c->peeked_signature = strndup((char*) q + 1, k - 1);
|
||||
if (!c->peeked_signature)
|
||||
if (free_and_strndup(&c->peeked_signature,
|
||||
(char*) q + 1, k - 1) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!signature_is_valid(c->peeked_signature, true))
|
||||
|
@ -4240,6 +4256,10 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
|
|||
return r;
|
||||
|
||||
l = *(uint8_t*) q;
|
||||
if (l == UINT8_MAX)
|
||||
/* avoid overflow right below */
|
||||
return -EBADMSG;
|
||||
|
||||
r = message_peek_body(m, &rindex, 1, l+1, &q);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -4277,11 +4297,10 @@ _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
|
|||
message_reset_containers(m);
|
||||
m->rindex = 0;
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
} else {
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
|
||||
c->offset_index = 0;
|
||||
c->index = 0;
|
||||
m->rindex = c->begin;
|
||||
}
|
||||
|
@ -4496,10 +4515,6 @@ _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
|
|||
va_list ap;
|
||||
int r;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(m->sealed, -EPERM);
|
||||
assert_return(types, -EINVAL);
|
||||
|
||||
va_start(ap, types);
|
||||
r = sd_bus_message_readv(m, types, ap);
|
||||
va_end(ap);
|
||||
|
@ -4524,7 +4539,7 @@ _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
|
|||
if (message_end_of_array(m, m->rindex))
|
||||
return 0;
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
|
||||
r = signature_element_length(c->signature + c->index, &l);
|
||||
if (r < 0)
|
||||
|
@ -4690,7 +4705,7 @@ _public_ int sd_bus_message_read_array(
|
|||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
c = message_get_container(m);
|
||||
c = message_get_last_container(m);
|
||||
|
||||
if (BUS_MESSAGE_IS_GVARIANT(m)) {
|
||||
align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
|
||||
|
@ -4827,6 +4842,10 @@ static int message_peek_field_string(
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (l == UINT32_MAX)
|
||||
/* avoid overflow right below */
|
||||
return -EBADMSG;
|
||||
|
||||
r = message_peek_fields(m, ri, 1, l+1, &q);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -4878,6 +4897,10 @@ static int message_peek_field_signature(
|
|||
return r;
|
||||
|
||||
l = *(uint8_t*) q;
|
||||
if (l == UINT8_MAX)
|
||||
/* avoid overflow right below */
|
||||
return -EBADMSG;
|
||||
|
||||
r = message_peek_fields(m, ri, 1, l+1, &q);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -4959,18 +4982,18 @@ static int message_skip_fields(
|
|||
|
||||
} else if (t == SD_BUS_TYPE_ARRAY) {
|
||||
|
||||
r = signature_element_length(*signature+1, &l);
|
||||
r = signature_element_length(*signature + 1, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
assert(l >= 1);
|
||||
{
|
||||
char sig[l-1], *s;
|
||||
char sig[l + 1], *s = sig;
|
||||
uint32_t nas;
|
||||
int alignment;
|
||||
|
||||
strncpy(sig, *signature + 1, l-1);
|
||||
s = sig;
|
||||
strncpy(sig, *signature + 1, l);
|
||||
sig[l] = '\0';
|
||||
|
||||
alignment = bus_type_get_alignment(sig[0]);
|
||||
if (alignment < 0)
|
||||
|
@ -5014,9 +5037,9 @@ static int message_skip_fields(
|
|||
|
||||
assert(l >= 2);
|
||||
{
|
||||
char sig[l-1], *s;
|
||||
strncpy(sig, *signature + 1, l-1);
|
||||
s = sig;
|
||||
char sig[l + 1], *s = sig;
|
||||
strncpy(sig, *signature + 1, l);
|
||||
sig[l] = '\0';
|
||||
|
||||
r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
|
||||
if (r < 0)
|
||||
|
@ -5025,7 +5048,7 @@ static int message_skip_fields(
|
|||
|
||||
*signature += l;
|
||||
} else
|
||||
return -EINVAL;
|
||||
return -EBADMSG;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5056,25 +5079,21 @@ int bus_message_parse_fields(sd_bus_message *m) {
|
|||
|
||||
if (*p == 0) {
|
||||
size_t l;
|
||||
char *c;
|
||||
|
||||
/* We found the beginning of the signature
|
||||
* string, yay! We require the body to be a
|
||||
* structure, so verify it and then strip the
|
||||
* opening/closing brackets. */
|
||||
|
||||
l = ((char*) m->footer + m->footer_accessible) - p - (1 + sz);
|
||||
l = (char*) m->footer + m->footer_accessible - p - (1 + sz);
|
||||
if (l < 2 ||
|
||||
p[1] != SD_BUS_TYPE_STRUCT_BEGIN ||
|
||||
p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END)
|
||||
return -EBADMSG;
|
||||
|
||||
c = strndup(p + 1 + 1, l - 2);
|
||||
if (!c)
|
||||
if (free_and_strndup(&m->root_container.signature,
|
||||
p + 1 + 1, l - 2) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
free(m->root_container.signature);
|
||||
m->root_container.signature = c;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -5396,6 +5415,8 @@ int bus_message_parse_fields(sd_bus_message *m) {
|
|||
&m->root_container.item_size,
|
||||
&m->root_container.offsets,
|
||||
&m->root_container.n_offsets);
|
||||
if (r == -EINVAL)
|
||||
return -EBADMSG;
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
@ -5591,7 +5612,7 @@ _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complet
|
|||
|
||||
assert_return(m, NULL);
|
||||
|
||||
c = complete ? &m->root_container : message_get_container(m);
|
||||
c = complete ? &m->root_container : message_get_last_container(m);
|
||||
return strempty(c->signature);
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,12 @@ static int signature_element_length_internal(
|
|||
p += t;
|
||||
}
|
||||
|
||||
if (p - s < 2)
|
||||
/* D-Bus spec: Empty structures are not allowed; there
|
||||
* must be at least one type code between the parentheses.
|
||||
*/
|
||||
return -EINVAL;
|
||||
|
||||
*l = p - s + 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
#include "util.h"
|
||||
|
||||
static void test_bus_gvariant_is_fixed_size(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(bus_gvariant_is_fixed_size("") > 0);
|
||||
assert_se(bus_gvariant_is_fixed_size("()") > 0);
|
||||
assert_se(bus_gvariant_is_fixed_size("()") == -EINVAL);
|
||||
assert_se(bus_gvariant_is_fixed_size("y") > 0);
|
||||
assert_se(bus_gvariant_is_fixed_size("u") > 0);
|
||||
assert_se(bus_gvariant_is_fixed_size("b") > 0);
|
||||
|
@ -42,8 +44,10 @@ static void test_bus_gvariant_is_fixed_size(void) {
|
|||
}
|
||||
|
||||
static void test_bus_gvariant_get_size(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(bus_gvariant_get_size("") == 0);
|
||||
assert_se(bus_gvariant_get_size("()") == 1);
|
||||
assert_se(bus_gvariant_get_size("()") == -EINVAL);
|
||||
assert_se(bus_gvariant_get_size("y") == 1);
|
||||
assert_se(bus_gvariant_get_size("u") == 4);
|
||||
assert_se(bus_gvariant_get_size("b") == 1);
|
||||
|
@ -74,8 +78,10 @@ static void test_bus_gvariant_get_size(void) {
|
|||
}
|
||||
|
||||
static void test_bus_gvariant_get_alignment(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(bus_gvariant_get_alignment("") == 1);
|
||||
assert_se(bus_gvariant_get_alignment("()") == 1);
|
||||
assert_se(bus_gvariant_get_alignment("()") == -EINVAL);
|
||||
assert_se(bus_gvariant_get_alignment("y") == 1);
|
||||
assert_se(bus_gvariant_get_alignment("b") == 1);
|
||||
assert_se(bus_gvariant_get_alignment("u") == 4);
|
||||
|
@ -129,7 +135,10 @@ static int test_marshal(void) {
|
|||
|
||||
bus->message_version = 2; /* dirty hack to enable gvariant */
|
||||
|
||||
assert_se(sd_bus_message_new_method_call(bus, &m, "a.service.name", "/an/object/path/which/is/really/really/long/so/that/we/hit/the/eight/bit/boundary/by/quite/some/margin/to/test/this/stuff/that/it/really/works", "an.interface.name", "AMethodName") >= 0);
|
||||
r = sd_bus_message_new_method_call(bus, &m, "a.service.name",
|
||||
"/an/object/path/which/is/really/really/long/so/that/we/hit/the/eight/bit/boundary/by/quite/some/margin/to/test/this/stuff/that/it/really/works",
|
||||
"an.interface.name", "AMethodName");
|
||||
assert_se(r >= 0);
|
||||
|
||||
assert_cc(sizeof(struct bus_header) == 16);
|
||||
|
||||
|
@ -202,7 +211,7 @@ static int test_marshal(void) {
|
|||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_setup_logging(LOG_INFO);
|
||||
test_setup_logging(LOG_DEBUG);
|
||||
|
||||
test_bus_gvariant_is_fixed_size();
|
||||
test_bus_gvariant_get_size();
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#include "bus-label.h"
|
||||
#include "bus-message.h"
|
||||
#include "bus-util.h"
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "log.h"
|
||||
#include "tests.h"
|
||||
#include "util.h"
|
||||
|
@ -111,7 +111,7 @@ int main(int argc, char *argv[]) {
|
|||
uint8_t u, v;
|
||||
void *buffer = NULL;
|
||||
size_t sz;
|
||||
char *h;
|
||||
_cleanup_free_ char *h = NULL;
|
||||
const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
|
||||
char *s;
|
||||
_cleanup_free_ char *first = NULL, *second = NULL, *third = NULL;
|
||||
|
@ -154,7 +154,7 @@ int main(int argc, char *argv[]) {
|
|||
assert_se(r >= 0);
|
||||
|
||||
r = sd_bus_message_append(m, "()");
|
||||
assert_se(r >= 0);
|
||||
assert_se(r == -EINVAL);
|
||||
|
||||
r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
|
||||
assert_se(r >= 0);
|
||||
|
@ -197,11 +197,9 @@ int main(int argc, char *argv[]) {
|
|||
r = bus_message_get_blob(m, &buffer, &sz);
|
||||
assert_se(r >= 0);
|
||||
|
||||
h = hexmem(buffer, sz);
|
||||
h = cescape_length(buffer, sz);
|
||||
assert_se(h);
|
||||
|
||||
log_info("message size = %zu, contents =\n%s", sz, h);
|
||||
free(h);
|
||||
|
||||
#if HAVE_GLIB
|
||||
#ifndef __SANITIZE_ADDRESS__
|
||||
|
@ -298,7 +296,7 @@ int main(int argc, char *argv[]) {
|
|||
assert_se(v == 10);
|
||||
|
||||
r = sd_bus_message_read(m, "()");
|
||||
assert_se(r > 0);
|
||||
assert_se(r < 0);
|
||||
|
||||
r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
|
||||
assert_se(r > 0);
|
||||
|
@ -379,7 +377,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
|
||||
|
||||
r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y()");
|
||||
r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y");
|
||||
assert_se(r >= 0);
|
||||
|
||||
assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
|
||||
|
|
|
@ -14,9 +14,9 @@ int main(int argc, char *argv[]) {
|
|||
assert_se(signature_is_single("v", false));
|
||||
assert_se(signature_is_single("as", false));
|
||||
assert_se(signature_is_single("(ss)", false));
|
||||
assert_se(signature_is_single("()", false));
|
||||
assert_se(signature_is_single("(()()()()())", false));
|
||||
assert_se(signature_is_single("(((())))", false));
|
||||
assert_se(!signature_is_single("()", false));
|
||||
assert_se(!signature_is_single("(()()()()())", false));
|
||||
assert_se(!signature_is_single("(((())))", false));
|
||||
assert_se(signature_is_single("((((s))))", false));
|
||||
assert_se(signature_is_single("{ss}", true));
|
||||
assert_se(signature_is_single("a{ss}", false));
|
||||
|
@ -61,7 +61,7 @@ int main(int argc, char *argv[]) {
|
|||
assert_se(signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas", false));
|
||||
assert_se(!signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaau", false));
|
||||
|
||||
assert_se(signature_is_valid("(((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))", false));
|
||||
assert_se(signature_is_valid("((((((((((((((((((((((((((((((((s))))))))))))))))))))))))))))))))", false));
|
||||
assert_se(!signature_is_valid("((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))", false));
|
||||
|
||||
assert_se(namespace_complex_pattern("", ""));
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "macro.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "tests.h"
|
||||
#include "utf8.h"
|
||||
|
||||
static void test_string_erase(void) {
|
||||
|
@ -30,6 +31,64 @@ static void test_string_erase(void) {
|
|||
assert_se(x[9] == '\0');
|
||||
}
|
||||
|
||||
static void test_free_and_strndup_one(char **t, const char *src, size_t l, const char *expected, bool change) {
|
||||
int r;
|
||||
|
||||
log_debug("%s: \"%s\", \"%s\", %zd (expect \"%s\", %s)",
|
||||
__func__, strnull(*t), strnull(src), l, strnull(expected), yes_no(change));
|
||||
|
||||
r = free_and_strndup(t, src, l);
|
||||
assert_se(streq_ptr(*t, expected));
|
||||
assert_se(r == change); /* check that change occurs only when necessary */
|
||||
}
|
||||
|
||||
static void test_free_and_strndup(void) {
|
||||
static const struct test_case {
|
||||
const char *src;
|
||||
size_t len;
|
||||
const char *expected;
|
||||
} cases[] = {
|
||||
{"abc", 0, ""},
|
||||
{"abc", 0, ""},
|
||||
{"abc", 1, "a"},
|
||||
{"abc", 2, "ab"},
|
||||
{"abc", 3, "abc"},
|
||||
{"abc", 4, "abc"},
|
||||
{"abc", 5, "abc"},
|
||||
{"abc", 5, "abc"},
|
||||
{"abc", 4, "abc"},
|
||||
{"abc", 3, "abc"},
|
||||
{"abc", 2, "ab"},
|
||||
{"abc", 1, "a"},
|
||||
{"abc", 0, ""},
|
||||
|
||||
{"", 0, ""},
|
||||
{"", 1, ""},
|
||||
{"", 2, ""},
|
||||
{"", 0, ""},
|
||||
{"", 1, ""},
|
||||
{"", 2, ""},
|
||||
{"", 2, ""},
|
||||
{"", 1, ""},
|
||||
{"", 0, ""},
|
||||
|
||||
{NULL, 0, NULL},
|
||||
|
||||
{"foo", 3, "foo"},
|
||||
{"foobar", 6, "foobar"},
|
||||
};
|
||||
|
||||
_cleanup_free_ char *t = NULL;
|
||||
const char *prev_expected = t;
|
||||
|
||||
for (unsigned i = 0; i < ELEMENTSOF(cases); i++) {
|
||||
test_free_and_strndup_one(&t,
|
||||
cases[i].src, cases[i].len, cases[i].expected,
|
||||
!streq_ptr(cases[i].expected, prev_expected));
|
||||
prev_expected = t;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_ascii_strcasecmp_n(void) {
|
||||
|
||||
assert_se(ascii_strcasecmp_n("", "", 0) == 0);
|
||||
|
@ -520,7 +579,10 @@ static void test_memory_startswith_no_case(void) {
|
|||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_setup_logging(LOG_DEBUG);
|
||||
|
||||
test_string_erase();
|
||||
test_free_and_strndup();
|
||||
test_ascii_strcasecmp_n();
|
||||
test_ascii_strcasecmp_nn();
|
||||
test_cellescape();
|
||||
|
|
1
test/fuzz-regressions/.gitattributes
vendored
1
test/fuzz-regressions/.gitattributes
vendored
|
@ -1 +0,0 @@
|
|||
/*/* -whitespace
|
|
@ -1,43 +0,0 @@
|
|||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
|
||||
sanitize_address = custom_target(
|
||||
'sanitize-address-fuzzers',
|
||||
output : 'sanitize-address-fuzzers',
|
||||
command : [meson_build_sh,
|
||||
meson.source_root(),
|
||||
'@OUTPUT@',
|
||||
'fuzzers',
|
||||
'-Db_lundef=false -Db_sanitize=address'])
|
||||
|
||||
sanitizers = [['address', sanitize_address]]
|
||||
|
||||
fuzz_regression_tests = '''
|
||||
fuzz-dhcp6-client/crash-4003c06fce43a11fbd22f02584df2807ac333eae
|
||||
fuzz-dhcp6-client/crash-6e88fcb6b85c9436bcbe05219aa8e550194645ef
|
||||
fuzz-dns-packet/issue-7888
|
||||
fuzz-dns-packet/oss-fuzz-5465
|
||||
fuzz-journal-remote/crash-5a8f03d4c3a46fcded39527084f437e8e4b54b76
|
||||
fuzz-journal-remote/crash-96dee870ea66d03e89ac321eee28ea63a9b9aa45
|
||||
fuzz-journal-remote/oss-fuzz-8659
|
||||
fuzz-journal-remote/oss-fuzz-8686
|
||||
fuzz-journald-syslog/github-9795
|
||||
fuzz-journald-syslog/github-9820
|
||||
fuzz-journald-syslog/github-9827
|
||||
fuzz-journald-syslog/github-9829
|
||||
fuzz-ndisc-rs/timeout-2815b773c712fa33bea62f541dfa3017c64ea2f1
|
||||
fuzz-ndisc-rs/timeout-61fff7fd1e5dcc07e1b656baab29065ce634ad5b
|
||||
fuzz-unit-file/oss-fuzz-6884
|
||||
fuzz-unit-file/oss-fuzz-6885
|
||||
fuzz-unit-file/oss-fuzz-6886
|
||||
fuzz-unit-file/oss-fuzz-6892
|
||||
fuzz-unit-file/oss-fuzz-6897
|
||||
fuzz-unit-file/oss-fuzz-6897-evverx
|
||||
fuzz-unit-file/oss-fuzz-6908
|
||||
fuzz-unit-file/oss-fuzz-6917
|
||||
fuzz-unit-file/oss-fuzz-6977
|
||||
fuzz-unit-file/oss-fuzz-6977-unminimized
|
||||
fuzz-unit-file/oss-fuzz-7004
|
||||
fuzz-unit-file/oss-fuzz-8064
|
||||
fuzz-unit-file/oss-fuzz-8827
|
||||
fuzz-unit-file/oss-fuzz-10007
|
||||
'''.split()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/fuzz/fuzz-bus-message/message1
Normal file
BIN
test/fuzz/fuzz-bus-message/message1
Normal file
Binary file not shown.
Binary file not shown.
33
test/fuzz/meson.build
Normal file
33
test/fuzz/meson.build
Normal file
|
@ -0,0 +1,33 @@
|
|||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
|
||||
sanitize_address = custom_target(
|
||||
'sanitize-address-fuzzers',
|
||||
output : 'sanitize-address-fuzzers',
|
||||
command : [meson_build_sh,
|
||||
meson.source_root(),
|
||||
'@OUTPUT@',
|
||||
'fuzzers',
|
||||
'-Db_lundef=false -Db_sanitize=address'])
|
||||
|
||||
sanitizers = [['address', sanitize_address]]
|
||||
|
||||
if git.found()
|
||||
out = run_command(
|
||||
git,
|
||||
'--git-dir=@0@/.git'.format(meson.source_root()),
|
||||
'ls-files', ':/test/fuzz/*/*')
|
||||
else
|
||||
out = run_command(
|
||||
'sh', '-c', 'ls @0@/*/*'.format(meson.current_source_dir()))
|
||||
endif
|
||||
|
||||
fuzz_regression_tests = []
|
||||
foreach p : out.stdout().split()
|
||||
# Remove the last entry which is ''.
|
||||
#
|
||||
# Also, backslashes get mangled, so skip test. See
|
||||
# https://github.com/mesonbuild/meson/issues/1564.
|
||||
if not p.contains('\\')
|
||||
fuzz_regression_tests += p
|
||||
endif
|
||||
endforeach
|
|
@ -256,4 +256,4 @@ if conf.get('ENABLE_HWDB') == 1
|
|||
endif
|
||||
endif
|
||||
|
||||
subdir('fuzz-regressions')
|
||||
subdir('fuzz')
|
||||
|
|
|
@ -35,8 +35,10 @@ fi
|
|||
meson $build -D$fuzzflag -Db_lundef=false
|
||||
ninja -C $build fuzzers
|
||||
|
||||
for d in "$(dirname "$0")/../test/fuzz-corpus/"*; do
|
||||
zip -jqr $OUT/fuzz-$(basename "$d")_seed_corpus.zip "$d"
|
||||
# The seed corpus is a separate flat archive for each fuzzer,
|
||||
# with a fixed name ${fuzzer}_seed_corpus.zip.
|
||||
for d in "$(dirname "$0")/../test/fuzz/fuzz-"*; do
|
||||
zip -jqr $OUT/$(basename "$d")_seed_corpus.zip "$d"
|
||||
done
|
||||
|
||||
# get fuzz-dns-packet corpus
|
||||
|
|
Loading…
Reference in a new issue