@@ -1230,16 +1230,14 @@ struct fs_image_segment {
#elif GOARCH_ppc64le
#define sys_memfd_create 360
#endif
#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)
static unsigned long fs_image_segment_check (unsigned long size, unsigned long nsegs, long segments)
{
char loopname[64 ], linkname[64 ];
int loopfd, err = 0 , res = -1 ;
unsigned long i, j;
// See the comment in syz_mount_image.
unsigned long i;
// Strictly saying we ought to do a nonfailing copyout of segments into a local var.
// But some filesystems have large number of segments (2000+),
// we can't allocate that much on stack and allocating elsewhere is problematic,
// so we just use the memory allocated by fuzzer.
struct fs_image_segment* segs = (struct fs_image_segment*)segments;
if (nsegs > IMAGE_MAX_SEGMENTS)
@@ -1255,6 +1253,18 @@ static long syz_read_part_table(volatile unsigned long size, volatile unsigned l
}
if (size > IMAGE_MAX_SIZE)
size = IMAGE_MAX_SIZE;
return size;
}
#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)
{
char loopname[64 ], linkname[64 ];
int loopfd, err = 0 , res = -1 ;
unsigned long i, j;
NONFAILING (size = fs_image_segment_check (size, nsegs, segments));
int memfd = syscall (sys_memfd_create, " syz_read_part_table" , 0 );
if (memfd == -1 ) {
err = errno;
@@ -1265,9 +1275,8 @@ static long syz_read_part_table(volatile unsigned long size, volatile unsigned l
goto error_close_memfd;
}
for (i = 0 ; i < nsegs; i++) {
if (pwrite (memfd, segs[i].data , segs[i].size , segs[i].offset ) < 0 ) {
debug (" syz_read_part_table: pwrite[%u ] failed: %d \n " , (int )i, errno);
}
struct fs_image_segment* segs = (struct fs_image_segment*)segments;
NONFAILING (pwrite (memfd, segs[i].data , segs[i].size , segs[i].offset ));
}
snprintf (loopname, sizeof (loopname), " /dev/loop%llu " , procid);
loopfd = open (loopname, O_RDWR);
@@ -1339,25 +1348,8 @@ static long syz_mount_image(volatile long fsarg, volatile long dir, volatile uns
char loopname[64 ], fs[32 ], opts[256 ];
int loopfd, err = 0 , res = -1 ;
unsigned long i;
// Strictly saying we ought to do a nonfailing copyout of segments into a local var.
// But some filesystems have large number of segments (2000+),
// we can't allocate that much on stack and allocating elsewhere is problematic,
// so we just use the memory allocated by fuzzer.
struct fs_image_segment* segs = (struct fs_image_segment*)segments;
if (nsegs > IMAGE_MAX_SEGMENTS)
nsegs = IMAGE_MAX_SEGMENTS;
for (i = 0 ; i < nsegs; i++) {
if (segs[i].size > IMAGE_MAX_SIZE)
segs[i].size = IMAGE_MAX_SIZE;
segs[i].offset %= IMAGE_MAX_SIZE;
if (segs[i].offset > IMAGE_MAX_SIZE - segs[i].size )
segs[i].offset = IMAGE_MAX_SIZE - segs[i].size ;
if (size < segs[i].offset + segs[i].offset )
size = segs[i].offset + segs[i].offset ;
}
if (size > IMAGE_MAX_SIZE)
size = IMAGE_MAX_SIZE;
NONFAILING (size = fs_image_segment_check (size, nsegs, segments));
int memfd = syscall (sys_memfd_create, " syz_mount_image" , 0 );
if (memfd == -1 ) {
err = errno;
@@ -1368,9 +1360,8 @@ static long syz_mount_image(volatile long fsarg, volatile long dir, volatile uns
goto error_close_memfd;
}
for (i = 0 ; i < nsegs; i++) {
if (pwrite (memfd, segs[i].data , segs[i].size , segs[i].offset ) < 0 ) {
debug (" syz_mount_image: pwrite[%u ] failed: %d \n " , (int )i, errno);
}
struct fs_image_segment* segs = (struct fs_image_segment*)segments;
NONFAILING (pwrite (memfd, segs[i].data , segs[i].size , segs[i].offset ));
}
snprintf (loopname, sizeof (loopname), " /dev/loop%llu " , procid);
loopfd = open (loopname, O_RDWR);