Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp1319261imu; Wed, 28 Nov 2018 07:53:44 -0800 (PST) X-Google-Smtp-Source: AFSGD/Wn+IkftqWfVHr935NCp4Ae2q6zEOrs68szROl/AfOpaY53BDNXC+Y07Qf+gZXnqCOvj1am X-Received: by 2002:a17:902:bf49:: with SMTP id u9mr37033369pls.4.1543420424577; Wed, 28 Nov 2018 07:53:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543420424; cv=none; d=google.com; s=arc-20160816; b=B5KU++mujqJgQKHi1heooVxJgMa8Pt/0gGb9i89udOewTZZw2/DMMtbIEWKWfn3KwR Lb4Leu+QbfQ9X2Wb/dxam8fmdtTgleW2YIDg3G5FuAf+qma4ItLEh025b6kfhkf1X54d 7HhnwwxORi3n7ASSGVI5V6knJmEWXXsOTSfMR8K1Ye7gzxveW8zMJ45Uqsz7Olb2hw1N zj8gq3zN8ijPkcUs/UY+SRsPQ1KYyvgRXyBnlQ3QsmX5bAnr3NUxxxIprruroT2HIvzM StZc5mezgSiyXA7YA+DBX75RP4svB1YqPn9fQaa/I5lTXwcDbZ7AgKNSZoNRG1o97Z/e K9/Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:content-transfer-encoding :mime-version:references:in-reply-to:date:cc:to:from:subject; bh=Ks1LmJslacu6eMuorEuCdGZKJaMAoeUf3jTZ1LPpM7g=; b=ArTbagWDOE9sL/d8dvbuthp2OmSFS04HUml4ZLPKUHKXaZEYf72Ym01pjWl22WCpBQ TCRYnTeCnEFdDwzTmZaRrCUjrtc/4Ti+lJgj+PW6JW9e7QXtqVNM4KTUuVruDyAfn8gJ fPzx8yWSMGv9+vnamWBtYP/w5LBuJ5tpVHtGJWt3hh80Ampb10bl8M+FjtN+SJ4WUJlU 6tzvMgq0LsiyBqsCIYILAwVUch4PFzA6KZ30o5r8nnU6IIxVTjQ+FQXUJKH6eFdwhCGZ S6Z3Lvj2xgq+BOSutteQcZmPBpIUjBn4/SyjEvWfkiA+vvlzgnoWUaRhv5d2f+TH8Yzn nWtQ== 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c4si7408398pfi.110.2018.11.28.07.53.20; Wed, 28 Nov 2018 07:53:44 -0800 (PST) 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728756AbeK2Cyi (ORCPT + 99 others); Wed, 28 Nov 2018 21:54:38 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:44988 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728300AbeK2Cyi (ORCPT ); Wed, 28 Nov 2018 21:54:38 -0500 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id wASFn2mb092653 for ; Wed, 28 Nov 2018 10:52:31 -0500 Received: from e06smtp04.uk.ibm.com (e06smtp04.uk.ibm.com [195.75.94.100]) by mx0a-001b2d01.pphosted.com with ESMTP id 2p1x03r6nt-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 28 Nov 2018 10:52:30 -0500 Received: from localhost by e06smtp04.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 28 Nov 2018 15:52:27 -0000 Received: from b06cxnps4075.portsmouth.uk.ibm.com (9.149.109.197) by e06smtp04.uk.ibm.com (192.168.101.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 28 Nov 2018 15:52:23 -0000 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id wASFqM0328639398 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 28 Nov 2018 15:52:22 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4FCC04C044; Wed, 28 Nov 2018 15:52:22 +0000 (GMT) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B75E74C058; Wed, 28 Nov 2018 15:52:20 +0000 (GMT) Received: from localhost.localdomain (unknown [9.80.103.235]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Wed, 28 Nov 2018 15:52:20 +0000 (GMT) Subject: Re: [PATCH 4/7] efi: Add an EFI signature blob parser From: Mimi Zohar To: Nayna Jain , David Howells , linux-integrity Cc: linux-security-module@vger.kernel.org, linux-efi@vger.kernel.org, linux-kernel , jforbes@redhat.com, seth.forshee@canonical.com, kexec@lists.infradead.org, keyrings@vger.kernel.org, vgoyal@redhat.com, ebiederm@xmission.com, mpe@ellerman.id.au Date: Wed, 28 Nov 2018 10:52:10 -0500 In-Reply-To: <20181125151500.8298-5-nayna@linux.ibm.com> References: <20181125151500.8298-1-nayna@linux.ibm.com> <20181125151500.8298-5-nayna@linux.ibm.com> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.20.5 (3.20.5-1.fc24) Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-TM-AS-GCONF: 00 x-cbid: 18112815-0016-0000-0000-0000022E0CB4 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18112815-0017-0000-0000-000032866B27 Message-Id: <1543420330.3902.220.camel@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2018-11-28_08:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1811280138 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sun, 2018-11-25 at 20:44 +0530, Nayna Jain wrote: > From: Dave Howells > > Add a function to parse an EFI signature blob looking for elements of > interest. A list is made up of a series of sublists, where all the > elements in a sublist are of the same type, but sublists can be of > different types. > > For each sublist encountered, the function pointed to by the > get_handler_for_guid argument is called with the type specifier GUID and > returns either a pointer to a function to handle elements of that type or > NULL if the type is not of interest. > > If the sublist is of interest, each element is passed to the handler > function in turn. There are a few checkpatch.pl warnings that need to be addressed, including the missing SPDX license. Mimi > > Signed-off-by: David Howells > Signed-off-by: Nayna Jain > --- > Changelog: > > v0: > - removed the CONFIG EFI_SIGNATURE_LIST_PARSER > - moved efi_parser.c from certs to security/integrity/platform_certs > directory > > include/linux/efi.h | 9 ++ > security/integrity/Makefile | 3 +- > security/integrity/platform_certs/efi_parser.c | 112 +++++++++++++++++++++++++ > 3 files changed, 123 insertions(+), 1 deletion(-) > create mode 100644 security/integrity/platform_certs/efi_parser.c > > diff --git a/include/linux/efi.h b/include/linux/efi.h > index 99cba6fe1234..2016145e2d6d 100644 > --- a/include/linux/efi.h > +++ b/include/linux/efi.h > @@ -1138,6 +1138,15 @@ extern int efi_memattr_apply_permissions(struct mm_struct *mm, > char * __init efi_md_typeattr_format(char *buf, size_t size, > const efi_memory_desc_t *md); > > + > +typedef void (*efi_element_handler_t)(const char *source, > + const void *element_data, > + size_t element_size); > +extern int __init parse_efi_signature_list( > + const char *source, > + const void *data, size_t size, > + efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *)); > + > /** > * efi_range_is_wc - check the WC bit on an address range > * @start: starting kvirt address > diff --git a/security/integrity/Makefile b/security/integrity/Makefile > index 046ffc1bb42d..6ee9058866cd 100644 > --- a/security/integrity/Makefile > +++ b/security/integrity/Makefile > @@ -9,7 +9,8 @@ integrity-y := iint.o > integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o > integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o > integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o > -integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o > +integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o \ > + platform_certs/efi_parser.o > > subdir-$(CONFIG_IMA) += ima > obj-$(CONFIG_IMA) += ima/ > diff --git a/security/integrity/platform_certs/efi_parser.c b/security/integrity/platform_certs/efi_parser.c > new file mode 100644 > index 000000000000..4e396f98f5c7 > --- /dev/null > +++ b/security/integrity/platform_certs/efi_parser.c > @@ -0,0 +1,112 @@ > +/* EFI signature/key/certificate list parser > + * > + * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved. > + * Written by David Howells (dhowells@redhat.com) > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public Licence > + * as published by the Free Software Foundation; either version > + * 2 of the Licence, or (at your option) any later version. > + */ > + > +#define pr_fmt(fmt) "EFI: "fmt > +#include > +#include > +#include > +#include > + > +/** > + * parse_efi_signature_list - Parse an EFI signature list for certificates > + * @source: The source of the key > + * @data: The data blob to parse > + * @size: The size of the data blob > + * @get_handler_for_guid: Get the handler func for the sig type (or NULL) > + * > + * Parse an EFI signature list looking for elements of interest. A list is > + * made up of a series of sublists, where all the elements in a sublist are of > + * the same type, but sublists can be of different types. > + * > + * For each sublist encountered, the @get_handler_for_guid function is called > + * with the type specifier GUID and returns either a pointer to a function to > + * handle elements of that type or NULL if the type is not of interest. > + * > + * If the sublist is of interest, each element is passed to the handler > + * function in turn. > + * > + * Error EBADMSG is returned if the list doesn't parse correctly and 0 is > + * returned if the list was parsed correctly. No error can be returned from > + * the @get_handler_for_guid function or the element handler function it > + * returns. > + */ > +int __init parse_efi_signature_list( > + const char *source, > + const void *data, size_t size, > + efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *)) > +{ > + efi_element_handler_t handler; > + unsigned offs = 0; > + > + pr_devel("-->%s(,%zu)\n", __func__, size); > + > + while (size > 0) { > + const efi_signature_data_t *elem; > + efi_signature_list_t list; > + size_t lsize, esize, hsize, elsize; > + > + if (size < sizeof(list)) > + return -EBADMSG; > + > + memcpy(&list, data, sizeof(list)); > + pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n", > + offs, > + list.signature_type.b, list.signature_list_size, > + list.signature_header_size, list.signature_size); > + > + lsize = list.signature_list_size; > + hsize = list.signature_header_size; > + esize = list.signature_size; > + elsize = lsize - sizeof(list) - hsize; > + > + if (lsize > size) { > + pr_devel("<--%s() = -EBADMSG [overrun @%x]\n", > + __func__, offs); > + return -EBADMSG; > + } > + > + if (lsize < sizeof(list) || > + lsize - sizeof(list) < hsize || > + esize < sizeof(*elem) || > + elsize < esize || > + elsize % esize != 0) { > + pr_devel("- bad size combo @%x\n", offs); > + return -EBADMSG; > + } > + > + handler = get_handler_for_guid(&list.signature_type); > + if (!handler) { > + data += lsize; > + size -= lsize; > + offs += lsize; > + continue; > + } > + > + data += sizeof(list) + hsize; > + size -= sizeof(list) + hsize; > + offs += sizeof(list) + hsize; > + > + for (; elsize > 0; elsize -= esize) { > + elem = data; > + > + pr_devel("ELEM[%04x]\n", offs); > + handler(source, > + &elem->signature_data, > + esize - sizeof(*elem)); > + > + data += esize; > + size -= esize; > + offs += esize; > + } > + } > + > + return 0; > +}