linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Mike Kravetz <mike.kravetz@oracle.com>,
	Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>,
	Michal Hocko <mhocko@kernel.org>, Hugh Dickins <hughd@google.com>,
	Andrea Arcangeli <aarcange@redhat.com>,
	"Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>,
	Davidlohr Bueso <dave@stgolabs.net>,
	Prakash Sangappa <prakash.sangappa@oracle.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 3.18 90/90] hugetlbfs: fix kernel BUG at fs/hugetlbfs/inode.c:444!
Date: Mon, 19 Nov 2018 17:30:12 +0100	[thread overview]
Message-ID: <20181119162634.181292799@linuxfoundation.org> (raw)
In-Reply-To: <20181119162620.585061184@linuxfoundation.org>

3.18-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mike Kravetz <mike.kravetz@oracle.com>

commit 5e41540c8a0f0e98c337dda8b391e5dda0cde7cf upstream.

This bug has been experienced several times by the Oracle DB team.  The
BUG is in remove_inode_hugepages() as follows:

	/*
	 * If page is mapped, it was faulted in after being
	 * unmapped in caller.  Unmap (again) now after taking
	 * the fault mutex.  The mutex will prevent faults
	 * until we finish removing the page.
	 *
	 * This race can only happen in the hole punch case.
	 * Getting here in a truncate operation is a bug.
	 */
	if (unlikely(page_mapped(page))) {
		BUG_ON(truncate_op);

In this case, the elevated map count is not the result of a race.
Rather it was incorrectly incremented as the result of a bug in the huge
pmd sharing code.  Consider the following:

 - Process A maps a hugetlbfs file of sufficient size and alignment
   (PUD_SIZE) that a pmd page could be shared.

 - Process B maps the same hugetlbfs file with the same size and
   alignment such that a pmd page is shared.

 - Process B then calls mprotect() to change protections for the mapping
   with the shared pmd. As a result, the pmd is 'unshared'.

 - Process B then calls mprotect() again to chage protections for the
   mapping back to their original value. pmd remains unshared.

 - Process B then forks and process C is created. During the fork
   process, we do dup_mm -> dup_mmap -> copy_page_range to copy page
   tables. Copying page tables for hugetlb mappings is done in the
   routine copy_hugetlb_page_range.

In copy_hugetlb_page_range(), the destination pte is obtained by:

	dst_pte = huge_pte_alloc(dst, addr, sz);

If pmd sharing is possible, the returned pointer will be to a pte in an
existing page table.  In the situation above, process C could share with
either process A or process B.  Since process A is first in the list,
the returned pte is a pointer to a pte in process A's page table.

However, the check for pmd sharing in copy_hugetlb_page_range is:

	/* If the pagetables are shared don't copy or take references */
	if (dst_pte == src_pte)
		continue;

Since process C is sharing with process A instead of process B, the
above test fails.  The code in copy_hugetlb_page_range which follows
assumes dst_pte points to a huge_pte_none pte.  It copies the pte entry
from src_pte to dst_pte and increments this map count of the associated
page.  This is how we end up with an elevated map count.

To solve, check the dst_pte entry for huge_pte_none.  If !none, this
implies PMD sharing so do not copy.

Link: http://lkml.kernel.org/r/20181105212315.14125-1-mike.kravetz@oracle.com
Fixes: c5c99429fa57 ("fix hugepages leak due to pagetable page sharing")
Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Prakash Sangappa <prakash.sangappa@oracle.com>
Cc: <stable@vger.kernel.org>
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>

---
 mm/hugetlb.c |   23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2576,7 +2576,7 @@ static int is_hugetlb_entry_hwpoisoned(p
 int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			    struct vm_area_struct *vma)
 {
-	pte_t *src_pte, *dst_pte, entry;
+	pte_t *src_pte, *dst_pte, entry, dst_entry;
 	struct page *ptepage;
 	unsigned long addr;
 	int cow;
@@ -2604,15 +2604,30 @@ int copy_hugetlb_page_range(struct mm_st
 			break;
 		}
 
-		/* If the pagetables are shared don't copy or take references */
-		if (dst_pte == src_pte)
+		/*
+		 * If the pagetables are shared don't copy or take references.
+		 * dst_pte == src_pte is the common case of src/dest sharing.
+		 *
+		 * However, src could have 'unshared' and dst shares with
+		 * another vma.  If dst_pte !none, this implies sharing.
+		 * Check here before taking page table lock, and once again
+		 * after taking the lock below.
+		 */
+		dst_entry = huge_ptep_get(dst_pte);
+		if ((dst_pte == src_pte) || !huge_pte_none(dst_entry))
 			continue;
 
 		dst_ptl = huge_pte_lock(h, dst, dst_pte);
 		src_ptl = huge_pte_lockptr(h, src, src_pte);
 		spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
 		entry = huge_ptep_get(src_pte);
-		if (huge_pte_none(entry)) { /* skip none entry */
+		dst_entry = huge_ptep_get(dst_pte);
+		if (huge_pte_none(entry) || !huge_pte_none(dst_entry)) {
+			/*
+			 * Skip if src entry none.  Also, skip in the
+			 * unlikely case dst entry !none as this implies
+			 * sharing with another vma.
+			 */
 			;
 		} else if (unlikely(is_hugetlb_entry_migration(entry) ||
 				    is_hugetlb_entry_hwpoisoned(entry))) {



  parent reply	other threads:[~2018-11-19 17:06 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-19 16:28 [PATCH 3.18 00/90] 3.18.126-stable review Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 01/90] bcache: fix miss key refill->end in writeback Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 02/90] jffs2: free jffs2_sb_info through jffs2_kill_sb() Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 03/90] pcmcia: Implement CLKRUN protocol disabling for Ricoh bridges Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 04/90] ALSA: ca0106: Disable IZD on SB0570 DAC to fix audio pops Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 05/90] x86/corruption-check: Fix panic in memory_corruption_check() when boot option without value is provided Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 06/90] sparc: Fix single-pcr perf event counter management Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 07/90] sparc: Throttle perf events properly Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 08/90] net: qla3xxx: Remove overflowing shift statement Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 09/90] selftests: ftrace: Add synthetic event syntax testcase Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 10/90] locking/lockdep: Fix debug_locks off performance problem Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 11/90] ataflop: fix error handling during setup Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 12/90] swim: fix cleanup on setup error Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 13/90] tun: Consistently configure generic netdev params via rtnetlink Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 14/90] perf tools: Free temporary sys string in read_event_files() Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 15/90] perf tools: Cleanup trace-event-info tdata leak Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 16/90] cpupower: Fix coredump on VMWare Greg Kroah-Hartman
