diff options
| -rw-r--r-- | executor/common_linux.h | 31 | ||||
| -rw-r--r-- | pkg/csource/generated.go | 29 |
2 files changed, 50 insertions, 10 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h index 9558bdb7d..98339194f 100644 --- a/executor/common_linux.h +++ b/executor/common_linux.h @@ -2967,6 +2967,7 @@ static int setup_loop_device(unsigned char* data, unsigned long size, const char loopfd = open(loopname, O_RDWR); if (loopfd == -1) { err = errno; + debug("setup_loop_device: open failed: %d\n", errno); goto error_close_memfd; } if (ioctl(loopfd, LOOP_SET_FD, memfd)) { @@ -2994,6 +2995,24 @@ error: errno = err; return -1; } + +#if SYZ_EXECUTOR || __NR_syz_mount_image + +static void reset_loop_device(const char* loopname) +{ + int loopfd = open(loopname, O_RDWR); + if (loopfd == -1) { + debug("reset_loop_device: open failed: %d\n", errno); + return; + } + if (ioctl(loopfd, LOOP_CLR_FD, 0)) { + debug("reset_loop_device: LOOP_CLR_FD failed: %d\n", errno); + } + close(loopfd); +} + +#endif + #endif #if SYZ_EXECUTOR || __NR_syz_read_part_table @@ -3067,7 +3086,7 @@ static long syz_mount_image( volatile long image) { unsigned char* data = (unsigned char*)image; - int res = -1, err = 0, loopfd = -1, need_loop_device = !!size; + int res = -1, err = 0, need_loop_device = !!size; char* mount_opts = (char*)optsarg; char* target = (char*)dir; char* fs = (char*)fsarg; @@ -3075,12 +3094,16 @@ static long syz_mount_image( char loopname[64]; if (need_loop_device) { + int loopfd; // Some filesystems (e.g. FUSE) do not need a backing device or // filesystem image. memset(loopname, 0, sizeof(loopname)); snprintf(loopname, sizeof(loopname), "/dev/loop%llu", procid); if (setup_loop_device(data, size, loopname, &loopfd) == -1) return -1; + // If BLK_DEV_WRITE_MOUNTED is set, we won't be able to mount() + // while holding the loop device fd. + close(loopfd); source = loopname; } @@ -3137,10 +3160,8 @@ static long syz_mount_image( } error_clear_loop: - if (need_loop_device) { - ioctl(loopfd, LOOP_CLR_FD, 0); - close(loopfd); - } + if (need_loop_device) + reset_loop_device(loopname); errno = err; return res; } diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go index dbb18a811..7d817e290 100644 --- a/pkg/csource/generated.go +++ b/pkg/csource/generated.go @@ -7100,6 +7100,7 @@ static int setup_loop_device(unsigned char* data, unsigned long size, const char loopfd = open(loopname, O_RDWR); if (loopfd == -1) { err = errno; + debug("setup_loop_device: open failed: %d\n", errno); goto error_close_memfd; } if (ioctl(loopfd, LOOP_SET_FD, memfd)) { @@ -7127,6 +7128,24 @@ error: errno = err; return -1; } + +#if SYZ_EXECUTOR || __NR_syz_mount_image + +static void reset_loop_device(const char* loopname) +{ + int loopfd = open(loopname, O_RDWR); + if (loopfd == -1) { + debug("reset_loop_device: open failed: %d\n", errno); + return; + } + if (ioctl(loopfd, LOOP_CLR_FD, 0)) { + debug("reset_loop_device: LOOP_CLR_FD failed: %d\n", errno); + } + close(loopfd); +} + +#endif + #endif #if SYZ_EXECUTOR || __NR_syz_read_part_table @@ -7188,7 +7207,7 @@ static long syz_mount_image( volatile long image) { unsigned char* data = (unsigned char*)image; - int res = -1, err = 0, loopfd = -1, need_loop_device = !!size; + int res = -1, err = 0, need_loop_device = !!size; char* mount_opts = (char*)optsarg; char* target = (char*)dir; char* fs = (char*)fsarg; @@ -7196,10 +7215,12 @@ static long syz_mount_image( char loopname[64]; if (need_loop_device) { + int loopfd; memset(loopname, 0, sizeof(loopname)); snprintf(loopname, sizeof(loopname), "/dev/loop%llu", procid); if (setup_loop_device(data, size, loopname, &loopfd) == -1) return -1; + close(loopfd); source = loopname; } @@ -7250,10 +7271,8 @@ static long syz_mount_image( } error_clear_loop: - if (need_loop_device) { - ioctl(loopfd, LOOP_CLR_FD, 0); - close(loopfd); - } + if (need_loop_device) + reset_loop_device(loopname); errno = err; return res; } |
