Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/lib/fuzzstub/fuzzstub.c
1532 views
1
/*
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2021 Todd C. Miller <[email protected]>
5
*
6
* Permission to use, copy, modify, and distribute this software for any
7
* purpose with or without fee is hereby granted, provided that the above
8
* copyright notice and this permission notice appear in all copies.
9
*
10
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
*/
18
19
#include <config.h>
20
21
#include <sys/stat.h>
22
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <errno.h>
27
#include <limits.h>
28
#include <fcntl.h>
29
#include <time.h>
30
#include <unistd.h>
31
#if defined(HAVE_STDINT_H)
32
# include <stdint.h>
33
#elif defined(HAVE_INTTYPES_H)
34
# include <inttypes.h>
35
#endif
36
37
#include <sudo_compat.h>
38
#include <sudo_util.h>
39
40
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
41
42
sudo_dso_public int main(int argc, char *argv[]);
43
44
/*
45
* Simple driver for fuzzers built for LLVM libfuzzer.
46
* This stub library allows fuzz targets to be built and run without
47
* libfuzzer. No actual fuzzing will occur but the provided inputs
48
* will be tested.
49
*/
50
int
51
main(int argc, char *argv[])
52
{
53
struct timespec start_time, stop_time;
54
size_t filesize, bufsize = 0;
55
ssize_t nread;
56
struct stat sb;
57
uint8_t *buf = NULL;
58
int fd, i, errors = 0;
59
int verbose = 0;
60
long ms;
61
62
/* Test provided input files. */
63
for (i = 1; i < argc; i++) {
64
const char *arg = argv[i];
65
if (*arg == '-') {
66
if (strncmp(arg, "-verbosity=", sizeof("-verbosity=") - 1) == 0) {
67
verbose = atoi(arg + sizeof("-verbosity=") - 1);
68
}
69
continue;
70
}
71
fd = open(arg, O_RDONLY);
72
if (fd == -1 || fstat(fd, &sb) != 0) {
73
fprintf(stderr, "open %s: %s\n", arg, strerror(errno));
74
if (fd != -1)
75
close(fd);
76
errors++;
77
continue;
78
}
79
#ifndef __LP64__
80
if (sizeof(sb.st_size) > sizeof(size_t) && sb.st_size > SSIZE_MAX) {
81
errno = E2BIG;
82
fprintf(stderr, "%s: %s\n", arg, strerror(errno));
83
close(fd);
84
errors++;
85
continue;
86
}
87
#endif
88
filesize = (size_t)sb.st_size;
89
if (bufsize < filesize) {
90
void *tmp = realloc(buf, filesize);
91
if (tmp == NULL) {
92
fprintf(stderr, "realloc: %s\n", strerror(errno));
93
close(fd);
94
errors++;
95
continue;
96
}
97
buf = tmp;
98
bufsize = filesize;
99
}
100
nread = read(fd, buf, filesize);
101
if ((size_t)nread != filesize) {
102
if (nread < 0)
103
fprintf(stderr, "read %s: %s\n", arg, strerror(errno));
104
else
105
fprintf(stderr, "read %s: short read\n", arg);
106
close(fd);
107
errors++;
108
continue;
109
}
110
close(fd);
111
112
/* NOTE: doesn't support LLVMFuzzerInitialize() (but we don't use it) */
113
if (verbose > 0) {
114
fprintf(stderr, "Running: %s\n", arg);
115
sudo_gettime_mono(&start_time);
116
}
117
LLVMFuzzerTestOneInput(buf, (size_t)nread);
118
if (verbose > 0) {
119
sudo_gettime_mono(&stop_time);
120
sudo_timespecsub(&stop_time, &start_time, &stop_time);
121
ms = (stop_time.tv_sec * 1000) + (stop_time.tv_nsec / 1000000);
122
fprintf(stderr, "Executed %s in %ld ms\n", arg, ms);
123
}
124
}
125
free(buf);
126
127
return errors;
128
}
129
130