diff options
| author | Hrutvik Kanabar <hrutvik@google.com> | 2022-10-27 14:32:27 +0000 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2022-11-21 11:06:14 +0100 |
| commit | dd8fa7b2240ece698be6604a8fa8ce05f82ce0b0 (patch) | |
| tree | 086975ab4c2b3e4557ad87cf72696a9726691d50 /executor/common_linux.h | |
| parent | 8cc0c5c595cd14fb40a0052bbedd7ff3e96f64c8 (diff) | |
executor: update to match the new `syz_mount_image` call
Update the executor to handle the new `syz_mount_image`/`syz_part_table`
pseudo-syscalls. It now expects compressed images, and decompresses
them using the new `common_zlib.h` header file before mounting.
Diffstat (limited to 'executor/common_linux.h')
| -rw-r--r-- | executor/common_linux.h | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h index 10f693815..e0537e062 100644 --- a/executor/common_linux.h +++ b/executor/common_linux.h @@ -2885,6 +2885,7 @@ static long syz_genetlink_get_family_id(volatile long name, volatile long sock_a #endif #if SYZ_EXECUTOR || __NR_syz_mount_image || __NR_syz_read_part_table +#include "common_zlib.h" #include <errno.h> #include <fcntl.h> #include <linux/loop.h> @@ -2892,17 +2893,11 @@ static long syz_genetlink_get_family_id(volatile long name, volatile long sock_a #include <sys/stat.h> #include <sys/types.h> -struct fs_image_segment { - void* data; - uintptr_t size; - uintptr_t offset; -}; - // Setup the loop device needed for mounting a filesystem image. Takes care of // creating and initializing the underlying file backing the loop device and // returns the fds to the file and device. // Returns 0 on success, -1 otherwise. -static int setup_loop_device(long unsigned size, long unsigned nsegs, struct fs_image_segment* segs, const char* loopname, int* memfd_p, int* loopfd_p) +static int setup_loop_device(long unsigned size, long unsigned compressed_size, unsigned char* data, const char* loopname, int* memfd_p, int* loopfd_p) { int err = 0, loopfd = -1; int memfd = syscall(__NR_memfd_create, "syzkaller", 0); @@ -2914,10 +2909,11 @@ static int setup_loop_device(long unsigned size, long unsigned nsegs, struct fs_ err = errno; goto error_close_memfd; } - for (size_t i = 0; i < nsegs; i++) { - if (pwrite(memfd, segs[i].data, segs[i].size, segs[i].offset) < 0) { - debug("setup_loop_device: pwrite[%zu] failed: %d\n", i, errno); - } + + err = puff_zlib_to_file(data, compressed_size, memfd, size); + if (err) { + debug("setup_loop_device: could not decompress data: %d\n", err); + goto error_close_memfd; } loopfd = open(loopname, O_RDWR); @@ -2953,15 +2949,15 @@ error: #endif #if SYZ_EXECUTOR || __NR_syz_read_part_table -// syz_read_part_table(size intptr, nsegs len[segments], segments ptr[in, array[fs_image_segment]]) -static long syz_read_part_table(volatile unsigned long size, volatile unsigned long nsegs, volatile long segments) +// syz_read_part_table(size intptr, size_compressed len[img], img ptr[in, compressed_image]) +static long syz_read_part_table(volatile unsigned long size, volatile unsigned long compressed_size, volatile long image) { - struct fs_image_segment* segs = (struct fs_image_segment*)segments; + unsigned char* data = (unsigned char*)image; int err = 0, res = -1, loopfd = -1, memfd = -1; char loopname[64]; snprintf(loopname, sizeof(loopname), "/dev/loop%llu", procid); - if (setup_loop_device(size, nsegs, segs, loopname, &memfd, &loopfd) == -1) + if (setup_loop_device(size, compressed_size, data, loopname, &memfd, &loopfd) == -1) return -1; struct loop_info64 info; @@ -3004,16 +3000,28 @@ error_clear_loop: #include <string.h> #include <sys/mount.h> -// syz_mount_image(fs ptr[in, string[disk_filesystems]], dir ptr[in, filename], size intptr, nsegs len[segments], segments ptr[in, array[fs_image_segment]], flags flags[mount_flags], opts ptr[in, fs_options[vfat_options]], chdir bool8) fd_dir -// fs_image_segment { -// data ptr[in, array[int8]] -// size len[data, intptr] -// offset intptr -// } -static long syz_mount_image(volatile long fsarg, volatile long dir, volatile unsigned long size, volatile unsigned long nsegs, volatile long segments, volatile long flags, volatile long optsarg, volatile long change_dir) -{ - struct fs_image_segment* segs = (struct fs_image_segment*)segments; - int res = -1, err = 0, loopfd = -1, memfd = -1, need_loop_device = !!segs; +// syz_mount_image( +// fs ptr[in, string[fs]], +// dir ptr[in, filename], +// size intptr, +// size_compressed len[img], +// flags flags[mount_flags], +// opts ptr[in, fs_options], +// chdir bool8, +// img ptr[in, compressed_image] +// ) fd_dir +static long syz_mount_image( + volatile long fsarg, + volatile long dir, + volatile unsigned long size, + volatile unsigned long compressed_size, + volatile long flags, + volatile long optsarg, + volatile long change_dir, + volatile long image) +{ + unsigned char* data = (unsigned char*)image; + int res = -1, err = 0, loopfd = -1, memfd = -1, need_loop_device = !!compressed_size; char* mount_opts = (char*)optsarg; char* target = (char*)dir; char* fs = (char*)fsarg; @@ -3025,7 +3033,7 @@ static long syz_mount_image(volatile long fsarg, volatile long dir, volatile uns // filesystem image. memset(loopname, 0, sizeof(loopname)); snprintf(loopname, sizeof(loopname), "/dev/loop%llu", procid); - if (setup_loop_device(size, nsegs, segs, loopname, &memfd, &loopfd) == -1) + if (setup_loop_device(size, compressed_size, data, loopname, &memfd, &loopfd) == -1) return -1; source = loopname; } @@ -3050,7 +3058,7 @@ static long syz_mount_image(volatile long fsarg, volatile long dir, volatile uns // and if two parallel executors mounts fs with the same uuid, second mount fails. strcat(opts, ",nouuid"); } - debug("syz_mount_image: size=%llu segs=%llu loop='%s' dir='%s' fs='%s' flags=%llu opts='%s'\n", (uint64)size, (uint64)nsegs, loopname, target, fs, (uint64)flags, opts); + debug("syz_mount_image: size=%llu compressed_size=%llu loop='%s' dir='%s' fs='%s' flags=%llu opts='%s'\n", (uint64)size, (uint64)compressed_size, loopname, target, fs, (uint64)flags, opts); #if SYZ_EXECUTOR cover_reset(0); #endif |
