Received: by 2002:a05:6a10:1d13:0:0:0:0 with SMTP id pp19csp49440pxb; Tue, 24 Aug 2021 19:46:30 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy6qRTfD7y0Mpls0suyroNwRlA53dRWBvZk34cXpwbUaD8om90FmvKpkf+BvrlsdemEAHe1 X-Received: by 2002:a92:dd0e:: with SMTP id n14mr27528370ilm.224.1629859590234; Tue, 24 Aug 2021 19:46:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1629859590; cv=none; d=google.com; s=arc-20160816; b=lAGEWp24b/Plorl3VG94xnP2HT91yk0so5UpJbs31coYeB1D9pxmGO8wR2bTzZB4IQ r9JlcHCDJtztuZr2+frd6mIR5dN4+wOjh7PAaYattq+fo5wyGm2VS3fcyN1zVZCMkjHN 5Mz6VjVaLIUcXePUEyNz4p+DNLmC+rNUg85grTHR7m2qfXWe/jtcSX6uVS98UBGvvn6O mY5zcZyZD/pPSz54Yxfp1CLfIWdPLt1MJrGRzJFXcfkLzwo9FqI0/sqFVXBfwr9OP42U p7pRmATVzqJqOX+PodOXXJD2SNmdqIJwyK7+mScow56sYt3t5xDL/iAYp8eD8EmDtt9F 5c0Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:message-id:date:subject:cc:to:from :dkim-signature; bh=CTWJLTSJroYMndBn0PhkaK8v33nMScSCNsUYYunUuks=; b=DKqU5uaOJmVX8/yVV9gOmUKpz/2VonIX9A7YyBH2vaxPNRhxvqTMlWY3rj9dbClEoe 1sLEEq4KN7ENT02yG2wutOTz337kg3UYpzV2eM3AmLhIusagwku1Fg+2xAgUgAjDoRoS ZH6Hqdslja5qHDSeBk50/6GGGcdOYmixAdJNNyorRl1i3JRVOZqhbTDabVqzpmI++/ML zgBaIwG0FZ+3JNYEyrt8nEjMUwf3dUDEoGqIAOSRHuGG1E7/bV28MzaGzoZzvd2f+3RN gcUL3HtkJWMBXvUoBlfpGOijhQnFFz25A3cNvxmKufiQUbZAqDT91mvVIAUgDVgT+KLt 5nhw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=jkjgJ0Dy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id 10si17040044ilz.71.2021.08.24.19.46.17; Tue, 24 Aug 2021 19:46:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=jkjgJ0Dy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237384AbhHYCoj (ORCPT + 99 others); Tue, 24 Aug 2021 22:44:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48150 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235700AbhHYCoi (ORCPT ); Tue, 24 Aug 2021 22:44:38 -0400 Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9B17CC061757; Tue, 24 Aug 2021 19:43:53 -0700 (PDT) Received: by mail-pj1-x1029.google.com with SMTP id j10-20020a17090a94ca00b00181f17b7ef7so3149409pjw.2; Tue, 24 Aug 2021 19:43:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=CTWJLTSJroYMndBn0PhkaK8v33nMScSCNsUYYunUuks=; b=jkjgJ0Dyj4L9f9ubpsjVa2rPGugDKcxnMU0niNCT+QaDJ9bZsCzpX27icvQ89Dzxlq Et5mNoP+rSkXNo674nANqXcgXZ6ywtcyveGIbENDbmzhJdbVToseA5fzyedEbxAL3wda XDwtARgdhlT+VbFLQHoUcoThlgxmU8YyZ7vN0DVRctbmN9bRW9DjWR36v5HVLLz5KOgI 829vLbbxpsA+R7654sSImNaZYJtOTzeaghpVAcFX6teBcbh5PfNaTQ4QSB8vOhYNt1lH JCJch/RUEV144ysBUw82kq4uTVxJFX8aki90Oqn5fo4VdmFc+bjJOlJypJ2gZTaeMdZD U3VA== 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; bh=CTWJLTSJroYMndBn0PhkaK8v33nMScSCNsUYYunUuks=; b=ZoutoH7Iob510UVoAh0aYVFMzFXgtx8tZ+H8mEcj2e+IV+/0A7BNX1dFscU2Y/sYZQ N7rmVIhNBmx/0eyHmdv8qGL98w50K9Hwb1cZ0FKwBQtaRrVe/h00RElJeA086UpLIodE PiLbA/T2jxz/9QIjRzBFV6eIAbOvElDNbDoDUzAc/ltUDl016MS/vu98b2WUi4qVMT15 FvBoxWVYkigBQ5Cw7GsK9rCMXObvfciTSyM7WTzTgA6T/KpbGqcBPAHVK2AcrBvTytBR YKdv7YQfLvO3wxYLqsiARDcWSUv7jyZn62AZ8/5LHfscjPZQD06e4AeeviZpEzYB4MNk g/ew== X-Gm-Message-State: AOAM530cPtsynEkSLtZqw1cdPZCW5LfG92Nb5e4zR3eKAQf1CFmTNCN+ GJO3GlBqD5dOuwX7xFaxkpBBR1c9YOTmWA== X-Received: by 2002:a17:902:dacd:b029:12d:7444:7f87 with SMTP id q13-20020a170902dacdb029012d74447f87mr35911764plx.77.1629859432809; Tue, 24 Aug 2021 19:43:52 -0700 (PDT) Received: from carrot.localdomain (i222-151-22-34.s42.a014.ap.plala.or.jp. [222.151.22.34]) by smtp.gmail.com with ESMTPSA id d3sm20352082pfa.51.2021.08.24.19.43.50 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Aug 2021 19:43:51 -0700 (PDT) From: Ryusuke Konishi To: Andrew Morton Cc: linux-nilfs , LKML Subject: [PATCH] nilfs2: use refcount_dec_and_lock() to fix potential UAF Date: Wed, 25 Aug 2021 11:43:48 +0900 Message-Id: <1629859428-5906-1-git-send-email-konishi.ryusuke@gmail.com> X-Mailer: git-send-email 1.8.3.1 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Zhen Lei When the refcount is decreased to 0, the resource reclamation branch is entered. Before CPU0 reaches the race point (1), CPU1 may obtain the spinlock and traverse the rbtree to find 'root', see nilfs_lookup_root(). Although CPU1 will call refcount_inc() to increase the refcount, it is obviously too late. CPU0 will release 'root' directly, CPU1 then accesses 'root' and triggers UAF. Use refcount_dec_and_lock() to ensure that both the operations of decrease refcount to 0 and link deletion are lock protected eliminates this risk. CPU0 CPU1 nilfs_put_root(): <-------- (1) spin_lock(&nilfs->ns_cptree_lock); rb_erase(&root->rb_node, &nilfs->ns_cptree); spin_unlock(&nilfs->ns_cptree_lock); kfree(root); <-------- use-after-free ======================================================================== refcount_t: underflow; use-after-free. WARNING: CPU: 2 PID: 9476 at lib/refcount.c:28 \ refcount_warn_saturate+0x1cf/0x210 lib/refcount.c:28 Modules linked in: CPU: 2 PID: 9476 Comm: syz-executor.0 Not tainted 5.10.45-rc1+ #3 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), ... RIP: 0010:refcount_warn_saturate+0x1cf/0x210 lib/refcount.c:28 ... ... Call Trace: __refcount_sub_and_test include/linux/refcount.h:283 [inline] __refcount_dec_and_test include/linux/refcount.h:315 [inline] refcount_dec_and_test include/linux/refcount.h:333 [inline] nilfs_put_root+0xc1/0xd0 fs/nilfs2/the_nilfs.c:795 nilfs_segctor_destroy fs/nilfs2/segment.c:2749 [inline] nilfs_detach_log_writer+0x3fa/0x570 fs/nilfs2/segment.c:2812 nilfs_put_super+0x2f/0xf0 fs/nilfs2/super.c:467 generic_shutdown_super+0xcd/0x1f0 fs/super.c:464 kill_block_super+0x4a/0x90 fs/super.c:1446 deactivate_locked_super+0x6a/0xb0 fs/super.c:335 deactivate_super+0x85/0x90 fs/super.c:366 cleanup_mnt+0x277/0x2e0 fs/namespace.c:1118 __cleanup_mnt+0x15/0x20 fs/namespace.c:1125 task_work_run+0x8e/0x110 kernel/task_work.c:151 tracehook_notify_resume include/linux/tracehook.h:188 [inline] exit_to_user_mode_loop kernel/entry/common.c:164 [inline] exit_to_user_mode_prepare+0x13c/0x170 kernel/entry/common.c:191 syscall_exit_to_user_mode+0x16/0x30 kernel/entry/common.c:266 do_syscall_64+0x45/0x80 arch/x86/entry/common.c:56 entry_SYSCALL_64_after_hwframe+0x44/0xa9 There is no reproduction program, and the above is only theoretical analysis. Fixes: ba65ae4729bf ("nilfs2: add checkpoint tree to nilfs object") Link: https://lkml.kernel.org/r/20210723012317.4146-1-thunder.leizhen@huawei.com Signed-off-by: Zhen Lei Signed-off-by: Ryusuke Konishi --- fs/nilfs2/the_nilfs.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 8b7b01a380ce..c8bfc01da5d7 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c @@ -792,14 +792,13 @@ struct nilfs_root * void nilfs_put_root(struct nilfs_root *root) { - if (refcount_dec_and_test(&root->count)) { - struct the_nilfs *nilfs = root->nilfs; + struct the_nilfs *nilfs = root->nilfs; - nilfs_sysfs_delete_snapshot_group(root); - - spin_lock(&nilfs->ns_cptree_lock); + if (refcount_dec_and_lock(&root->count, &nilfs->ns_cptree_lock)) { rb_erase(&root->rb_node, &nilfs->ns_cptree); spin_unlock(&nilfs->ns_cptree_lock); + + nilfs_sysfs_delete_snapshot_group(root); iput(root->ifile); kfree(root); -- 1.8.3.1