Received: by 10.192.165.148 with SMTP id m20csp3898846imm; Mon, 23 Apr 2018 14:37:11 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/H6mp/D+4TarEbzWnjj35PCuF/RC0kHQn57xHdIH21NPYOn95oJNEJjik5dM46XOHN2MFJ X-Received: by 2002:a17:902:4464:: with SMTP id k91-v6mr22035370pld.219.1524519431864; Mon, 23 Apr 2018 14:37:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524519431; cv=none; d=google.com; s=arc-20160816; b=vMSe3EkQh9GGmS6nx86YNbJBobM8IAlr+RP7IlA0pAOTy5bl+9TjI7SaE7UX5IrA49 FQv5C+UHOfvQYowhzOlXdAnioqRfgLucg2fPGpmFXpdfjm3VJ5J1rAEyhY3r7T4L/ty5 OfyF4Nj21AFfboUBGodA0XZ1x9ckZguElWHLw5IpE06wLzh4v9wVcUgj9WFWohg0LKg1 3YRHDNBd4s2PkK+fGoCkTa/oMCTCpzKjlbvf4RV+BYgqKRjWlQ3CxpQ3dy2avJgO+lQO /Os/axPtNDOwgMLYv2lv1oiqbKmAGbEuF9ZhL7Iz7+9YPoyoMa8b7pEj4LrSyv5QeO/g Jr6Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=qHObfg+7Bs5ltNELD8FW/9VJ7C711LXGmq5jtZ8tz00=; b=h7AypPjn9xzFpsXTxnAztaWOO9VrRKvwJ8f+6aDUxmZL+jLbWCQA0hbZ6uPMHQ/B6g 8++tdXY9mXTEEdQjEU7RpkruFg4oPWX4vU/a8l7dEYcBRmZCM4W2ZQrXrpCad1QkL2vW BgUiT1O5j/47eW71pK6V85Rix5J1G1wiO8eg/M/2i8VLkdF40ou8K8PwpyMjMvk3kGy2 cO3PrNmMo9oLBtr8RFBWTzH67OAceAZSG/N3aMlj5vZfbl/Y2kBTHF6DqU8bgPDy58cF skKPuzd8CjBUXm5VQhbKZA3VNOzGILwgBXvNTwrnw6d2tdQv9tgubKfMAaF8el4ZotnU jzUg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l19si11909866pfg.17.2018.04.23.14.36.57; Mon, 23 Apr 2018 14:37:11 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932551AbeDWVer (ORCPT + 99 others); Mon, 23 Apr 2018 17:34:47 -0400 Received: from vps-vb.mhejs.net ([37.28.154.113]:40980 "EHLO vps-vb.mhejs.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932483AbeDWVek (ORCPT ); Mon, 23 Apr 2018 17:34:40 -0400 Received: by vps-vb.mhejs.net with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1fAj6C-0004wL-Tz; Mon, 23 Apr 2018 23:34:12 +0200 From: "Maciej S. Szmigiero" To: Borislav Petkov Cc: Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , x86@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 3/6] x86/microcode/AMD: Check microcode container data in the early loader Date: Mon, 23 Apr 2018 23:34:08 +0200 Message-Id: <60157b92eef72a73778d9e483b5376db737b5a97.1524515406.git.mail@maciej.szmigiero.name> X-Mailer: git-send-email 2.17.0 In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This commit converts the early loader in the AMD microcode update driver to use the container data checking functions introduced by the previous commit. We have to be careful to call these functions with 'early' parameter set, so they won't try to print errors as the early loader runs too early for printk()-style functions to work. Signed-off-by: Maciej S. Szmigiero --- arch/x86/kernel/cpu/microcode/amd.c | 45 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 4fafaf0852d7..94fcd702a67a 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -216,29 +216,33 @@ static bool verify_patch(u8 family, const u8 *buf, size_t buf_size, bool early) * Returns the amount of bytes consumed while scanning. @desc contains all the * data we're going to use in later stages of the application. */ -static ssize_t parse_container(u8 *ucode, ssize_t size, struct cont_desc *desc) +static size_t parse_container(u8 *ucode, size_t size, struct cont_desc *desc) { struct equiv_cpu_entry *eq; - ssize_t orig_size = size; + size_t orig_size = size; u32 *hdr = (u32 *)ucode; + u32 equiv_tbl_len; u16 eq_id; u8 *buf; - /* Am I looking at an equivalence table header? */ - if (hdr[0] != UCODE_MAGIC || - hdr[1] != UCODE_EQUIV_CPU_TABLE_TYPE || - hdr[2] == 0) + if (!verify_container(ucode, size, true)) + return 0; + + if (!verify_equivalence_table(ucode, size, true)) return CONTAINER_HDR_SZ; buf = ucode; + equiv_tbl_len = hdr[2]; eq = (struct equiv_cpu_entry *)(buf + CONTAINER_HDR_SZ); /* Find the equivalence ID of our CPU in this table: */ eq_id = find_equiv_id(eq, desc->cpuid_1_eax); - buf += hdr[2] + CONTAINER_HDR_SZ; - size -= hdr[2] + CONTAINER_HDR_SZ; + buf += CONTAINER_HDR_SZ; + buf += equiv_tbl_len; + size -= CONTAINER_HDR_SZ; + size -= equiv_tbl_len; /* * Scan through the rest of the container to find where it ends. We do @@ -250,25 +254,22 @@ static ssize_t parse_container(u8 *ucode, ssize_t size, struct cont_desc *desc) hdr = (u32 *)buf; - if (hdr[0] != UCODE_UCODE_TYPE) + if (!verify_patch_section(buf, size, true)) break; - /* Sanity-check patch size. */ patch_size = hdr[1]; - if (patch_size > PATCH_MAX_SIZE) - break; - /* Skip patch section header: */ - buf += SECTION_HDR_SIZE; - size -= SECTION_HDR_SIZE; - - mc = (struct microcode_amd *)buf; - if (eq_id == mc->hdr.processor_rev_id) { + mc = (struct microcode_amd *)(buf + SECTION_HDR_SIZE); + if (eq_id == mc->hdr.processor_rev_id && + verify_patch(x86_family(desc->cpuid_1_eax), buf, size, + true)) { desc->psize = patch_size; desc->mc = mc; } + buf += SECTION_HDR_SIZE; buf += patch_size; + size -= SECTION_HDR_SIZE; size -= patch_size; } @@ -295,15 +296,13 @@ static ssize_t parse_container(u8 *ucode, ssize_t size, struct cont_desc *desc) */ static void scan_containers(u8 *ucode, size_t size, struct cont_desc *desc) { - ssize_t rem = size; - - while (rem >= 0) { - ssize_t s = parse_container(ucode, rem, desc); + while (size > 0) { + size_t s = parse_container(ucode, size, desc); if (!s) return; ucode += s; - rem -= s; + size -= s; } }