1 * Flesh out the child ops some more
2 - Add more things that a real program would do.
3 - add all the ops things like fsx do.
4 - do file ops on a bunch of trinity test files
6 - open->mmap->access mem->close
8 - pick random elevator alg for all queues
9 - fork-and-dirty mappings
10 - Ability to mark some ops as 'NEEDS_ROOT'.
11 - Move the drop privs code from main to just before we start a new child.
13 * maps.c improvements:
14 - Sometimes generate overlapping addresses/lengths when we have ARG_ADDRESS/ARG_ADDRESS2 pairs
15 - make sure ARG_ADDRESS only uses addresses from this list, and audit all other mmap/malloc uses
17 - munge lengths when handing them out.
19 (we do this already, but don't track it properly)
21 - mprotect parts of a map
22 will need to somehow track what pages are RO/RW etc
23 - keep track of holes when munmap'd
25 (store original len, and current len)
27 * munge_process() on child startup
28 - replace fork() with random clone()
29 - run children in different namespaces, personalities.
33 - needs filename globbing for some ioctls
34 - Sanitise routines for more ioctls
36 - Maybe just make the ioctl's be NEED_ROOT child ops
38 * Some debugging enhancements.
39 - dump_child_state(childno), to debug a specific child. (Dump all a childs shm arrays)
40 - Make -D use a separate debug log file
43 - If we have logging disabled, we don't have a clue really what happened if we taint, and exit.
44 Store a ringbuffer of the last few syscalls, and dump it before we exit.
45 - Compare timestamp that taint was noticed at, ignore all later.
46 - Do taint watching in the child loop too.
49 need to work around segv's when we do things like mmap->post and register null maps.
51 * Rewrite the fd code.
52 - register_fd interface for each of the fd-*.c files.
53 setup_fds() iterates over registered fd producers.
54 Then get_new_random_fd should become a lot cleaner.
55 - kill off NR_FILE_FDS
56 - open some files in the child too after forking.
57 - this requires a child-local fd mapping table.
58 Maybe we can then reduce the size of the shared shm->file_fds
59 - When requesting an fd, occasionally generate a new one.
60 - Could we do the nftw walks in parallel ?
61 That would speed up startup a lot. Though would need to pass list back up to main thread somehow.
62 - support for multiple victim file parameters
63 - When picking a random path, instead of treating the pool of paths as one thing,
64 treat it as multiple (/dev, /sys, /proc). And then do a 1-in-3 chance
65 of getting one of those. Right now, because there are 5-6 digits worth of /proc & /sys,
66 they dominate over the /dev entries.
67 - more fd 'types' (fanotify_init)
68 - Add a parameter to specify only certain fd types. --fds=sockets,files
70 * Change regeneration code.
71 - Instead of every n syscalls, make it happen after 15 minutes (but with a minimum of n syscalls)
73 * Pretty-print improvements.
74 - decode fd number -> filename in output
75 - decode addresses when printing them out to print 'page_rand+4' instead of a hex address.
76 - ->decode_argN functions to print decoded flags etc.
79 * Watchdog improvements
80 - in main loop, check watchdog is still alive
83 * filename related issues.
85 Similar to the socketcache. Create on startup, then on loading, invalidate entries
86 that aren't present (/proc/pid etc).
87 This should improve reproducability in some cases. Right now, when a syscall
88 says "open the 5231st filename in the list", it differs across runs because we're
89 rebuilding the list, and the system state means stuff moves around.
90 - Add a way to add a filter to filelist.
91 ie, something like --filter-files=*[0-9]* to ignore all files with numbers in them.
92 Maybe also make this a config file parser.
93 - Dump filelist to a logfile. (Perhaps this ties in with the idea above to cache the filelist?)
94 - blacklist filenames for victim path & /proc/self/exe
95 - make sure we don't call unlink() or rmdir() on them
96 - also need to watch /proc/$$/exe, look up using shm->pids.
97 - file list struct extensions
100 * Networking improvements.
101 - Rewrite socket generation.
102 Organise into (sorted) per-protocol buckets of linked-lists..
103 - Search buckets for dupes before adding.
104 - for syscalls that take a fd and a sockaddr, look up the triplet and match.
105 - Flesh out sockaddr/socket gen for all remaining protocols.
106 - setsockopt on network sockets when we regenerate
107 Disabled right now, because it causes some socket types to hang.
108 - specify an ip of a victim machine (Maybe also config file)
110 * Improve the ->post routine to walk a list of objects that we allocated during a
111 syscalls ->sanitise in a ->post method.
112 - On return from the syscall, we don't call the destructor immediately.
113 We pick a small random number, and do N other syscalls before we do the destruction.
114 This requires us to create a list of work to be done later, along with a pointer
115 to any allocated data.
116 - some ancillary data needs to be destroyed immediately after the syscall
117 (it's pointless keeping around mangled pathnames for eg).
118 For this, we just destroy it in ->post
119 - Right now ->sanitise routines have to pick either a map, or malloc itself and
120 do the right thing to free it in ->post. By tagging what the allocation type was in
121 generic-sanitise, we can do multiple types.
123 * Perform some checks on return from syscall
124 - check padding between struct members is zeroed.
126 * Output errno distribution on exit
128 * allow for multiple -G's (after there is more than 'vm')
130 * audit which syscalls never succeed, and write sanitise routines for them
132 * if a read() blocks and we get a kill from the watchdog, blacklist (close?) that fd/filename.
134 * Some of the syscalls marked AVOID are done so for good reason.
135 - Revisit fuzzing ptrace.
136 - It's disabled currently because of situations like..
137 child a traces child b
139 child b never proceeds, and doesn't get untraced.
141 * Further syscall annotation improvements
142 - Finish annotating syscall return types
144 * structured logging.
145 - To begin with, in parallel with existing text based logging.
146 - Basic premise is that we store records of each syscall in a manner that would
147 allow easier replay of logs.
148 - For eg, if a param is an fd, we store the type (socket/file/etc..)
149 as well as a pathname/socket triplet/whatever to create it.
150 - Eventually, kill off the text based logging, and replace it with
151 ./trinity --parselog=mylog.bin
152 - Done correctly, this should allow automated bisecting of replays.
153 - Different replay strategies:
154 - replay log in reverse order
155 - brute force replay using 1 call at a time from beginning of log + last syscall.
156 (possibly unnecessary if the above strategies are good enough)
157 - Once bisected, have a tool that can parse the binary log, and generate C.
158 - Would need a separate binary logfile for each child.
159 Because locking on a shared file would slow things down, and effectively single
160 thread things, unless the children pass things to a separate logger thread, which
161 has its own problems like potentially losing the last N syscalls if we crash)
162 - To begin with, just allow replay/bisect using one child process.
163 Synchronising threads across different runs may be complicated.
166 - syscall.c:syscall32() hide the assembly in a macro in arch-*.h and only do it
167 #ifdef HAVE_SYSCALL_32
168 - Move arch specific syscalls into syscalls/arch/
169 - Move addresses in get_interesting_value() to a function in per-arch headers.
171 * watch dmesg buffer for interesting kernel messages and halt if necessary. Lockdep for eg.
173 Sometimes we might want to read trinity state when we trigger a bad event.
175 * Blocked child improvements.
176 - if we find a blocking fd, check if it's a socket, and shutdown() it.
177 (tricky: we need to do the shutdown in the main process, and then tell other children)
179 * make -p take an arg for seconds