linux/drivers/block
David Rientjes def52acc90 mm: close PageTail race
commit 668f9abbd4 upstream.

Commit bf6bddf192 ("mm: introduce compaction and migration for
ballooned pages") introduces page_count(page) into memory compaction
which dereferences page->first_page if PageTail(page).

This results in a very rare NULL pointer dereference on the
aforementioned page_count(page).  Indeed, anything that does
compound_head(), including page_count() is susceptible to racing with
prep_compound_page() and seeing a NULL or dangling page->first_page
pointer.

This patch uses Andrea's implementation of compound_trans_head() that
deals with such a race and makes it the default compound_head()
implementation.  This includes a read memory barrier that ensures that
if PageTail(head) is true that we return a head page that is neither
NULL nor dangling.  The patch then adds a store memory barrier to
prep_compound_page() to ensure page->first_page is set.

This is the safest way to ensure we see the head page that we are
expecting, PageTail(page) is already in the unlikely() path and the
memory barriers are unfortunately required.

Hugetlbfs is the exception, we don't enforce a store memory barrier
during init since no race is possible.

Signed-off-by: David Rientjes <rientjes@google.com>
Cc: Holger Kiehl <Holger.Kiehl@dwd.de>
Cc: Christoph Lameter <cl@linux.com>
Cc: Rafael Aquini <aquini@redhat.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-04-03 12:01:05 -07:00
..
aoe mm: close PageTail race 2014-04-03 12:01:05 -07:00
drbd Merge branch 'for-3.10/drivers' of git://git.kernel.dk/linux-block 2013-05-08 11:51:05 -07:00
mtip32xx mtip32xx: Correctly handle bio->bi_idx != 0 conditions 2013-05-15 10:09:05 +02:00
paride block_device_operations->release() should return void 2013-05-07 02:16:21 -04:00
rsxx rsxx: remove unused variable 2013-03-26 14:48:12 -06:00
xen-blkback xen/blkback: fix reference counting 2013-12-04 10:56:25 -08:00
amiflop.c block_device_operations->release() should return void 2013-05-07 02:16:21 -04:00
ataflop.c block_device_operations->release() should return void 2013-05-07 02:16:21 -04:00
brd.c block: fix a probe argument to blk_register_region 2013-11-29 11:11:50 -08:00
cciss_cmd.h
cciss_scsi.c cciss: switch to ->show_info() 2013-04-09 14:13:19 -04:00
cciss_scsi.h
cciss.c cciss: fix info leak in cciss_ioctl32_passthru() 2013-10-13 16:08:28 -07:00
cciss.h
cpqarray.c cpqarray: fix info leak in ida_locked_ioctl() 2013-10-13 16:08:28 -07:00
cpqarray.h
cryptoloop.c
DAC960.c procfs: new helper - PDE_DATA(inode) 2013-04-09 14:13:32 -04:00
DAC960.h
floppy.c Merge branch 'for-3.10/core' of git://git.kernel.dk/linux-block 2013-05-08 10:13:35 -07:00
hd.c
ida_cmd.h
ida_ioctl.h
Kconfig block: IBM RamSan 70/80 branding changes. 2013-03-11 19:53:55 +01:00
loop.c loop: fix crash when using unassigned loop device 2013-12-04 10:56:20 -08:00
Makefile NVMe: Add nvme-scsi.c 2013-03-28 14:50:49 -04:00
mg_disk.c Merge branch 'for-3.10/drivers' of git://git.kernel.dk/linux-block 2013-05-08 11:51:05 -07:00
nbd.c nbd: correct disconnect behavior 2013-07-21 18:21:29 -07:00
nvme-core.c NVMe: Add MSI support 2013-05-31 11:45:52 -04:00
nvme-scsi.c NVMe: Fix a signedness bug in nvme_trans_modesel_get_mp 2013-05-17 09:10:38 -04:00
osdblk.c
pktcdvd.c pktcdvd: silence static checker warning 2013-05-29 15:36:22 +02:00
ps3disk.c Drivers: block: remove __dev* attributes. 2013-01-03 15:57:15 -08:00
ps3vram.c procfs: new helper - PDE_DATA(inode) 2013-04-09 14:13:32 -04:00
rbd_types.h rbd: get rid of RBD_MAX_SEG_NAME_LEN 2012-12-17 08:37:29 -06:00
rbd.c rbd: fix error handling from rbd_snap_name() 2014-01-09 12:24:26 -08:00
smart1,2.h
sunvdc.c sunvdc: Fix off-by-one in generic_request(). 2013-02-14 11:49:01 -08:00
swim_asm.S
swim.c block_device_operations->release() should return void 2013-05-07 02:16:21 -04:00
swim3.c block_device_operations->release() should return void 2013-05-07 02:16:21 -04:00
sx8.c
umem.c Drivers: block: remove __dev* attributes. 2013-01-03 15:57:15 -08:00
umem.h
virtio_blk.c virtio_blk: remove nents member. 2013-03-20 15:44:58 +10:30
xen-blkfront.c xen-blkfront: handle backend CLOSED without CLOSING 2014-02-22 12:41:25 -08:00
xsysace.c drivers/block/xsysace.c: fix id with missing port-number 2013-05-24 16:22:50 -07:00
z2ram.c block_device_operations->release() should return void 2013-05-07 02:16:21 -04:00