aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-06-25 15:43:52 +0200
committerDmitry Vyukov <dvyukov@google.com>2024-06-25 13:58:54 +0000
commitdc5564eb36462b29de4a0dbf85ef9f91df2eecca (patch)
treebe71aec17a1289b7cba876dfec19d86bf6d1955f /executor
parent707e48e60aa33a49ef5c753466930f70227a7d21 (diff)
executor: prohibit malloc/calloc via linter
We include a number of C++ headers in the runnner. On FreeBSD some of them mention malloc, and our defines break the build. Use the style test to check only our files for these things.
Diffstat (limited to 'executor')
-rw-r--r--executor/common.h2
-rw-r--r--executor/common_test.h2
-rw-r--r--executor/executor.cc14
-rw-r--r--executor/style_test.go37
4 files changed, 39 insertions, 16 deletions
diff --git a/executor/common.h b/executor/common.h
index 243d388c2..a38768536 100644
--- a/executor/common.h
+++ b/executor/common.h
@@ -53,7 +53,7 @@ typedef signed int ssize_t;
#endif
NORETURN void doexit(int status)
{
- _exit(status);
+ _exit(status); // prevent linter warning: doexit()
for (;;) {
}
}
diff --git a/executor/common_test.h b/executor/common_test.h
index 67585be9a..c5f7f5bca 100644
--- a/executor/common_test.h
+++ b/executor/common_test.h
@@ -31,7 +31,7 @@ static long syz_errno(volatile long v)
// syz_exit(status int32)
static long syz_exit(volatile long status)
{
- _exit(status);
+ doexit(status);
return 0;
}
#endif
diff --git a/executor/executor.cc b/executor/executor.cc
index a4ea17f47..cf80d7491 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -62,18 +62,6 @@ typedef unsigned int uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
-// exit/_exit do not necessary work (e.g. if fuzzer sets seccomp filter that prohibits exit_group).
-// Use doexit instead. We must redefine exit to something that exists in stdlib,
-// because some standard libraries contain "using ::exit;", but has different signature.
-#define exit vsnprintf
-
-// Dynamic memory allocation reduces test reproducibility across different libc versions and kernels.
-// malloc will cause unspecified number of additional mmap's at unspecified locations.
-// For small objects prefer stack allocations, for larger -- either global objects (this may have
-// issues with concurrency), or controlled mmaps, or make the fuzzer allocate memory.
-#define malloc do_not_use_malloc
-#define calloc do_not_use_calloc
-
// Note: zircon max fd is 256.
// Some common_OS.h files know about this constant for RLIMIT_NOFILE.
const int kMaxFd = 250;
@@ -1440,7 +1428,7 @@ void copyin_int(char* addr, uint64 val, uint64 bf, uint64 bf_off, uint64 bf_len)
const uint64 shift = bf_off;
#endif
x = (x & ~BITMASK(shift, bf_len)) | ((val << shift) & BITMASK(shift, bf_len));
- debug_verbose("copyin_int<%zu>: new x=0x%llx\n", sizeof(T), (uint64)x);
+ debug_verbose("copyin_int<%zu>: x=0x%llx\n", sizeof(T), (uint64)x);
*(T*)addr = swap(x, sizeof(T), bf);
}
diff --git a/executor/style_test.go b/executor/style_test.go
index c5f7177b2..42f99c412 100644
--- a/executor/style_test.go
+++ b/executor/style_test.go
@@ -19,7 +19,8 @@ func TestExecutorMistakes(t *testing.T) {
suppression string
message string
tests []string
- commonOnly bool
+ commonOnly bool // only applies to common*.h files
+ fuzzerOnly bool // only applies to files used during fuzzing
}{
{
pattern: `\)\n\t*(debug|debug_dump_data)\(`,
@@ -151,6 +152,36 @@ if (foo) {
`#ifdef SYZ_EXECUTOR_USES_FORK_SERVER`,
},
},
+ {
+ // Dynamic memory allocation reduces test reproducibility across
+ // different libc versions and kernels. Malloc will cause unspecified
+ // number of additional mmap's at unspecified locations.
+ // For small objects prefer stack allocations, for larger -- either global
+ // objects (this may have issues with concurrency), or controlled mmaps.
+ fuzzerOnly: true,
+ pattern: `(malloc|calloc|operator new)\(|new [a-zA-Z]`,
+ message: "Don't use standard allocation functions," +
+ " they disturb address space and issued syscalls",
+ suppression: `// `,
+ tests: []string{
+ `malloc(10)`,
+ `malloc(sizeof(int))`,
+ `calloc(sizeof T, n)`,
+ `operator new(10)`,
+ `new int`,
+ },
+ },
+ {
+ // Exit/_exit do not necessary work (e.g. if fuzzer sets seccomp
+ // filter that prohibits exit_group). Use doexit instead.
+ pattern: `exit\(`,
+ suppression: `doexit\(|syz_exit`,
+ message: "Don't use [_]exit, use doexit/exitf/fail instead",
+ tests: []string{
+ `_exit(1)`,
+ `exit(FAILURE)`,
+ },
+ },
}
for _, check := range checks {
re := regexp.MustCompile(check.pattern)
@@ -160,6 +191,7 @@ if (foo) {
}
}
}
+ runnerFiles := regexp.MustCompile(`(executor_runner|conn|shmem|files)\.h`)
for _, file := range executorFiles(t) {
data, err := os.ReadFile(file)
if err != nil {
@@ -169,6 +201,9 @@ if (foo) {
if check.commonOnly && !strings.Contains(file, "common") {
continue
}
+ if check.fuzzerOnly && runnerFiles.MatchString(file) {
+ continue
+ }
re := regexp.MustCompile(check.pattern)
supp := regexp.MustCompile(check.suppression)
for _, match := range re.FindAllIndex(data, -1) {