Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2410474imm; Thu, 14 Jun 2018 13:56:58 -0700 (PDT) X-Google-Smtp-Source: ADUXVKI+lCMNSOi8lHR8WDsI7jbhec4SVyP687hKfj3VKhi57gx00KH0fPM6FeQW1nk6GWZ4kcbJ X-Received: by 2002:aa7:8311:: with SMTP id t17-v6mr11087745pfm.45.1529009818397; Thu, 14 Jun 2018 13:56:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529009818; cv=none; d=google.com; s=arc-20160816; b=RP/RztB8ws58pbIYhPPom9e5nvpcG4yg3+SEXNAEM6oMyfufon8ZDZawxAZVjzXIBv kZu1ohlrZhXprzeeNjaZlzpYIk++TydRoKwnnbKpj5ln/dWOpusdMkAeMKSJhUWPaw7X EnOP92VfeIPNlV0GltSladQvv2smUFX5/f2qfGbcABzrm2UEF7XaDIGSq4CvA7V1U1ML 9iW9QKU/VPNK0/aEWCZg3ZFrQKAe3Ak4CbJAym24czN0v0yT+625s+k1LvtHPpd5DjGj vgx725NVUI0Kyry3NuWmO1WjgUXloh4lHEyQFVt+76RixpGty2MRu65gftJGTQdyMMyz RCxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:autocrypt:openpgp:from:references:cc:to:subject :arc-authentication-results; bh=/Z94SckPsX39JAYtVqcMoq37BlF4sxnvDcabkU4bs/8=; b=KpA2CEzbXRTcBIHWeAWMJFKEjXtbi2EnajcFfxAidBWGu+1aY4sGFLuH/7ibP9h1r3 cFS23VAUUa+Gq+EXjBrpv0IGk7N1bnZXYbqBt4Jxmo0inc/mEU48uFw6lkFNANK398UR RkSmwGUcmlCnujnlKJX+FZEf9b2VGb6jqy1YnvMSxYq6SzJbsj+aziXUndt2MKtWY8ad PwHMChHwukQ456R6hGYzapwvATwESXC1tiY4qS4D01yuB6nTZQW55JNXIWfRc/oRaM3b utdDcc8pV9U+DqPLLLZAeF2iPtsIX9eAv1gFn6y28bPFlMedekrLWk0/c0JGYBvukjtj gCBA== 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 n7-v6si4913695pgv.641.2018.06.14.13.56.41; Thu, 14 Jun 2018 13:56:58 -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 S1755448AbeFNU4N (ORCPT + 99 others); Thu, 14 Jun 2018 16:56:13 -0400 Received: from vps-vb.mhejs.net ([37.28.154.113]:39018 "EHLO vps-vb.mhejs.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754841AbeFNU4M (ORCPT ); Thu, 14 Jun 2018 16:56:12 -0400 Received: by vps-vb.mhejs.net with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.90_1) (envelope-from ) id 1fTZHs-0004n9-4L; Thu, 14 Jun 2018 22:56:08 +0200 Subject: Re: [PATCH v6 3/8] x86/microcode/AMD: Check microcode container data in the early loader To: Borislav Petkov Cc: Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , x86@kernel.org, linux-kernel@vger.kernel.org References: <0c53181bd5eb4e172407d9fde534cedb12e19b98.1526767245.git.mail@maciej.szmigiero.name> <20180605085427.GB1617@zn.tnic> From: "Maciej S. Szmigiero" Openpgp: preference=signencrypt Autocrypt: addr=mail@maciej.szmigiero.name; prefer-encrypt=mutual; keydata= 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 Message-ID: <7c47bfe2-3293-2973-d9bb-daa218d5751b@maciej.szmigiero.name> Date: Thu, 14 Jun 2018 22:56:07 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0 MIME-Version: 1.0 In-Reply-To: <20180605085427.GB1617@zn.tnic> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 05.06.2018 10:54, Borislav Petkov wrote: (..) >> @@ -258,25 +265,27 @@ 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 + SECTION_HDR_SIZE); >> + if (eq_id != mc->hdr.processor_rev_id) >> + goto next_patch; >> >> - mc = (struct microcode_amd *)buf; >> - if (eq_id == mc->hdr.processor_rev_id) { >> - desc->psize = patch_size; >> - desc->mc = mc; >> - } >> + if (!verify_patch(x86_family(desc->cpuid_1_eax), buf, size, >> + true)) > > Let it stick out. > > Ok, so above you do verify_patch_section() and then you take patch_size > without fully verifying it - it can be something non-sensically huge and > thus we might skip over good patches. > > What you should do instead is call verify_patch() directly - which > already calls verify_patch_section() and if the patch size exceeds the > per-family maximum, return *that* instead and skip only the per family > maximum inside the buffer so that any patches following can get a chance > to get inspected. verify_patch_section() does only very basic patch section checks - more or less whether the section, its header and a patch header exist and can be accessed at all. Here, a check can be added whether the indicated patch size does not exceed PATCH_MAX_SIZE to catch nonsensically huge patch sizes and to skip only a maximum patch length of that many bytes. At this point we don't know the CPU family the particular patch is for since the patch header contains only CPU rev_id, not an explicit family number. Only the late loader is able to translate back this CPU rev_id to its family number via the CPU equivalence table, the early loader simply skips patches that have CPU rev_id different from the current CPU one - so it can always use the current CPU family number for a patch verification. But either way, in order to read the CPU rev_id in the patch header we have to verify its presence in the microcode container file. This is what verify_patch_section() does. Then, once the particular loader determines the family number for a patch, verify_patch() does additional per-family size check. In principle, this function could be renamed verify_patch_family_size() and have call to verify_patch_section() at its beginning dropped. Maciej