The patch checks for this condition of NULL pointer for the buffer_head returned from page_buffers() and also a check placed within the list traversal loop for next buffer_head structs. crash scenario: The buffer_head returned from page_buffers() is not checked in block_invalidatepage_range function. The struct buffer_head* pointer returned by page_buffers(page) was 0x0, although this page had its private flag PG_private bit set and was expected to have buffer_head structs attached.The NULL pointer buffer_head was dereferenced in block_invalidatepage_range function at bh->b_size, where bh returned by page_buffers(page) was 0x0. The stack frames were truncate_inode_page() => do_invalidatepage_range() => xfs_vm_invalidatepage() => [exception RIP: block_invalidatepage_range+132] The inode for truncate in this case was valid and had proper inode.i_state = 0x20 - FREEING and had a valid mapped address space to xfs. And the struct page in context of block_invalidatepage_range() had its page flag PG_private set but the page.private was 0x0. So page_buffers(page) returned 0x0 and hence the crash. This patch performs NULL pointer check for returned buffer_head. Applies to 3.16 and later kernels. Signed-off-by: Monthero Ronald <rhmcruiser@xxxxxxxxx> --- fs/buffer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/buffer.c b/fs/buffer.c index eba6e4f..fa80cf4 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1541,6 +1541,7 @@ void block_invalidatepage(struct page *page, unsigned int offset, BUG_ON(stop > PAGE_CACHE_SIZE || stop < length); head = page_buffers(page); + BUG_ON(!head); bh = head; do { unsigned int next_off = curr_off + bh->b_size; @@ -1559,6 +1560,7 @@ void block_invalidatepage(struct page *page, unsigned int offset, discard_buffer(bh); curr_off = next_off; bh = next; + BUG_ON(!bh); } while (bh != head); /* -- 1.8.3.1