From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by mx.groups.io with SMTP id smtpd.web10.14218.1585150188491097335 for ; Wed, 25 Mar 2020 08:29:48 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@linaro.org header.s=google header.b=jC3lMcKK; spf=pass (domain: linaro.org, ip: 209.85.128.67, mailfrom: ard.biesheuvel@linaro.org) Received: by mail-wm1-f67.google.com with SMTP id a9so3174896wmj.4 for ; Wed, 25 Mar 2020 08:29:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5yNxbDhkG1Sprk3mAmlWdLLOAreSFf2k+ubG2HPfaFs=; b=jC3lMcKK8S+08eMU5AgxtdzSygntRj7IFIPOv7dbBZYTY2O1H3i6NqP5KdD8BpixjE UTGebUx9TMN96omh5mgpXUBQbK9x1dz1eiwv2D8M9vN1gfq3yOfSD0jgCRqmk1KvUs2w ffQUbaFZnwAJnhFFoWZMYV4vHfD01JNantbYDZ5djHmBxQGIhiPhcOhOfW24MtqU87s7 QMs4rzabGTTrJCw5O3iogMlOXxEhPAGeFY5I4qZux+cyqYcigg2VM5XS8AgjOW9QTQPY Hxap7tKDgfZszMjm4PK+YMQHIpcEVz6nSP1/leZYP2aI9WCwsMxq0XnvWkYAOJx3dP6X e+SA== 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:in-reply-to :references; bh=5yNxbDhkG1Sprk3mAmlWdLLOAreSFf2k+ubG2HPfaFs=; b=si+i8eKXTUjfUWT/JNMzX8Xcy7IjBWndDB5TIAEKfPH3dfAGmB3uhnHCdqem2AXhtY gaF8Z6lRm8dB9oAhsDbntst1f736FvhXeslw2Asm+oGdNfqLOI0v7MXeeORzzuY421Fc HQqBT5bnArFYnzzPBFO2oLgfq5KNjcoDBBXTFHrZ10cJ9mqICnscvPKMm2P2RI3NT3Nh 0fRP16Q4gE8qRRDl+pWiwFJfwB/makjo89Vq3AZ3/HM35P4ZVP5iF6AovVqR0FL/uQuA aOHQTa3ds589wE/M7HmmfrHYoKSOH1nhBWdGFdFWI13FJCvS4mlowAy2OCEGvtLOwu0K +65A== X-Gm-Message-State: ANhLgQ0uSMhrVtipwHfxJUuirnpCn/2Nlns1LTEFWqQy5JuVkeHXBxy+ wGJFq0FVBKCnyBf03ADumcPceu1L+HEInYux X-Google-Smtp-Source: ADFU+vvSRlzhyGUwiC97LMBsZQgr6U3MhZ9SGdupE258bSqcXjNbsRC1kxeTmqpPNOW75jkTwjzuZw== X-Received: by 2002:a1c:7ec9:: with SMTP id z192mr3988276wmc.100.1585150186858; Wed, 25 Mar 2020 08:29:46 -0700 (PDT) Return-Path: Received: from e123331-lin.home (amontpellier-657-1-18-247.w109-210.abo.wanadoo.fr. [109.210.65.247]) by smtp.gmail.com with ESMTPSA id r15sm29249296wra.19.2020.03.25.08.29.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Mar 2020 08:29:46 -0700 (PDT) From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Laszlo Ersek , Leif Lindholm , Ashish Singhal Subject: [PATCH v3 1/3] ArmPkg/ArmMmuLib AARCH64: limit recursion when freeing page tables Date: Wed, 25 Mar 2020 16:29:38 +0100 Message-Id: <20200325152940.1492-2-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200325152940.1492-1-ard.biesheuvel@linaro.org> References: <20200325152940.1492-1-ard.biesheuvel@linaro.org> FreePageTablesRecursive () traverses the page table tree depth first to free all pages that it finds, without taking into account the level at which it is operating. Since TT_TYPE_TABLE_ENTRY aliases TT_TYPE_BLOCK_ENTRY_LEVEL3, we cannot distinguish table entries from block entries unless we take the level into account, and so we may be dereferencing garbage if we happen to try and free a hierarchy of page tables that has level 3 pages in it. Let's fix this by passing the level into FreePageTablesRecursive (), and limit the recursion to levels < 3. Signed-off-by: Ard Biesheuvel --- ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index a43d468b73ca..d78918cf7ba8 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -142,15 +142,21 @@ ReplaceTableEntry ( STATIC VOID FreePageTablesRecursive ( - IN UINT64 *TranslationTable + IN UINT64 *TranslationTable, + IN UINTN Level ) { UINTN Index; - for (Index = 0; Index < TT_ENTRY_COUNT; Index++) { - if ((TranslationTable[Index] & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) { - FreePageTablesRecursive ((VOID *)(UINTN)(TranslationTable[Index] & - TT_ADDRESS_MASK_BLOCK_ENTRY)); + ASSERT (Level <= 3); + + if (Level < 3) { + for (Index = 0; Index < TT_ENTRY_COUNT; Index++) { + if ((TranslationTable[Index] & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) { + FreePageTablesRecursive ((VOID *)(UINTN)(TranslationTable[Index] & + TT_ADDRESS_MASK_BLOCK_ENTRY), + Level + 1); + } } } FreePages (TranslationTable, 1); @@ -254,7 +260,7 @@ UpdateRegionMappingRecursive ( // possible for existing table entries, since we cannot revert the // modifications we made to the subhierarchy it represents.) // - FreePageTablesRecursive (TranslationTable); + FreePageTablesRecursive (TranslationTable, Level + 1); } return Status; } -- 2.17.1