From patchwork Sat Aug 22 09:53:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Muchun Song X-Patchwork-Id: 11731077 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B57A3109B for ; Sat, 22 Aug 2020 09:53:54 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 7C36420825 for ; Sat, 22 Aug 2020 09:53:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=bytedance-com.20150623.gappssmtp.com header.i=@bytedance-com.20150623.gappssmtp.com header.b="Hy08vYzb" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7C36420825 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=bytedance.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 7B24C6B009E; Sat, 22 Aug 2020 05:53:53 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 763F36B009F; Sat, 22 Aug 2020 05:53:53 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 6795B6B00A0; Sat, 22 Aug 2020 05:53:53 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0140.hostedemail.com [216.40.44.140]) by kanga.kvack.org (Postfix) with ESMTP id 536766B009E for ; Sat, 22 Aug 2020 05:53:53 -0400 (EDT) Received: from smtpin13.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with ESMTP id 0E028180AD81A for ; Sat, 22 Aug 2020 09:53:53 +0000 (UTC) X-FDA: 77177743146.13.cars46_3900d0e27041 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin13.hostedemail.com (Postfix) with ESMTP id D875C18140B60 for ; Sat, 22 Aug 2020 09:53:52 +0000 (UTC) X-Spam-Summary: 1,0,0,ece8d7a3997cd4fd,d41d8cd98f00b204,songmuchun@bytedance.com,,RULES_HIT:41:355:379:541:800:960:973:988:989:1260:1311:1314:1345:1437:1515:1535:1543:1711:1730:1747:1777:1792:2198:2199:2393:2559:2562:2731:2895:3138:3139:3140:3141:3142:3354:3865:3866:3867:3868:3870:3871:3872:4117:4250:4321:5007:6261:6653:7208:7903:8660:9113:9165:10004:11026:11473:11658:11914:12043:12291:12296:12297:12438:12517:12519:12555:12679:12895:12986:13148:13161:13229:13230:13870:13894:13972:14093:14096:14181:14394:14721:21063:21080:21444:21451:21627:21939:21990:30003:30012:30054:30070,0,RBL:209.85.216.67:@bytedance.com:.lbl8.mailshell.net-62.14.0.100 66.201.201.201;04y8ij9b6twm84rtpmcxjtcb7w43doc4uqknbsemet8r49dbm4njicpj41zagdd.bt7x6abiacck97kn4ujf4t455ru7uepzcb6cdxx1ddrq338z9dcs4wrx9184t17.1-lbl8.mailshell.net-223.238.255.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:25,LUA_SUMMARY:none X-HE-Tag: cars46_3900d0e27041 X-Filterd-Recvd-Size: 6146 Received: from mail-pj1-f67.google.com (mail-pj1-f67.google.com [209.85.216.67]) by imf12.hostedemail.com (Postfix) with ESMTP for ; Sat, 22 Aug 2020 09:53:52 +0000 (UTC) Received: by mail-pj1-f67.google.com with SMTP id mt12so1867879pjb.4 for ; Sat, 22 Aug 2020 02:53:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=AA4QvqZ8G3UUgWk56L6siBEVYBlQ7DKtEof4BU/gmnM=; b=Hy08vYzbJ2PXLCKeaQ8gMOUe5NEBsJHKUF3pXyca6ilV/ucXow/JiUg6qZKy2iL14I 4gM6qgv9d3Hpktgt722p6TTGFt9m5EXNQWFQafd65aD8q5URNVlW4HuD/16xYbKayopp ppWSbM5gpm2h9jQRzRfPHuYv/ChyvWGH8OfGw2uD3QLz9ZSrPvrSKxrGK12c1/Ve2YEv ydDNukJRr3Fp2rWaQX/jLpgaFtKouvt9pvF/qC7uxQcnpvKiUh0FIuuDU/JY3dBA77Ak +xaQ5ef9Ten+QwSHX+Y9gdq+4py32DSzTve84iV272hi//du1s++RPXnNKIMwLBVwEGa pl2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=AA4QvqZ8G3UUgWk56L6siBEVYBlQ7DKtEof4BU/gmnM=; b=Fs9jtecuaaLL7wnni2uKCjJUefO09f9qN0ZlVliW3UCTTFwSuhC0O135ZxjewCBunN dSCTBZkfoIT0x0Exm+hyKKRpA3/MUh7Z9E+Q8ZHxwich7BprS776n7wbwVdBf0hqrdLn ZVQkHalCarkENmOG1EQCrHyVmBg5ljp3jFwjVCwXwlqbgN9/ZrCQ2z324H9iYiY0tyor mMtr0ylQPA0duHavJR5TaCgNy0PBvglwkADUE2ifYmJhk2T1bX1wW4K957liCzKcXjtU FZT88QncR2LLNc85gWKTrwVmaGVNUgmDdL/pg7awLI5/A2l+k+vE3SZhRR+Jcjye5FMq aCVA== X-Gm-Message-State: AOAM530bqiJscGnCNP6/ZrEvhPF6EpRf2AnA4wAjizoOyeEg1m35+jrd +p67pG1uNExKqj98hpCtarZlRA== X-Google-Smtp-Source: ABdhPJwCdC0vX5RwrRTQazcUNEUWzmuBbBvU1mkKSWh2/76IuEPrmpkdMhhiFvoPI3tn7Nm5ZeXcFw== X-Received: by 2002:a17:902:b714:: with SMTP id d20mr5636180pls.103.1598090031269; Sat, 22 Aug 2020 02:53:51 -0700 (PDT) Received: from localhost.localdomain ([103.136.220.72]) by smtp.gmail.com with ESMTPSA id a13sm4972397pfo.49.2020.08.22.02.53.46 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 22 Aug 2020 02:53:50 -0700 (PDT) From: Muchun Song To: mike.kravetz@oracle.com, akpm@linux-foundation.org Cc: npiggin@suse.de, agl@us.ibm.com, ak@linux.intel.com, nacc@us.ibm.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Muchun Song Subject: [PATCH] mm/hugetlb: Fix a race between hugetlb sysctl handlers Date: Sat, 22 Aug 2020 17:53:28 +0800 Message-Id: <20200822095328.61306-1-songmuchun@bytedance.com> X-Mailer: git-send-email 2.21.0 (Apple Git-122) MIME-Version: 1.0 X-Rspamd-Queue-Id: D875C18140B60 X-Spamd-Result: default: False [0.00 / 100.00] X-Rspamd-Server: rspam03 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: There is a race between the assignment of `table->data` and write value to the pointer of `table->data` in the __do_proc_doulongvec_minmax(). Fix this by duplicating the `table`, and only update the duplicate of it. And introduce a helper of proc_hugetlb_doulongvec_minmax() to simplify the code. The following oops was seen: BUG: kernel NULL pointer dereference, address: 0000000000000000 #PF: supervisor instruction fetch in kernel mode #PF: error_code(0x0010) - not-present page Code: Bad RIP value. ... Call Trace: ? set_max_huge_pages+0x3da/0x4f0 ? alloc_pool_huge_page+0x150/0x150 ? proc_doulongvec_minmax+0x46/0x60 ? hugetlb_sysctl_handler_common+0x1c7/0x200 ? nr_hugepages_store+0x20/0x20 ? copy_fd_bitmaps+0x170/0x170 ? hugetlb_sysctl_handler+0x1e/0x20 ? proc_sys_call_handler+0x2f1/0x300 ? unregister_sysctl_table+0xb0/0xb0 ? __fd_install+0x78/0x100 ? proc_sys_write+0x14/0x20 ? __vfs_write+0x4d/0x90 ? vfs_write+0xef/0x240 ? ksys_write+0xc0/0x160 ? __ia32_sys_read+0x50/0x50 ? __close_fd+0x129/0x150 ? __x64_sys_write+0x43/0x50 ? do_syscall_64+0x6c/0x200 ? entry_SYSCALL_64_after_hwframe+0x44/0xa9 Fixes: e5ff215941d5 ("hugetlb: multiple hstates for multiple page sizes") Signed-off-by: Muchun Song --- mm/hugetlb.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index a301c2d672bf..818d6125af49 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -3454,6 +3454,23 @@ static unsigned int allowed_mems_nr(struct hstate *h) } #ifdef CONFIG_SYSCTL +static int proc_hugetlb_doulongvec_minmax(struct ctl_table *table, int write, + void *buffer, size_t *length, + loff_t *ppos, unsigned long *out) +{ + struct ctl_table dup_table; + + /* + * In order to avoid races with __do_proc_doulongvec_minmax(), we + * can duplicate the @table and alter the duplicate of it. + */ + dup_table = *table; + dup_table.data = out; + dup_table.maxlen = sizeof(unsigned long); + + return proc_doulongvec_minmax(&dup_table, write, buffer, length, ppos); +} + static int hugetlb_sysctl_handler_common(bool obey_mempolicy, struct ctl_table *table, int write, void *buffer, size_t *length, loff_t *ppos) @@ -3465,9 +3482,8 @@ static int hugetlb_sysctl_handler_common(bool obey_mempolicy, if (!hugepages_supported()) return -EOPNOTSUPP; - table->data = &tmp; - table->maxlen = sizeof(unsigned long); - ret = proc_doulongvec_minmax(table, write, buffer, length, ppos); + ret = proc_hugetlb_doulongvec_minmax(table, write, buffer, length, ppos, + &tmp); if (ret) goto out; @@ -3510,9 +3526,8 @@ int hugetlb_overcommit_handler(struct ctl_table *table, int write, if (write && hstate_is_gigantic(h)) return -EINVAL; - table->data = &tmp; - table->maxlen = sizeof(unsigned long); - ret = proc_doulongvec_minmax(table, write, buffer, length, ppos); + ret = proc_hugetlb_doulongvec_minmax(table, write, buffer, length, ppos, + &tmp); if (ret) goto out;