From d6f3385b1a3f2fba8e14d6794bece1dcdd9e479e Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Wed, 12 Jan 2022 14:40:51 +0000 Subject: all: add syz_clone() and syz_clone3() pseudo calls As was pointed out in #2921, the current approach of limiting the number of pids per process does not work on all Linux-based kernels. We could just treat fork, clone and clone3 in a special way (e.g. exit on a zero return). However, in that case we also need to sanitize the arguments for clone and clone3 - if CLONE_VM is passed and stack is 0, the forked child processes (threads) will become nearly unindentifiable and will corrupt syz-executor's memory. While we could sanitize clone's arguments, we cannot do so for clone3 - nothing can guarantee that they will not be changed concurrently. Instead of calling those syscalls directly, introduce a special pseudo syscall syz_clone3. It copies and sanitizes the arguments and then executes clone3 (or fork, if we're on an older kernel) in such a way so as to prevent fork bombs from happening. Also introduce syz_clone() to still be able to fuzz it on older systems. --- sys/linux/sys.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'sys/linux/sys.txt') diff --git a/sys/linux/sys.txt b/sys/linux/sys.txt index fd934f976..8664e09a8 100644 --- a/sys/linux/sys.txt +++ b/sys/linux/sys.txt @@ -293,9 +293,14 @@ utimes(filename ptr[in, filename], times ptr[in, itimerval]) futimesat(dir fd_dir, pathname ptr[in, filename], times ptr[in, itimerval]) utimensat(dir fd_dir, pathname ptr[in, filename], times ptr[in, itimerval], flags flags[utimensat_flags]) -fork() pid (breaks_returns) -clone(flags flags[clone_flags], sp buffer[in], parentid ptr[out, int32], childtid ptr[out, int32], tls buffer[in]) (breaks_returns) -clone3(args ptr[in, clone_args], size bytesize[args]) pid (breaks_returns) +# Small trick - syzkaller cannot give the proper stack pointer to clone(), but we can do it with the aid of pseudo syscalls. +syz_clone(flags flags[clone_flags], stack buffer[in], stack_len bytesize[stack], parentid ptr[out, int32], childtid ptr[out, int32], tls buffer[in]) pid + +syz_clone3(args ptr[in, clone_args], size bytesize[args]) pid + +# We need these disabled definitions to simplify the presence and the NR checking. +clone(flags flags[clone_flags], sp buffer[in], parentid ptr[out, int32], childtid ptr[out, int32], tls buffer[in]) (breaks_returns, disabled) +clone3(args ptr[in, clone_args], size bytesize[args]) pid (breaks_returns, disabled) clone_args { flags flags[clone3_flags, int64] -- cgit mrf-deployment