@@ -259,6 +259,16 @@ void SetFuzzedErrNo(FuzzedDataProvider& fuzzed_data_provider, const std::array<T
259
259
errno = fuzzed_data_provider.PickValueInArray (errnos);
260
260
}
261
261
262
+ /*
263
+ * Sets a fuzzed errno in the range [0, 133 (EHWPOISON)]. Can be used from functions emulating
264
+ * standard library functions that set errno, or in other contexts where the value of errno
265
+ * might be relevant for the execution path that will be taken.
266
+ */
267
+ inline void SetFuzzedErrNo (FuzzedDataProvider& fuzzed_data_provider) noexcept
268
+ {
269
+ errno = fuzzed_data_provider.ConsumeIntegralInRange <int >(0 , 133 );
270
+ }
271
+
262
272
/* *
263
273
* Returns a byte vector of specified size regardless of the number of remaining bytes available
264
274
* from the fuzzer. Pads with zero value bytes if needed to achieve the specified size.
@@ -345,6 +355,7 @@ class FuzzedFileProvider
345
355
346
356
FILE* open ()
347
357
{
358
+ SetFuzzedErrNo (m_fuzzed_data_provider);
348
359
if (m_fuzzed_data_provider.ConsumeBool ()) {
349
360
return nullptr ;
350
361
}
@@ -386,6 +397,7 @@ class FuzzedFileProvider
386
397
static ssize_t read (void * cookie, char * buf, size_t size)
387
398
{
388
399
FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
400
+ SetFuzzedErrNo (fuzzed_file->m_fuzzed_data_provider );
389
401
if (buf == nullptr || size == 0 || fuzzed_file->m_fuzzed_data_provider .ConsumeBool ()) {
390
402
return fuzzed_file->m_fuzzed_data_provider .ConsumeBool () ? 0 : -1 ;
391
403
}
@@ -404,6 +416,7 @@ class FuzzedFileProvider
404
416
static ssize_t write (void * cookie, const char * buf, size_t size)
405
417
{
406
418
FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
419
+ SetFuzzedErrNo (fuzzed_file->m_fuzzed_data_provider );
407
420
const ssize_t n = fuzzed_file->m_fuzzed_data_provider .ConsumeIntegralInRange <ssize_t >(0 , size);
408
421
if (AdditionOverflow (fuzzed_file->m_offset , (int64_t )n)) {
409
422
return fuzzed_file->m_fuzzed_data_provider .ConsumeBool () ? 0 : -1 ;
@@ -414,8 +427,9 @@ class FuzzedFileProvider
414
427
415
428
static int seek (void * cookie, int64_t * offset, int whence)
416
429
{
417
- assert (whence == SEEK_SET || whence == SEEK_CUR); // SEEK_END not implemented yet.
430
+ assert (whence == SEEK_SET || whence == SEEK_CUR || whence == SEEK_END);
418
431
FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
432
+ SetFuzzedErrNo (fuzzed_file->m_fuzzed_data_provider );
419
433
int64_t new_offset = 0 ;
420
434
if (whence == SEEK_SET) {
421
435
new_offset = *offset;
@@ -424,6 +438,12 @@ class FuzzedFileProvider
424
438
return -1 ;
425
439
}
426
440
new_offset = fuzzed_file->m_offset + *offset;
441
+ } else if (whence == SEEK_END) {
442
+ const int64_t n = fuzzed_file->m_fuzzed_data_provider .ConsumeIntegralInRange <int64_t >(0 , 4096 );
443
+ if (AdditionOverflow (n, *offset)) {
444
+ return -1 ;
445
+ }
446
+ new_offset = n + *offset;
427
447
}
428
448
if (new_offset < 0 ) {
429
449
return -1 ;
@@ -436,6 +456,7 @@ class FuzzedFileProvider
436
456
static int close (void * cookie)
437
457
{
438
458
FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
459
+ SetFuzzedErrNo (fuzzed_file->m_fuzzed_data_provider );
439
460
return fuzzed_file->m_fuzzed_data_provider .ConsumeIntegralInRange <int >(-1 , 0 );
440
461
}
441
462
};
0 commit comments