From patchwork Thu Nov 10 20:17:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Yuxuan Luo X-Patchwork-Id: 1702296 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=SIFcs/jv; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4N7Y6t5cTPz23mb for ; Fri, 11 Nov 2022 07:17:57 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1otDzi-0004q8-5W; Thu, 10 Nov 2022 20:17:50 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1otDzf-0004pQ-Td for kernel-team@lists.ubuntu.com; Thu, 10 Nov 2022 20:17:47 +0000 Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id B49104129B for ; Thu, 10 Nov 2022 20:17:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1668111467; bh=cPWHsrSWJtmJmhkBVEGiru7/zuu8M36itQoKDy32sfM=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=SIFcs/jvvnkRgsRymz1Dt7IE8wMw28PQjPLTVS297MAEWP9HalN/NL99phFyyzoRE nV6t24GVKcXBbZwQC2xwvf5Gw+JysKOOFMmz1i9+gctsRlN79mkIhrBAKlX6KBp0T4 D6WpDwZ6d57Dbj9v26lJcWXGW4v8F/UF1fKeattqZP8A89+Pd3EyEEEas1qMPwdDWW AL3TDvdC79lnrXeNXCuzFKpxv4KC93JYna8V6Pm0aRKa7Dabz+d/l90g5yF3SdZhE3 w7TcowkAYJD6BjIi3XMeH8hWxDfH8FjoJe8DX9YX/SZEMJUponotJDWw/K+6toAy9P Z48pJLA8zOqkQ== Received: by mail-qt1-f198.google.com with SMTP id n12-20020ac85a0c000000b003a5849497f9so2223045qta.20 for ; Thu, 10 Nov 2022 12:17:47 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cPWHsrSWJtmJmhkBVEGiru7/zuu8M36itQoKDy32sfM=; b=yhGm0+g6fZlu/6KXihVwAE2BgvTASsKzxl1iFxsQVWRFc53L6CXqGXojIqSXYCp2zY BaoP1zAZc1LYSXMqFkMMT6zx7gh/HwSqhMd8JjOstteBQZu86yaNmAiAK3zCuQmIYBZB hW8l5/jqA6ByNMsxqPiszoccZ7V+CQr8MOMFy2CwabkOfkIrO7K7Rmt/F6G/3H5H0Kox 0tgRYH5tgjkPWwc96rZjCWbNEBqta0hKdu60vcebL5+EaA3rY9iIYw+2RnOdRfQSLEHu 8v8GpEDB0Q1fk5iEUw09Z9gfL9ITARb6iEieHGY9SinKTIXMU4twbNiVYvlCD1GD4YiJ Mifg== X-Gm-Message-State: ACrzQf2Vjfow1pXRLIEQ+M75mQBt/y5hBMxeXFbrwZfJKuIRYnSHvHR3 vrkgnplhtAfQo9pAZoV1cMrvKbqlmwd+sdWQFK9cvxUXX8motNOg9jifE+PqIWPOM4B+5sMUUE0 XuJG013I4OMRQQQ4FtX98Udl0JsTpEUaazqO28TzF6g== X-Received: by 2002:a05:622a:429b:b0:3a5:2a82:7742 with SMTP id cr27-20020a05622a429b00b003a52a827742mr43359597qtb.524.1668111465286; Thu, 10 Nov 2022 12:17:45 -0800 (PST) X-Google-Smtp-Source: AMsMyM7NIlAhkoPsEfpNV8eKiMHbNjwKgUKyuqONy2iXKmJrXTBL4w3hXCrNRqW74uUZZbNpY2LKVg== X-Received: by 2002:a05:622a:429b:b0:3a5:2a82:7742 with SMTP id cr27-20020a05622a429b00b003a52a827742mr43359590qtb.524.1668111465008; Thu, 10 Nov 2022 12:17:45 -0800 (PST) Received: from cache-ubuntu.hsd1.nj.comcast.net ([2601:86:200:98b0:e7d0:be88:9c08:616a]) by smtp.gmail.com with ESMTPSA id b3-20020ac85403000000b00342f8d4d0basm125923qtq.43.2022.11.10.12.17.43 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Nov 2022 12:17:44 -0800 (PST) From: Yuxuan Luo To: kernel-team@lists.ubuntu.com Subject: [SRU][Bionic][PATCH 1/3] mm/rmap.c: don't reuse anon_vma if we just want a copy Date: Thu, 10 Nov 2022 15:17:31 -0500 Message-Id: <1506ecdef0cfc95ee677ac0d45f269a39020da90.1668099845.git.yuxuan.luo@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Wei Yang Before commit 7a3ef208e662 ("mm: prevent endless growth of anon_vma hierarchy"), anon_vma_clone() doesn't change dst->anon_vma. While after this commit, anon_vma_clone() will try to reuse an exist one on forking. But this commit go a little bit further for the case not forking. anon_vma_clone() is called from __vma_split(), __split_vma(), copy_vma() and anon_vma_fork(). For the first three places, the purpose here is get a copy of src and we don't expect to touch dst->anon_vma even it is NULL. While after that commit, it is possible to reuse an anon_vma when dst->anon_vma is NULL. This is not we intend to have. This patch stops reuse of anon_vma for non-fork cases. Link: http://lkml.kernel.org/r/20191011072256.16275-1-richardw.yang@linux.intel.com Fixes: 7a3ef208e662 ("mm: prevent endless growth of anon_vma hierarchy") Signed-off-by: Wei Yang Acked-by: Konstantin Khlebnikov Cc: Kirill A. Shutemov Cc: "Jérôme Glisse" Cc: Mike Kravetz Cc: Rik van Riel Cc: Qian Cai Cc: Shakeel Butt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds (cherry picked from commit 47b390d23bf81894395c8773acf6f73c66465dc4) CVE-2022-42703 Signed-off-by: Yuxuan Luo --- mm/rmap.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/mm/rmap.c b/mm/rmap.c index 4b6737027890..658f267235ed 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -250,13 +250,19 @@ static inline void unlock_anon_vma_root(struct anon_vma *root) * Attach the anon_vmas from src to dst. * Returns 0 on success, -ENOMEM on failure. * - * If dst->anon_vma is NULL this function tries to find and reuse existing - * anon_vma which has no vmas and only one child anon_vma. This prevents - * degradation of anon_vma hierarchy to endless linear chain in case of - * constantly forking task. On the other hand, an anon_vma with more than one - * child isn't reused even if there was no alive vma, thus rmap walker has a - * good chance of avoiding scanning the whole hierarchy when it searches where - * page is mapped. + * anon_vma_clone() is called by __vma_split(), __split_vma(), copy_vma() and + * anon_vma_fork(). The first three want an exact copy of src, while the last + * one, anon_vma_fork(), may try to reuse an existing anon_vma to prevent + * endless growth of anon_vma. Since dst->anon_vma is set to NULL before call, + * we can identify this case by checking (!dst->anon_vma && src->anon_vma). + * + * If (!dst->anon_vma && src->anon_vma) is true, this function tries to find + * and reuse existing anon_vma which has no vmas and only one child anon_vma. + * This prevents degradation of anon_vma hierarchy to endless linear chain in + * case of constantly forking task. On the other hand, an anon_vma with more + * than one child isn't reused even if there was no alive vma, thus rmap + * walker has a good chance of avoiding scanning the whole hierarchy when it + * searches where page is mapped. */ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src) { @@ -286,8 +292,8 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src) * will always reuse it. Root anon_vma is never reused: * it has self-parent reference and at least one child. */ - if (!dst->anon_vma && anon_vma != src->anon_vma && - anon_vma->degree < 2) + if (!dst->anon_vma && src->anon_vma && + anon_vma != src->anon_vma && anon_vma->degree < 2) dst->anon_vma = anon_vma; } if (dst->anon_vma) From patchwork Thu Nov 10 20:17:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuxuan Luo X-Patchwork-Id: 1702295 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=tUifk9BE; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4N7Y6t4Thqz23mY for ; Fri, 11 Nov 2022 07:17:58 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1otDzj-0004r6-GV; Thu, 10 Nov 2022 20:17:51 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1otDzg-0004pX-U4 for kernel-team@lists.ubuntu.com; Thu, 10 Nov 2022 20:17:48 +0000 Received: from mail-qv1-f72.google.com (mail-qv1-f72.google.com [209.85.219.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 770024129B for ; Thu, 10 Nov 2022 20:17:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1668111468; bh=IJ+zjaTzMMQ+laNrx5mwOSF4gSx4xdwvYxBWjbVqHsU=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tUifk9BEgOurrrI5x/q46Wbsqlcy9P7otH9Qar0LZIYi3oGxYU21xBU3puEWzuio9 qAn2aK/gSjwyBVYeiOXUr88NNNxo8s0NjBxeXs6D/v9+6li4nBnhuWpmshqTi03cAk eqEPv77z2RBv5oj41Y3zV4CdPvhoyG7pKnr0hkODvjaZdVDTj9YqTiZG/K8z5wHsPx gT7s61q7r/Mkx2bxM/ZUZylKRjy0qm5DfKSxPs8QrjoWyVVzMT4x+vAtEnBvKIgotw vmLUXUBElcG/WhDVDiBHkHSTiLKiYfgnZOFrxIFN57HvcZwlIlWlxj9Gm2thwq9Z5H 6RRQGhfgFPJ9g== Received: by mail-qv1-f72.google.com with SMTP id mh13-20020a056214564d00b004c60dd95880so1224147qvb.6 for ; Thu, 10 Nov 2022 12:17:48 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IJ+zjaTzMMQ+laNrx5mwOSF4gSx4xdwvYxBWjbVqHsU=; b=8HIcRa1tFniEdbr962Y91aNt4B+6I7XcVXLlfFUPEt4pAYOc9h/0jDG1fkXuGi2+7A wu7vv+bs30xdMOCS7SlePgQz+XiPB/XN5ipX/19LlC3yBKAkY3F3xPnfRxa4H0SF0mDx Uc8UDCOV9toNiza/P5aC9z2vYbUiyqQmRQuBA49lh8sHBc092z0X0sBzqqOAtje0mDhu FhAFCcYY++BeFXX8+cWAGYHGXHmcPOlcKf4tjQlmxb9beG3KIS4L7zw9h7liday+Mhs7 3NSpmg9eTjIFONmOnBHESBGSb1BAY5KuZrTsoZItsSvv8W2xDg6s/zzoS3ayEdrbXS9B JDFQ== X-Gm-Message-State: ANoB5plPzj0EtKlYAKMrUB7HdK6I1CYeOO8kTXrTQCpYnwmAogyEzhBQ r7EqogdUHm2jpoJLgYnd1XyLv0Y1How6LKj3evPVYz+27SkYLbWAa7o9g8zfzkJTVCRI8Cquwro trkxSmYRCn5IPyJ0grlcnrYHF8Kl1tGFdShKj9JZuqQ== X-Received: by 2002:a37:5a47:0:b0:6fa:e58e:64e3 with SMTP id o68-20020a375a47000000b006fae58e64e3mr1169220qkb.430.1668111466515; Thu, 10 Nov 2022 12:17:46 -0800 (PST) X-Google-Smtp-Source: AA0mqf75WUkRX3lgp6JeIfg/jcQIcSBfA5nhQrPO6WEc1gsd4qfwZjA67mzlGabE0ss8XQaxvnUkuA== X-Received: by 2002:a37:5a47:0:b0:6fa:e58e:64e3 with SMTP id o68-20020a375a47000000b006fae58e64e3mr1169213qkb.430.1668111466260; Thu, 10 Nov 2022 12:17:46 -0800 (PST) Received: from cache-ubuntu.hsd1.nj.comcast.net ([2601:86:200:98b0:e7d0:be88:9c08:616a]) by smtp.gmail.com with ESMTPSA id b3-20020ac85403000000b00342f8d4d0basm125923qtq.43.2022.11.10.12.17.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Nov 2022 12:17:45 -0800 (PST) From: Yuxuan Luo To: kernel-team@lists.ubuntu.com Subject: [SRU][Bionic][PATCH 2/3] mm: rmap: explicitly reset vma->anon_vma in unlink_anon_vmas() Date: Thu, 10 Nov 2022 15:17:32 -0500 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Li Xinhai In case the vma will continue to be used after unlink its relevant anon_vma, we need to reset the vma->anon_vma pointer to NULL. So, later when fault happen within this vma again, a new anon_vma will be prepared. By this way, the vma will only be checked for reverse mapping of pages which been fault in after the unlink_anon_vmas call. Currently, the mremap with MREMAP_DONTUNMAP scenario will continue use the vma after moved its page table entries to a new vma. For other scenarios, the vma itself will be freed after call unlink_anon_vmas. Link: https://lkml.kernel.org/r/20210119075126.3513154-1-lixinhai.lxh@gmail.com Signed-off-by: Li Xinhai Cc: Andrea Arcangeli Cc: Brian Geffon Cc: Kirill A. Shutemov Cc: Lokesh Gidra Cc: Minchan Kim Cc: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds (cherry picked from commit ee8ab1903e3d912d8f10bedbf96c3b6a1c8cbede) CVE-2022-42703 Signed-off-by: Yuxuan Luo --- mm/rmap.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mm/rmap.c b/mm/rmap.c index 658f267235ed..89b62b6b2008 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -406,8 +406,15 @@ void unlink_anon_vmas(struct vm_area_struct *vma) list_del(&avc->same_vma); anon_vma_chain_free(avc); } - if (vma->anon_vma) + if (vma->anon_vma) { vma->anon_vma->degree--; + + /* + * vma would still be needed after unlink, and anon_vma will be prepared + * when handle fault. + */ + vma->anon_vma = NULL; + } unlock_anon_vma_root(root); /* From patchwork Thu Nov 10 20:17:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuxuan Luo X-Patchwork-Id: 1702298 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=g4XiSqpd; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4N7Y6w3r2pz23mV for ; Fri, 11 Nov 2022 07:18:00 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1otDzm-0004uF-Mg; Thu, 10 Nov 2022 20:17:54 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1otDzj-0004r2-RX for kernel-team@lists.ubuntu.com; Thu, 10 Nov 2022 20:17:51 +0000 Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 8773C423DF for ; Thu, 10 Nov 2022 20:17:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1668111470; bh=qjcaWC/jxJ08hP85KtAFLBxqNLF2WWVSLSoZggc1kkg=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=g4XiSqpd2ji5Z+v4Dcc457k5ARz9ZIig6Cl2yIa5npkNJkDFo9GmHFijnzn1kgZ1/ MeT/96rb8BfRNHQUK+KpgdwR+4dxMgTyJu55c+cEc/qkpsbC7CvQRSTmyzuWfp9hbf 2gzHQcbSK1hc2HtWmpgUyq4npNxxpGkAdR2RKW2HQQfvk9UhbUhrYumqmosqmUMqkx k4qncZhR898z+5r6QJLHbCxVlSY5Gferm7M17GyBW7Y55PraPM3HIfyhA8F2YlrgM+ e5vVOcZbOGYLpqOJ4NI1zbS5XV+pH+xh08dVdS82Ns0eojBgR6n36xv8lSWV3V0cAb LQFoQB3txO7JQ== Received: by mail-qt1-f200.google.com with SMTP id v12-20020ac8578c000000b003a50eb13e29so2226098qta.3 for ; Thu, 10 Nov 2022 12:17:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qjcaWC/jxJ08hP85KtAFLBxqNLF2WWVSLSoZggc1kkg=; b=El65zvOmmf152GaoBdfErLrGX4viteXaZZllYY1krOgVvzpB4nhClyVE7ocT7Li9AW Hi/ig/oe6GpAvBE1YMEPlKHo9LPz8wwBE6xPZ9id6HFW5gndkgTBXwApZFEcxCjZ6jf3 YjfHL/c2X5wAlE2gFjWweeQp6HGbK2rGUbKo/yDWKvdnT3FYxOkYl43TjjPo22tCBgku bpfmxajhSCKVX3BrUPDavd4nyOYTxslv0id4V6qjTe+RevaxSZjU4KwpXwSqbUg4QJR6 7UxdVQ0nRMEcKFJvzR6A2umSAz/0EI5wtAozqc/XLSM/bD4s2jYQTsg1IawTI1DoyNYQ 6OQg== X-Gm-Message-State: ACrzQf10psX1tV3yVTcZognNBfMAv9nfdSiEw0ULLSp4Wq0aaZVsECnd MnJ2fQGiEnpJLOi5NtxSfATnWGkRPeF5jJapq+UnieOrvYR+P55aYmCwjvRmp3H+VvBJwDBOZQT fIyCvXUfTKMlu5WVve4zC/KncYi2qfKneBfaMrV2jBA== X-Received: by 2002:a05:620a:205e:b0:6f9:4890:3b47 with SMTP id d30-20020a05620a205e00b006f948903b47mr1719096qka.272.1668111467934; Thu, 10 Nov 2022 12:17:47 -0800 (PST) X-Google-Smtp-Source: AMsMyM465hGOQdbBzZkEA40LCgrSG/wN5sBRY3UXNWTFLb86S+iHJ/lA4kaCf11vaczrrLw3ExueTQ== X-Received: by 2002:a05:620a:205e:b0:6f9:4890:3b47 with SMTP id d30-20020a05620a205e00b006f948903b47mr1719083qka.272.1668111467561; Thu, 10 Nov 2022 12:17:47 -0800 (PST) Received: from cache-ubuntu.hsd1.nj.comcast.net ([2601:86:200:98b0:e7d0:be88:9c08:616a]) by smtp.gmail.com with ESMTPSA id b3-20020ac85403000000b00342f8d4d0basm125923qtq.43.2022.11.10.12.17.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Nov 2022 12:17:46 -0800 (PST) From: Yuxuan Luo To: kernel-team@lists.ubuntu.com Subject: [SRU][Bionic][PATCH 3/3] mm/rmap: Fix anon_vma->degree ambiguity leading to double-reuse Date: Thu, 10 Nov 2022 15:17:33 -0500 Message-Id: <61456909638ad2210b1d046c0b2414519703b527.1668099845.git.yuxuan.luo@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Jann Horn anon_vma->degree tracks the combined number of child anon_vmas and VMAs that use the anon_vma as their ->anon_vma. anon_vma_clone() then assumes that for any anon_vma attached to src->anon_vma_chain other than src->anon_vma, it is impossible for it to be a leaf node of the VMA tree, meaning that for such VMAs ->degree is elevated by 1 because of a child anon_vma, meaning that if ->degree equals 1 there are no VMAs that use the anon_vma as their ->anon_vma. This assumption is wrong because the ->degree optimization leads to leaf nodes being abandoned on anon_vma_clone() - an existing anon_vma is reused and no new parent-child relationship is created. So it is possible to reuse an anon_vma for one VMA while it is still tied to another VMA. This is an issue because is_mergeable_anon_vma() and its callers assume that if two VMAs have the same ->anon_vma, the list of anon_vmas attached to the VMAs is guaranteed to be the same. When this assumption is violated, vma_merge() can merge pages into a VMA that is not attached to the corresponding anon_vma, leading to dangling page->mapping pointers that will be dereferenced during rmap walks. Fix it by separately tracking the number of child anon_vmas and the number of VMAs using the anon_vma as their ->anon_vma. Fixes: 7a3ef208e662 ("mm: prevent endless growth of anon_vma hierarchy") Cc: stable@kernel.org Acked-by: Michal Hocko Acked-by: Vlastimil Babka Signed-off-by: Jann Horn Signed-off-by: Linus Torvalds (backported from commit 2555283eb40df89945557273121e9393ef9b542b) [yuxuan.luo: fix conflit on comment] CVE-2022-42073 Signed-off-by: Yuxuan Luo --- include/linux/rmap.h | 7 +++++-- mm/rmap.c | 29 ++++++++++++++++------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 91ccae946716..c80bd129e939 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -39,12 +39,15 @@ struct anon_vma { atomic_t refcount; /* - * Count of child anon_vmas and VMAs which points to this anon_vma. + * Count of child anon_vmas. Equals to the count of all anon_vmas that + * have ->parent pointing to this one, including itself. * * This counter is used for making decision about reusing anon_vma * instead of forking new one. See comments in function anon_vma_clone. */ - unsigned degree; + unsigned long num_children; + /* Count of VMAs whose ->anon_vma pointer points to this object. */ + unsigned long num_active_vmas; struct anon_vma *parent; /* Parent of this anon_vma */ diff --git a/mm/rmap.c b/mm/rmap.c index 89b62b6b2008..ac0b7dccf68f 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -82,7 +82,8 @@ static inline struct anon_vma *anon_vma_alloc(void) anon_vma = kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL); if (anon_vma) { atomic_set(&anon_vma->refcount, 1); - anon_vma->degree = 1; /* Reference for first vma */ + anon_vma->num_children = 0; + anon_vma->num_active_vmas = 0; anon_vma->parent = anon_vma; /* * Initialise the anon_vma root to point to itself. If called @@ -190,6 +191,7 @@ int __anon_vma_prepare(struct vm_area_struct *vma) anon_vma = anon_vma_alloc(); if (unlikely(!anon_vma)) goto out_enomem_free_avc; + anon_vma->num_children++; /* self-parent link for new root */ allocated = anon_vma; } @@ -199,8 +201,7 @@ int __anon_vma_prepare(struct vm_area_struct *vma) if (likely(!vma->anon_vma)) { vma->anon_vma = anon_vma; anon_vma_chain_link(vma, avc, anon_vma); - /* vma reference or self-parent link for new root */ - anon_vma->degree++; + anon_vma->num_active_vmas++; allocated = NULL; avc = NULL; } @@ -285,19 +286,19 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src) anon_vma_chain_link(dst, avc, anon_vma); /* - * Reuse existing anon_vma if its degree lower than two, - * that means it has no vma and only one anon_vma child. + * Reuse existing anon_vma if it has no vma and only one + * anon_vma child. * - * Do not chose parent anon_vma, otherwise first child - * will always reuse it. Root anon_vma is never reused: + * Root anon_vma is never reused: * it has self-parent reference and at least one child. */ if (!dst->anon_vma && src->anon_vma && - anon_vma != src->anon_vma && anon_vma->degree < 2) + anon_vma->num_children < 2 && + anon_vma->num_active_vmas == 0) dst->anon_vma = anon_vma; } if (dst->anon_vma) - dst->anon_vma->degree++; + dst->anon_vma->num_active_vmas++; unlock_anon_vma_root(root); return 0; @@ -347,6 +348,7 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma) anon_vma = anon_vma_alloc(); if (!anon_vma) goto out_error; + anon_vma->num_active_vmas++; avc = anon_vma_chain_alloc(GFP_KERNEL); if (!avc) goto out_error_free_anon_vma; @@ -367,7 +369,7 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma) vma->anon_vma = anon_vma; anon_vma_lock_write(anon_vma); anon_vma_chain_link(vma, avc, anon_vma); - anon_vma->parent->degree++; + anon_vma->parent->num_children++; anon_vma_unlock_write(anon_vma); return 0; @@ -399,7 +401,7 @@ void unlink_anon_vmas(struct vm_area_struct *vma) * to free them outside the lock. */ if (RB_EMPTY_ROOT(&anon_vma->rb_root.rb_root)) { - anon_vma->parent->degree--; + anon_vma->parent->num_children--; continue; } @@ -407,7 +409,7 @@ void unlink_anon_vmas(struct vm_area_struct *vma) anon_vma_chain_free(avc); } if (vma->anon_vma) { - vma->anon_vma->degree--; + vma->anon_vma->num_active_vmas--; /* * vma would still be needed after unlink, and anon_vma will be prepared @@ -425,7 +427,8 @@ void unlink_anon_vmas(struct vm_area_struct *vma) list_for_each_entry_safe(avc, next, &vma->anon_vma_chain, same_vma) { struct anon_vma *anon_vma = avc->anon_vma; - VM_WARN_ON(anon_vma->degree); + VM_WARN_ON(anon_vma->num_children); + VM_WARN_ON(anon_vma->num_active_vmas); put_anon_vma(anon_vma); list_del(&avc->same_vma);