Path: blob/main/lib/iolog/regress/fuzz/fuzz_iolog_json.c
1532 views
/*1* Copyright (c) 2021 Todd C. Miller <[email protected]>2*3* Permission to use, copy, modify, and distribute this software for any4* purpose with or without fee is hereby granted, provided that the above5* copyright notice and this permission notice appear in all copies.6*7* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES8* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF9* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR10* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES11* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN12* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF13* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.14*/1516#include <config.h>1718#include <stdio.h>19#include <stdlib.h>20#include <fcntl.h>21#include <unistd.h>22#if defined(HAVE_STDINT_H)23# include <stdint.h>24#elif defined(HAVE_INTTYPES_H)25# include <inttypes.h>26#endif2728#include <sudo_compat.h>29#include <sudo_debug.h>30#include <sudo_eventlog.h>31#include <sudo_fatal.h>32#include <sudo_iolog.h>33#include <sudo_plugin.h>34#include <sudo_util.h>3536int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);3738static FILE *39open_data(const uint8_t *data, size_t size)40{41#ifdef HAVE_FMEMOPEN42/* Operate in-memory. */43return fmemopen((void *)data, size, "r");44#else45char tempfile[] = "/tmp/json.XXXXXX";46size_t nwritten;47int fd;4849/* Use (unlinked) temporary file. */50fd = mkstemp(tempfile);51if (fd == -1)52return NULL;53unlink(tempfile);54nwritten = write(fd, data, size);55if (nwritten != size) {56close(fd);57return NULL;58}59lseek(fd, 0, SEEK_SET);60return fdopen(fd, "r");61#endif62}6364static int65fuzz_conversation(int num_msgs, const struct sudo_conv_message msgs[],66struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)67{68int n;6970for (n = 0; n < num_msgs; n++) {71const struct sudo_conv_message *msg = &msgs[n];7273switch (msg->msg_type & 0xff) {74case SUDO_CONV_PROMPT_ECHO_ON:75case SUDO_CONV_PROMPT_MASK:76case SUDO_CONV_PROMPT_ECHO_OFF:77/* input not supported */78return -1;79case SUDO_CONV_ERROR_MSG:80case SUDO_CONV_INFO_MSG:81/* no output for fuzzers */82break;83default:84return -1;85}86}87return 0;88}8990int91LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)92{93struct eventlog *evlog = NULL;94FILE *fp;9596initprogname("fuzz_iolog_json");97if (getenv("SUDO_FUZZ_VERBOSE") == NULL)98sudo_warn_set_conversation(fuzz_conversation);99100fp = open_data(data, size);101if (fp == NULL)102return 0;103104/* Parsed contents of an log.json file are stored in evlog. */105evlog = calloc(1, sizeof(*evlog));106if (evlog != NULL) {107evlog->runuid = (uid_t)-1;108evlog->rungid = (gid_t)-1;109evlog->exit_value = -1;110111/* Try to parse buffer as a JSON-format I/O log info file. */112iolog_parse_loginfo_json(fp, "fuzz.json", evlog);113eventlog_free(evlog);114}115fclose(fp);116117fflush(stdout);118119return 0;120}121122123