2018-11-19 18:11   ` Prarit Bhargava
2018-11-20  8:49     ` Greg Kroah-Hartman
2018-11-19 16:28 ` [PATCH 3.18 17/90] mmc: sdhci-pci-o2micro: Add quirk for O2 Micro dev 0x8620 rev 0x01 Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 18/90] x86/olpc: Indicate that legacy PC XO-1 platform should not register RTC Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 19/90] x86: boot: Fix EFI stub alignment Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 20/90] kprobes: Return error if we fail to reuse kprobe instead of BUG_ON() Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 21/90] ath10k: schedule hardware restart if WMI command times out Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 22/90] scsi: esp_scsi: Track residual for PIO transfers Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 23/90] ext4: fix argument checking in EXT4_IOC_MOVE_EXT Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 24/90] usb: chipidea: Prevent unbalanced IRQ disable Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 25/90] uio: ensure class is registered before devices Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 26/90] scsi: lpfc: Correct soft lockup when running mds diagnostics Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 27/90] signal: Always deliver the kernels SIGKILL and SIGSTOP to a pid namespace init Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 28/90] net/ipv4: defensive cipso option parsing Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 29/90] jbd2: fix use after free in jbd2_log_do_checkpoint() Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 30/90] gfs2_meta: ->mount() can get NULL dev_name Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 31/90] ext4: initialize retries variable in ext4_da_write_inline_data_begin() Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 32/90] signal/GenWQE: Fix sending of SIGKILL Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 33/90] crypto: lrw - Fix out-of bounds access on counter overflow Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 34/90] ima: fix showing large violations or runtime_measurements_count Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 35/90] kbuild: fix kernel/bounds.c W=1 warning Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 36/90] iio: adc: at91: fix acking DRDY irq on simple conversions Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 37/90] iio: adc: at91: fix wrong channel number in triggered buffer mode Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 38/90] w1: omap-hdq: fix missing bus unregister at removal Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 39/90] smb3: allow stats which track session and share reconnects to be reset Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 40/90] smb3: do not attempt cifs operation in smb3 query info error path Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 41/90] smb3: on kerberos mount if server doesnt specify auth type use krb5 Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 42/90] printk: Fix panic caused by passing log_buf_len to command line Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 43/90] NFSv4.1: Fix the r/wsize checking Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 44/90] nfsd: Fix an Oops in free_session() Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 45/90] lockd: fix access beyond unterminated strings in prints Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 46/90] dm ioctl: harden copy_params()s copy_from_user() from malicious users Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 47/90] TC: Set DMA masks for devices Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 48/90] kgdboc: Passing ekgdboc to command line causes panic Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 49/90] media: em28xx: use a default format if TRY_FMT fails Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 50/90] media: em28xx: fix input name for Terratec AV 350 Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 51/90] media: em28xx: make v4l2-compliance happier by starting sequence on zero Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 52/90] Cramfs: fix abad comparison when wrap-arounds occur Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 53/90] dm: remove duplicate dm_get_live_table() in __dm_destroy() Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 54/90] tty: check name length in tty_find_polling_driver() Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 55/90] powerpc/nohash: fix undefined behaviour when testing page size support Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 56/90] drm/omap: fix memory barrier bug in DMM driver Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 57/90] media: pci: cx23885: handle adding to list failure Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 58/90] MIPS: kexec: Mark CPU offline before disabling local IRQ Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 59/90] powerpc/boot: Ensure _zimage_start is a weak symbol Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 60/90] media: tvp5150: fix width alignment during set_selection() Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 61/90] 9p: clear dangling pointers in p9stat_free Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 62/90] cdrom: fix improper type cast, which can leat to information leak Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 63/90] xtensa: fix boot parameters address translation Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 64/90] clk: s2mps11: Fix matching when built as module and DT node contains compatible Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 65/90] libceph: bump CEPH_MSG_MAX_DATA_LEN Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 66/90] mach64: fix display corruption on big endian machines Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 67/90] mach64: fix image corruption due to reading accelerator registers Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 68/90] ocfs2: fix a misuse a of brelse after failing ocfs2_check_dir_entry Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 69/90] mtd: docg3: dont set conflicting BCH_CONST_PARAMS option Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 70/90] termios, tty/tty_baudrate.c: fix buffer overrun Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 71/90] arch/alpha, termios: implement BOTHER, IBSHIFT and termios2 Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 72/90] ext4: add missing brelse() update_backups()s error path Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 73/90] ext4: add missing brelse() in set_flexbg_block_bitmap()s " Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 74/90] ext4: add missing brelse() add_new_gdb_meta_bg()s " Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 75/90] ext4: avoid potential extra brelse in setup_new_flex_group_blocks() Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 76/90] ext4: fix possible inode leak in the retry loop of ext4_resize_fs() Greg Kroah-Hartman
2018-11-19 16:29 ` [PATCH 3.18 77/90] ext4: avoid buffer leak in ext4_orphan_add() after prior errors Greg Kroah-Hartman
2018-11-19 16:30 ` [PATCH 3.18 78/90] ext4: fix missing cleanup if ext4_alloc_flex_bg_array() fails while resizing Greg Kroah-Hartman
2018-11-19 16:30 ` [PATCH 3.18 79/90] ext4: avoid possible double brelse() in add_new_gdb() on error path Greg Kroah-Hartman
2018-11-19 16:30 ` [PATCH 3.18 80/90] ext4: fix possible leak of sbi->s_group_desc_leak in " Greg Kroah-Hartman
2018-11-19 16:30 ` [PATCH 3.18 81/90] ext4: release bs.bh before re-using in ext4_xattr_block_find() Greg Kroah-Hartman
2018-11-19 16:30 ` [PATCH 3.18 82/90] ext4: fix buffer leak in ext4_xattr_move_to_block() on error path Greg Kroah-Hartman
2018-11-19 16:30 ` [PATCH 3.18 83/90] ext4: fix buffer leak in __ext4_read_dirblock() " Greg Kroah-Hartman
2018-11-19 16:30 ` [PATCH 3.18 84/90] mount: Retest MNT_LOCKED in do_umount Greg Kroah-Hartman
2018-11-19 16:30 ` [PATCH 3.18 85/90] mount: Dont allow copying MNT_UNBINDABLE|MNT_LOCKED mounts Greg Kroah-Hartman
2018-11-19 16:30 ` [PATCH 3.18 86/90] mount: Prevent MNT_DETACH from disconnecting locked mounts Greg Kroah-Hartman
2018-11-19 16:30 ` [PATCH 3.18 87/90] sunrpc: correct the computation for page_ptr when truncating Greg Kroah-Hartman
2018-11-19 16:30 ` [PATCH 3.18 88/90] fuse: fix leaked notify reply Greg Kroah-Hartman
2018-11-19 16:30 ` [PATCH 3.18 89/90] configfs: replace strncpy with memcpy Greg Kroah-Hartman
2018-11-19 16:30 ` Greg Kroah-Hartman [this message]
2018-11-20  0:09 ` [PATCH 3.18 00/90] 3.18.126-stable review shuah
2018-11-20  7:49   ` Greg Kroah-Hartman
2018-11-20 10:39 ` Harsh Shandilya
2018-11-20 11:16   ` Greg Kroah-Hartman
     [not found]     ` <D161C16F-60D6-4C60-B065-C780BD3DCF55@prjkt.io>
2018-11-20 16:40       ` Greg Kroah-Hartman
2018-11-20 16:58 ` Guenter Roeck
2018-11-20 20:38 ` Guenter Roeck
2018-11-21 10:37   ` Greg Kroah-Hartman
2018-11-21 23:40     ` Guenter Roeck
2018-11-22  6:30       ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181119162634.181292799@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=aarcange@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=dave@stgolabs.net \
    --cc=hughd@google.com \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhocko@kernel.org \
    --cc=mike.kravetz@oracle.com \
    --cc=n-horiguchi@ah.jp.nec.com \
    --cc=prakash.sangappa@oracle.com \
    --cc=stable@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).