From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id A7574C3ABB9 for ; Mon, 5 May 2025 19:31:27 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 499AD6B0099; Mon, 5 May 2025 15:31:24 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 448D06B009A; Mon, 5 May 2025 15:31:24 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 3387F6B009B; Mon, 5 May 2025 15:31:24 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 149906B0099 for ; Mon, 5 May 2025 15:31:24 -0400 (EDT) Received: from smtpin03.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id 12EEB5B6BF for ; Mon, 5 May 2025 19:31:26 +0000 (UTC) X-FDA: 83409848172.03.7D51BF9 Received: from m16.mail.163.com (m16.mail.163.com [117.135.210.2]) by imf01.hostedemail.com (Postfix) with ESMTP id DD9064000A for ; Mon, 5 May 2025 19:31:22 +0000 (UTC) Authentication-Results: imf01.hostedemail.com; dkim=pass header.d=163.com header.s=s110527 header.b=bWfprKyx; dmarc=pass (policy=none) header.from=163.com; spf=pass (imf01.hostedemail.com: domain of 00107082@163.com designates 117.135.210.2 as permitted sender) smtp.mailfrom=00107082@163.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1746473484; a=rsa-sha256; cv=none; b=J/BTxcdytT95ZvtJJJYbFUNak8oQXWY1uZ9w+Pm1kpz1R7ZRsxp4Xyo1cO96Q5uX3IunTl waqTtdNN41P0E0FMpDpA/sUZvjEbkyLoxywNrAFQRuDFjcZnxL/1VICXT8DjVgL6YKCfud CW/3vHGBY48d2yINpcoRnj7K7LJLmFo= ARC-Authentication-Results: i=1; imf01.hostedemail.com; dkim=pass header.d=163.com header.s=s110527 header.b=bWfprKyx; dmarc=pass (policy=none) header.from=163.com; spf=pass (imf01.hostedemail.com: domain of 00107082@163.com designates 117.135.210.2 as permitted sender) smtp.mailfrom=00107082@163.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1746473484; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=MMxsBxI5NR7NYwNT1QUEgUcE2MVKZMz9ZlRNrU8ptlM=; b=2Llk0ROPXaDaWT/0T64qmjWpeCYQVjKPnAf8Y/0j4C0RqiNV5kiKz/89NVJtNj30XiCs7o dOlLzzraTeEvGnT5cUIVKyNZRVvVJix6ZAcJog6OJB+7WtK6SubBB1yuz/WlJ8fodc4U9D 73VwKNiKURKqXlXfmjlO3livaykgR+k= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Subject:Date:Message-Id:MIME-Version; bh=MMxsB xI5NR7NYwNT1QUEgUcE2MVKZMz9ZlRNrU8ptlM=; b=bWfprKyx2oFGVSkso5OVT JBdyCg/k1zpSghy8XdvHTd0CwBrwHZ+Yn9MTaZ0e/XUrDWxKiSIAzRknCXxlB8/K LxtYjAsmtiBG2HqU47FWQFSqfUi1F5BawwIPpKquflpunolIgRgntahfPrDhsMjG Ye/Mezj+Zfk9yzCtCTRoBs= Received: from localhost.localdomain (unknown []) by gzga-smtp-mtada-g1-4 (Coremail) with SMTP id _____wDnbxjcERloOELhEQ--.50443S4; Tue, 06 May 2025 03:30:48 +0800 (CST) From: David Wang <00107082@163.com> To: akpm@linux-foundation.org, vbabka@suse.cz, surenb@google.com, mhocko@suse.com, jackmanb@google.com, hannes@cmpxchg.org, ziy@nvidia.com Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, David Wang <00107082@163.com> Subject: [PATCH v3] mm/codetag: move tag retrieval back upfront in __free_pages() Date: Tue, 6 May 2025 03:30:34 +0800 Message-Id: <20250505193034.91682-1-00107082@163.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID:_____wDnbxjcERloOELhEQ--.50443S4 X-Coremail-Antispam: 1Uf129KBjvJXoWxuF1kWw1kCryxGr1fXF4Dtwb_yoWrGF4kpF WjqF18Ca98JFy5KFWvyr4q9r13Jws7KaykAFW3K34rZF13tr40kFykJryavF18CFy8AFyv krsrKw4Ykw1Ut3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0piL0ePUUUUU= X-Originating-IP: [111.35.191.17] X-CM-SenderInfo: qqqrilqqysqiywtou0bp/xtbB0gpEqmgZDbphLAAAs9 X-Rspamd-Queue-Id: DD9064000A X-Stat-Signature: ee4rb1p1suq61zkhn1ksj4r95em84awe X-Rspam-User: X-Rspamd-Server: rspam08 X-HE-Tag: 1746473482-143680 X-HE-Meta: U2FsdGVkX1/bO2/IRf+EDkQ/sk/M+auGS1cSzKrRwwqejhxHvtMCPcddF/qWo09yZTPKZB1LX5RCjwTZI8O3W/dyqknnG0/nHWQd8FOgrQQ9sCsbh43qtg90saxQa++ckQUA7CpcJJXO2QgDG7JiGhR6zssT8QxYcjpad57eat0iYQY4STuO5ADm+R7ooHf6BIcoY7QaeH6LdIP0U6IqLAUgCXgRTA8wQ60NLkz/5/x0MaHx74Yreda8UaID7ST61r3szQTWWNOyVWo5INrswBVMOFAfFyuCw3cy6b+P8kc+tbmW8uj/At3hVS3Jsr5yYK/PCXTSb2tlyeWcqk8T32DA++yDJHvGuyRCVRFxNRKTZvZyks8Vee0DbR3ViKwiXar/efQaQEXWdKL1FnmKMJ6DcuR9hAS6ugF6rmPabIdfXen2IqMviPp9tvhQBP6o32e9KbipxMuqkUw3tBze2IfceedVGmVUSHLqTP/0TDtyfuX+KOlsia9ylxvxmsSPRP9XGPA4Lit1/Av60KtA4/Hy2vrLD2sHxlOPxB8rghDstp2Gc6RYGt/RLbsPMbIsvfTfa7EmO5EiwE5M8DgB24JPVaeux+slAXxxaT2h6drEe5zkc62LUj1bk4xPyvm6iphe+13XVX1J23itRUE6onQUf0svDinOUvMmMmLYqwNtX9s0gc5tZ7BTnEw/Z1B6BVKHhl51VDQfRPrawbCIJLpnQ5LD8RkGJ6EH5XUpKpwCgrLrSGi5koqjK0rsuz1WVrl6aMgPa7njbJWcaURyQ/oIAIey+yMslCXwG4L78TOntzoc3I+ild7tVkgzXwzFlwojdstZd+kTSs0Gnamw2thBp4ulKcX1CLVuA9FTEpkss6XaD6pu6UxFx4yIhL46aBBRnjf5D0d9wmiuPfjL0Y0P2AXIlw4toz4mo/kFhGEkiBfQVtUNWP03jTpgzFC7lnu/8j9QCMG/mt1V+LJ Pb1aF5ah 1G5fDtOZ5klaUfPHU2uMn1JU7+9HZApYRWdqXFcRvhWhGY3yeCOe5cGAqmOQVQRAKQXPvlYBv5JAj2OHG0COticsxSdNL7Xfdnwc+oUh6ZCxJf8lyhc0GEem2q0dfrPEqct1yV0ob4TbuPdgHMqHjmNhCWSA/innYLxgq2X74gN9smDx+Nv51o+4717sduWSkLQuMmL+A3+44gudU8pJHByRc6C53s52uwrp74q7mH5cNVEvIBkIQC5cgLTgcKMjq19+elhcJ/eLoTsEAJ65wOU7bp4db7N3eWRuBuuSUtj98MS+Ut8mVqtjt2M44mMrMM9nu2Lkwbehv8Bfz8xt2Yplt35riKXUYwBICIQ0TTGKbkC7mnHFg6XV+g/FpzppioBVu6BYMIlm3/JpI5ex29fIX5uPwTYbXUpuoEaKKqn2bfStvmZt04+UgqQ== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Commit 51ff4d7486f0 ("mm: avoid extra mem_alloc_profiling_enabled() checks") introduces a possible use-after-free scenario, when page is non-compound, page[0] could be released by other thread right after put_page_testzero failed in current thread, pgalloc_tag_sub_pages afterwards would manipulate an invalid page for accounting remaining pages: [timeline] [thread1] [thread2] | alloc_page non-compound V | get_page, rf counter inc V | in ___free_pages | put_page_testzero fails V | put_page, page released V | in ___free_pages, | pgalloc_tag_sub_pages | manipulate an invalid page V Restore __free_pages() to its state before, retrieve alloc tag beforehand. Fixes: 51ff4d7486f0 ("mm: avoid extra mem_alloc_profiling_enabled() checks") Signed-off-by: David Wang <00107082@163.com> --- include/linux/pgalloc_tag.h | 8 ++++++++ mm/page_alloc.c | 15 ++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/include/linux/pgalloc_tag.h b/include/linux/pgalloc_tag.h index c74077977830..8a7f4f802c57 100644 --- a/include/linux/pgalloc_tag.h +++ b/include/linux/pgalloc_tag.h @@ -188,6 +188,13 @@ static inline struct alloc_tag *__pgalloc_tag_get(struct page *page) return tag; } +static inline struct alloc_tag *pgalloc_tag_get(struct page *page) +{ + if (mem_alloc_profiling_enabled()) + return __pgalloc_tag_get(page); + return NULL; +} + void pgalloc_tag_split(struct folio *folio, int old_order, int new_order); void pgalloc_tag_swap(struct folio *new, struct folio *old); @@ -199,6 +206,7 @@ static inline void clear_page_tag_ref(struct page *page) {} static inline void alloc_tag_sec_init(void) {} static inline void pgalloc_tag_split(struct folio *folio, int old_order, int new_order) {} static inline void pgalloc_tag_swap(struct folio *new, struct folio *old) {} +static inline struct alloc_tag *pgalloc_tag_get(struct page *page) { return NULL; } #endif /* CONFIG_MEM_ALLOC_PROFILING */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 5669baf2a6fe..1b00e14a9780 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1151,14 +1151,9 @@ static inline void pgalloc_tag_sub(struct page *page, unsigned int nr) __pgalloc_tag_sub(page, nr); } -static inline void pgalloc_tag_sub_pages(struct page *page, unsigned int nr) +/* When tag is not NULL, assuming mem_alloc_profiling_enabled */ +static inline void pgalloc_tag_sub_pages(struct alloc_tag *tag, unsigned int nr) { - struct alloc_tag *tag; - - if (!mem_alloc_profiling_enabled()) - return; - - tag = __pgalloc_tag_get(page); if (tag) this_cpu_sub(tag->counters->bytes, PAGE_SIZE * nr); } @@ -1168,7 +1163,7 @@ static inline void pgalloc_tag_sub_pages(struct page *page, unsigned int nr) static inline void pgalloc_tag_add(struct page *page, struct task_struct *task, unsigned int nr) {} static inline void pgalloc_tag_sub(struct page *page, unsigned int nr) {} -static inline void pgalloc_tag_sub_pages(struct page *page, unsigned int nr) {} +static inline void pgalloc_tag_sub_pages(struct alloc_tag *tag, unsigned int nr) {} #endif /* CONFIG_MEM_ALLOC_PROFILING */ @@ -5065,11 +5060,13 @@ static void ___free_pages(struct page *page, unsigned int order, { /* get PageHead before we drop reference */ int head = PageHead(page); + /* get alloc tag in case the page is released by others */ + struct alloc_tag *tag = pgalloc_tag_get(page); if (put_page_testzero(page)) __free_frozen_pages(page, order, fpi_flags); else if (!head) { - pgalloc_tag_sub_pages(page, (1 << order) - 1); + pgalloc_tag_sub_pages(tag, (1 << order) - 1); while (order-- > 0) __free_frozen_pages(page + (1 << order), order, fpi_flags); -- 2.39.2