// SPDX-License-Identifier: GPL-2.0-or-later /* * zlog fuzzer target. */ #include #include "log.h" #include "zlog_5424.h" #include "command.h" struct input_opts { uint16_t out1_debug; uint16_t out2_debug; uint16_t out3_warn; uint8_t fmt; uint8_t dst; }; static char buffer[65536]; int main(int argc, char **argv) { struct input_opts io; int fd; int pair[2] = {-1, -1}; if (read(0, &io, sizeof(io)) != sizeof(io)) return 1; if (io.fmt > ZLOG_FMT_LAST) return 1; switch (io.dst) { case 0: fd = 1; break; case 1: socketpair(AF_UNIX, SOCK_STREAM, 0, pair); fd = pair[0]; break; case 2: socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair); fd = pair[0]; break; case 3: socketpair(AF_UNIX, SOCK_DGRAM, 0, pair); fd = pair[0]; break; default: return 1; } pid_t child = -1; if (pair[1] != -1) { child = fork(); if (child == 0) { char buf[4096]; close(pair[0]); while (read(pair[1], buf, sizeof(buf)) > 0) ; exit(0); } else if (child == -1) { perror("fork"); return 1; } close(pair[1]); } for (size_t i = 0; i < sizeof(buffer); i++) buffer[i] = (i | 0x20) & 0x7f; zlog_aux_init("FUZZBALL: ", LOG_DEBUG); zlog_tls_buffer_init(); struct zlog_cfg_5424 cfg[1] = {}; zlog_5424_init(cfg); cfg->facility = LOG_DAEMON; cfg->prio_min = LOG_DEBUG; cfg->kw_version = true; cfg->kw_location = true; cfg->kw_uid = true; cfg->kw_ec = true; cfg->kw_args = true; cfg->ts_flags = 9; cfg->fmt = io.fmt; cfg->dst = ZLOG_5424_DST_FD; cfg->fd = fd; cmd_hostname_set("TEST"); cfg->master = event_master_create("TEST"); zlog_5424_apply_dst(cfg); zlog_debug("test #1 %.*s", (int)io.out1_debug, buffer); zlog_debug("test #2 %.*s", (int)io.out2_debug, buffer); zlog_warn("test #1 %.*s", (int)io.out3_warn, buffer); zlog_tls_buffer_flush(); zlog_tls_buffer_fini(); /* AFL++ seems to do some weird stuff with its fuzzing target, make * sure the fork() child is zapped here rather than creating hordes * of it. */ close(fd); if (child != -1) kill(child, SIGTERM); return 0; }