Hi, We found a data race in linux kernel 5.3.11 that we are able to reproduce in x86 under specific interleavings. Currently, we are not sure about the consequence of this race so we would like to confirm with the community if this is a harmful bug. ------------------------------------------ Writer site /tmp/tmp.B7zb7od2zE-5.3.11/extract/linux-5.3.11/block/ioctl.c:573 553 case BLKPBSZGET: /* get block device physical block size */ 554 return put_uint(arg, bdev_physical_block_size(bdev)); 555 case BLKIOMIN: 556 return put_uint(arg, bdev_io_min(bdev)); 557 case BLKIOOPT: 558 return put_uint(arg, bdev_io_opt(bdev)); 559 case BLKALIGNOFF: 560 return put_int(arg, bdev_alignment_offset(bdev)); 561 case BLKDISCARDZEROES: 562 return put_uint(arg, 0); 563 case BLKSECTGET: 564 max_sectors = min_t(unsigned int, USHRT_MAX, 565 queue_max_sectors(bdev_get_queue(bdev))); 566 return put_ushort(arg, max_sectors); 567 case BLKROTATIONAL: 568 return put_ushort(arg, !blk_queue_nonrot(bdev_get_queue(bdev))); 569 case BLKRASET: 570 case BLKFRASET: 571 if(!capable(CAP_SYS_ADMIN)) 572 return -EACCES; ==> 573 bdev->bd_bdi->ra_pages = (arg * 512) / PAGE_SIZE; 574 return 0; 575 case BLKBSZSET: 576 return blkdev_bszset(bdev, mode, argp); 577 case BLKPG: 578 return blkpg_ioctl(bdev, argp); 579 case BLKRRPART: 580 return blkdev_reread_part(bdev); 581 case BLKGETSIZE: 582 size = i_size_read(bdev->bd_inode); 583 if ((size >> 9) > ~0UL) 584 return -EFBIG; 585 return put_ulong(arg, size >> 9); 586 case BLKGETSIZE64: 587 return put_u64(arg, i_size_read(bdev->bd_inode)); 588 case BLKTRACESTART: 589 case BLKTRACESTOP: 590 case BLKTRACESETUP: 591 case BLKTRACETEARDOWN: 592 return blk_trace_ioctl(bdev, cmd, argp); 593 case IOC_PR_REGISTER: ------------------------------------------ Reader site /tmp/tmp.B7zb7od2zE-5.3.11/extract/linux-5.3.11/mm/fadvise.c:79 66 /* 67 * Careful about overflows. Len == 0 means "as much as possible". Use 68 * unsigned math because signed overflows are undefined and UBSan 69 * complains. 70 */ 71 endbyte = (u64)offset + (u64)len; 72 if (!len || endbyte < len) 73 endbyte = -1; 74 else 75 endbyte--; /* inclusive */ 76 77 switch (advice) { 78 case POSIX_FADV_NORMAL: ==> 79 file->f_ra.ra_pages = bdi->ra_pages; 80 spin_lock(&file->f_lock); 81 file->f_mode &= ~FMODE_RANDOM; 82 spin_unlock(&file->f_lock); 83 break; 84 case POSIX_FADV_RANDOM: 85 spin_lock(&file->f_lock); 86 file->f_mode |= FMODE_RANDOM; 87 spin_unlock(&file->f_lock); 88 break; 89 case POSIX_FADV_SEQUENTIAL: 90 file->f_ra.ra_pages = bdi->ra_pages * 2; 91 spin_lock(&file->f_lock); 92 file->f_mode &= ~FMODE_RANDOM; 93 spin_unlock(&file->f_lock); 94 break; 95 case POSIX_FADV_WILLNEED: 96 /* First and last PARTIAL page! */ 97 start_index = offset >> PAGE_SHIFT; 98 end_index = endbyte >> PAGE_SHIFT; ------------------------------------------ Writer calling trace - ksys_ioctl -- do_vfs_ioctl --- vfs_ioctl ---- blkdev_ioctl ------------------------------------------ Reader calling trace - ksys_fadvise64_64 -- vfs_fadvise --- generic_fadvise Thanks, Sishuai