lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200731122112.11263-17-nao.horiguchi@gmail.com>
Date:   Fri, 31 Jul 2020 12:21:12 +0000
From:   nao.horiguchi@...il.com
To:     linux-mm@...ck.org
Cc:     mhocko@...nel.org, akpm@...ux-foundation.org,
        mike.kravetz@...cle.com, osalvador@...e.de, tony.luck@...el.com,
        david@...hat.com, aneesh.kumar@...ux.vnet.ibm.com,
        zeil@...dex-team.ru, cai@....pw, naoya.horiguchi@....com,
        linux-kernel@...r.kernel.org
Subject: [PATCH v5 16/16] mm,hwpoison: double-check page count in __get_any_page()

From: Naoya Horiguchi <naoya.horiguchi@....com>

Soft offlining could fail with EIO due to the race condition with
hugepage migration. This issuse became visible due to the change by
previous patch that makes soft offline handler take page refcount
by its own.  We have no way to directly pin zero refcount page, and
the page considered as a zero refcount page could be allocated just
after the first check.

This patch adds the second check to find the race and gives us
chance to handle it more reliably.

Reported-by: Qian Cai <cai@....pw>
Signed-off-by: Naoya Horiguchi <naoya.horiguchi@....com>
---
 mm/memory-failure.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git v5.8-rc7-mmotm-2020-07-27-18-18/mm/memory-failure.c v5.8-rc7-mmotm-2020-07-27-18-18_patched/mm/memory-failure.c
index 6f242a194c64..b2753ce2b85b 100644
--- v5.8-rc7-mmotm-2020-07-27-18-18/mm/memory-failure.c
+++ v5.8-rc7-mmotm-2020-07-27-18-18_patched/mm/memory-failure.c
@@ -1694,6 +1694,9 @@ static int __get_any_page(struct page *p, unsigned long pfn)
 		} else if (is_free_buddy_page(p)) {
 			pr_info("%s: %#lx free buddy page\n", __func__, pfn);
 			ret = 0;
+		} else if (page_count(p)) {
+			/* raced with allocation */
+			ret = -EBUSY;
 		} else {
 			pr_info("%s: %#lx: unknown zero refcount page type %lx\n",
 				__func__, pfn, p->flags);
@@ -1710,6 +1713,9 @@ static int get_any_page(struct page *page, unsigned long pfn)
 {
 	int ret = __get_any_page(page, pfn);
 
+	if (ret == -EBUSY)
+		ret = __get_any_page(page, pfn);
+
 	if (ret == 1 && !PageHuge(page) &&
 	    !PageLRU(page) && !__PageMovable(page)) {
 		/*
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