• Brian Foster's avatar
    bcachefs: fix truncate overflow if folio is beyond EOF · 4ad6aa46
    Brian Foster authored
    generic/083 occasionally reproduces a panic caused by an overflow
    when accessing the bch_folio_sector array of the folio being
    processed by __bch2_truncate_folio(). The immediate cause of the
    overflow is that the folio offset is beyond i_size, and therefore
    the sector index calculation underflows on subtraction of the folio
    offset.
    
    One cause of this is mainly observed on nocow mounts. When nocow is
    enabled, fallocate performs physical block allocation (as opposed to
    block reservation in cow mode), which range_has_data() then
    interprets as valid data that requires partial zeroing on truncate.
    Therefore, if a post-eof zero range request lands across post-eof
    preallocated blocks, __bch2_truncate_folio() may actually create a
    post-eof folio in order to perform zeroing. To avoid this problem,
    update range_has_data() to filter out unwritten blocks from folio
    creation and partial zeroing.
    
    Even though we should never create folios beyond EOF like this, the
    mere existence of such folios is not necessarily a fatal error. Fix
    up the truncate code to warn about this condition and not overflow
    the sector array and possibly crash the system. The addition of this
    warning without the corresponding unwritten extent fix has shown
    that various other fstests are able to reproduce this problem fairly
    frequently, but often in ways that doesn't necessarily result in a
    kernel panic or a change in user observable behavior, and therefore
    the problem goes undetected.
    Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
    Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
    4ad6aa46
fs-io.c 93.5 KB