Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions executor/common_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -3032,6 +3032,22 @@ static void reset_loop_device(const char* loopname)

#endif

#if SYZ_EXECUTOR || __NR_syz_read_part_table || __NR_syz_mount_image
static int loopnr;

static int loop_get_free(void)
{
int ctlfd;

ctlfd = open("/dev/loop-control", O_RDWR);
if (ctlfd == -1)
return -1;
loopnr = ioctl(ctlfd, LOOP_CTL_GET_FREE);
close(ctlfd);
return loopnr;
}
#endif

#if SYZ_EXECUTOR || __NR_syz_read_part_table
// syz_read_part_table(size len[img], img ptr[in, compressed_image])
static long syz_read_part_table(volatile unsigned long size, volatile long image)
Expand All @@ -3040,7 +3056,10 @@ static long syz_read_part_table(volatile unsigned long size, volatile long image
int err = 0, res = -1, loopfd = -1;
char loopname[64];

snprintf(loopname, sizeof(loopname), "/dev/loop%llu", procid);
loopnr = loop_get_free();
if (loopnr == -1)
return -1;
snprintf(loopname, sizeof(loopname), "/dev/loop%d", loopnr);
if (setup_loop_device(data, size, loopname, &loopfd) == -1)
return -1;

Expand All @@ -3060,7 +3079,7 @@ static long syz_read_part_table(volatile unsigned long size, volatile long image
res = 0;
// If we managed to parse some partitions, symlink them into our work dir.
for (unsigned long i = 1, j = 0; i < 8; i++) {
snprintf(loopname, sizeof(loopname), "/dev/loop%llup%d", procid, (int)i);
snprintf(loopname, sizeof(loopname), "/dev/loop%dp%d", loopnr, (int)i);
struct stat statbuf;
if (stat(loopname, &statbuf) == 0) {
char linkname[64];
Expand Down Expand Up @@ -3112,10 +3131,14 @@ static long syz_mount_image(

if (need_loop_device) {
int loopfd;

// Some filesystems (e.g. FUSE) do not need a backing device or
// filesystem image.
loopnr = loop_get_free();
if (loopnr == -1)
return -1;
memset(loopname, 0, sizeof(loopname));
snprintf(loopname, sizeof(loopname), "/dev/loop%llu", procid);
snprintf(loopname, sizeof(loopname), "/dev/loop%d", loopnr);
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()
Expand Down Expand Up @@ -4850,7 +4873,7 @@ static void reset_loop()
{
#if SYZ_EXECUTOR || __NR_syz_mount_image || __NR_syz_read_part_table
char buf[64];
snprintf(buf, sizeof(buf), "/dev/loop%llu", procid);
snprintf(buf, sizeof(buf), "/dev/loop%d", loopnr);
int loopfd = open(buf, O_RDWR);
if (loopfd != -1) {
ioctl(loopfd, LOOP_CLR_FD, 0);
Expand Down