1 /*
2 american fuzzy lop++ - snapshot helpers routines
3 ------------------------------------------------
4
5 Originally written by Michal Zalewski
6
7 Forkserver design by Jann Horn <[email protected]>
8
9 Now maintained by Marc Heuse <[email protected]>,
10 Heiko Eißfeldt <[email protected]>,
11 Andrea Fioraldi <[email protected]>,
12 Dominik Maier <[email protected]>
13
14 Copyright 2016, 2017 Google Inc. All rights reserved.
15 Copyright 2019-2024 AFLplusplus Project. All rights reserved.
16
17 Licensed under the Apache License, Version 2.0 (the "License");
18 you may not use this file except in compliance with the License.
19 You may obtain a copy of the License at:
20
21 https://www.apache.org/licenses/LICENSE-2.0
22
23 */
24
25 // From AFL-Snapshot-LKM/include/afl_snapshot.h (must be kept synced)
26
27 #include <sys/ioctl.h>
28 #include <stdlib.h>
29 #include <fcntl.h>
30
31 #define AFL_SNAPSHOT_FILE_NAME "/dev/afl_snapshot"
32
33 #define AFL_SNAPSHOT_IOCTL_MAGIC 44313
34
35 #define AFL_SNAPSHOT_IOCTL_DO _IO(AFL_SNAPSHOT_IOCTL_MAGIC, 1)
36 #define AFL_SNAPSHOT_IOCTL_CLEAN _IO(AFL_SNAPSHOT_IOCTL_MAGIC, 2)
37 #define AFL_SNAPSHOT_EXCLUDE_VMRANGE \
38 _IOR(AFL_SNAPSHOT_IOCTL_MAGIC, 3, struct afl_snapshot_vmrange_args *)
39 #define AFL_SNAPSHOT_INCLUDE_VMRANGE \
40 _IOR(AFL_SNAPSHOT_IOCTL_MAGIC, 4, struct afl_snapshot_vmrange_args *)
41 #define AFL_SNAPSHOT_IOCTL_TAKE _IOR(AFL_SNAPSHOT_IOCTL_MAGIC, 5, int)
42 #define AFL_SNAPSHOT_IOCTL_RESTORE _IO(AFL_SNAPSHOT_IOCTL_MAGIC, 6)
43
44 // Trace new mmaped ares and unmap them on restore.
45 #define AFL_SNAPSHOT_MMAP 1
46 // Do not snapshot any page (by default all writeable not-shared pages
47 // are shanpshotted.
48 #define AFL_SNAPSHOT_BLOCK 2
49 // Snapshot file descriptor state, close newly opened descriptors
50 #define AFL_SNAPSHOT_FDS 4
51 // Snapshot registers state
52 #define AFL_SNAPSHOT_REGS 8
53 // Perform a restore when exit_group is invoked
54 #define AFL_SNAPSHOT_EXIT 16
55 // TODO(andrea) allow not COW snapshots (high perf on small processes)
56 // Disable COW, restore all the snapshotted pages
57 #define AFL_SNAPSHOT_NOCOW 32
58 // Do not snapshot Stack pages
59 #define AFL_SNAPSHOT_NOSTACK 64
60
61 struct afl_snapshot_vmrange_args {
62
63 unsigned long start, end;
64
65 };
66
67 static int afl_snapshot_dev_fd;
68
afl_snapshot_init(void)69 static int afl_snapshot_init(void) {
70
71 afl_snapshot_dev_fd = open(AFL_SNAPSHOT_FILE_NAME, 0);
72 return afl_snapshot_dev_fd;
73
74 }
75
afl_snapshot_exclude_vmrange(void * start,void * end)76 static void afl_snapshot_exclude_vmrange(void *start, void *end) {
77
78 struct afl_snapshot_vmrange_args args = {(unsigned long)start,
79 (unsigned long)end};
80 ioctl(afl_snapshot_dev_fd, AFL_SNAPSHOT_EXCLUDE_VMRANGE, &args);
81
82 }
83
afl_snapshot_include_vmrange(void * start,void * end)84 static void afl_snapshot_include_vmrange(void *start, void *end) {
85
86 struct afl_snapshot_vmrange_args args = {(unsigned long)start,
87 (unsigned long)end};
88 ioctl(afl_snapshot_dev_fd, AFL_SNAPSHOT_INCLUDE_VMRANGE, &args);
89
90 }
91
afl_snapshot_take(int config)92 static int afl_snapshot_take(int config) {
93
94 return ioctl(afl_snapshot_dev_fd, AFL_SNAPSHOT_IOCTL_TAKE, config);
95
96 }
97
afl_snapshot_do(void)98 static int afl_snapshot_do(void) {
99
100 return ioctl(afl_snapshot_dev_fd, AFL_SNAPSHOT_IOCTL_DO);
101
102 }
103
afl_snapshot_restore(void)104 static void afl_snapshot_restore(void) {
105
106 ioctl(afl_snapshot_dev_fd, AFL_SNAPSHOT_IOCTL_RESTORE);
107
108 }
109
afl_snapshot_clean(void)110 static void afl_snapshot_clean(void) {
111
112 ioctl(afl_snapshot_dev_fd, AFL_SNAPSHOT_IOCTL_CLEAN);
113
114 }
115
116