• L
    drbd: fix access of unallocated pages and kernel panic · 1b6f1974
    Lars Ellenberg 提交于
    BUG: unable to handle kernel NULL pointer dereference at (null)
    ...
     [<d1e17561>] ? _drbd_bm_set_bits+0x151/0x240 [drbd]
     [<d1e236f8>] ? receive_bitmap+0x4f8/0xbc0 [drbd]
    
    This fixes an off-by-one error in the receive_bitmap() path,
    if run-length encoded bitmap transfer is enabled.
    
    If the bitmap is an exact multiple of PAGE_SIZE, which means the visible
    capacity of the drbd device is an exact multiple of 128 MiB (for 4k page
    size), and bitmap compression (use-rle) is enabled (which became default
    with 8.4), and the very last bit is dirty and reported in an rle
    comressed bitmap packet, we ended up trying to kmap_atomic a page pointer
    that does not exist (bitmap->bm_pages[last index + 1]).
    
    bug introduced by:
        Date:   Fri Jul 24 15:33:24 2009 +0200
        set bits: optimize for complete last word, fix off-by-one-word corner case
    
    made effective by:
        Date:   Thu Dec 16 00:32:38 2010 +0100
        drbd: get rid of unused debug code
    
        Long time ago, we had paranoia code in the bitmap that allocated one
        extra word, assigned a magic value, and checked on every occasion that
        the magic value was still unchanged.
    
        That debug code is unused, the extra long word complicates code a bit.
        Get rid of it.
    
    No-one triggered this bug in the last few years, because a large subset
    of our userbase is unaffected:
     * typically the last few blocks of a device are not modified
       frequently, and remain unset
     * use-rle was disabled by default in drbd < 8.4
     * those with slightly "odd" device sizes, or
     * drbd internal meta data (which will skew the device size slightly,
       thus makes it harder to have a bug relevant device size)
    Signed-off-by: NPhilipp Reisner <philipp.reisner@linbit.com>
    Signed-off-by: NLars Ellenberg <lars.ellenberg@linbit.com>
    1b6f1974
drbd_bitmap.c 46.9 KB