From patchwork Tue Aug 30 17:45:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thiago Jung Bauermann X-Patchwork-Id: 9305825 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A42E060756 for ; Tue, 30 Aug 2016 17:48:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9881828CE9 for ; Tue, 30 Aug 2016 17:48:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8D1F128CEB; Tue, 30 Aug 2016 17:48:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7A7E328CE9 for ; Tue, 30 Aug 2016 17:48:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933648AbcH3Rp0 (ORCPT ); Tue, 30 Aug 2016 13:45:26 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:35796 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933373AbcH3RpY (ORCPT ); Tue, 30 Aug 2016 13:45:24 -0400 Received: from pps.filterd (m0098393.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id u7UHhd5m071504 for ; Tue, 30 Aug 2016 13:45:23 -0400 Received: from e24smtp04.br.ibm.com (e24smtp04.br.ibm.com [32.104.18.25]) by mx0a-001b2d01.pphosted.com with ESMTP id 2558r5d6gf-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 30 Aug 2016 13:45:23 -0400 Received: from localhost by e24smtp04.br.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 30 Aug 2016 14:45:20 -0300 Received: from d24dlp02.br.ibm.com (9.18.248.206) by e24smtp04.br.ibm.com (10.172.0.140) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 30 Aug 2016 14:45:18 -0300 X-IBM-Helo: d24dlp02.br.ibm.com X-IBM-MailFrom: bauerman@linux.vnet.ibm.com X-IBM-RcptTo: linux-kernel@vger.kernel.org; linux-security-module@vger.kernel.org Received: from d24relay02.br.ibm.com (d24relay02.br.ibm.com [9.13.184.26]) by d24dlp02.br.ibm.com (Postfix) with ESMTP id D61431DC0070; Tue, 30 Aug 2016 13:45:07 -0400 (EDT) Received: from d24av05.br.ibm.com (d24av05.br.ibm.com [9.18.232.44]) by d24relay02.br.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u7UHjHZ428639638; Tue, 30 Aug 2016 14:45:17 -0300 Received: from d24av05.br.ibm.com (localhost [127.0.0.1]) by d24av05.br.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u7UHjGS4015724; Tue, 30 Aug 2016 14:45:17 -0300 Received: from hactar.ibm.com (lcfurno.br.ibm.com [9.18.203.1] (may be forged)) by d24av05.br.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u7UHjAVa015449; Tue, 30 Aug 2016 14:45:15 -0300 From: Thiago Jung Bauermann To: kexec@lists.infradead.org Cc: linux-security-module@vger.kernel.org, linux-ima-devel@lists.sourceforge.net, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, Eric Biederman , Dave Young , Vivek Goyal , Baoquan He , Michael Ellerman , Stewart Smith , Mimi Zohar , Eric Richter , Andrew Morton , Balbir Singh , Thiago Jung Bauermann Subject: [PATCH v4 3/5] kexec_file: Allow skipping checksum calculation for some segments. Date: Tue, 30 Aug 2016 14:45:03 -0300 X-Mailer: git-send-email 1.9.1 In-Reply-To: <1472579105-26296-1-git-send-email-bauerman@linux.vnet.ibm.com> References: <1472579105-26296-1-git-send-email-bauerman@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16083017-0028-0000-0000-0000013A3259 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16083017-0029-0000-0000-000013F5C916 Message-Id: <1472579105-26296-4-git-send-email-bauerman@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-08-30_07:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1608300169 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Add skip_checksum member to struct kexec_buf to specify whether the corresponding segment should be part of the checksum calculation. The next patch will add a way to update segments after a kimage is loaded. Segments that will be updated in this way should not be checksummed, otherwise they will cause the purgatory checksum verification to fail when the machine is rebooted. As a bonus, we don't need to special-case the purgatory segment anymore to avoid checksumming it. Places using struct kexec_buf get false as the default value for skip_checksum since they all use designated initializers. Therefore, there is no behavior change with this patch and all segments except the purgatory are checksummed. Signed-off-by: Thiago Jung Bauermann Nacked-by: "Eric W. Biederman" --- include/linux/kexec.h | 23 ++++++++++++++--------- kernel/kexec_file.c | 15 +++++++-------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 16561e96a6d7..edadff6c86ff 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -100,6 +100,9 @@ struct kexec_segment { size_t bufsz; unsigned long mem; size_t memsz; + + /* Whether this segment is ignored in the checksum calculation. */ + bool skip_checksum; }; #ifdef CONFIG_COMPAT @@ -151,15 +154,16 @@ struct kexec_file_ops { /** * struct kexec_buf - parameters for finding a place for a buffer in memory - * @image: kexec image in which memory to search. - * @buffer: Contents which will be copied to the allocated memory. - * @bufsz: Size of @buffer. - * @mem: On return will have address of the buffer in memory. - * @memsz: Size for the buffer in memory. - * @buf_align: Minimum alignment needed. - * @buf_min: The buffer can't be placed below this address. - * @buf_max: The buffer can't be placed above this address. - * @top_down: Allocate from top of memory. + * @image: kexec image in which memory to search. + * @buffer: Contents which will be copied to the allocated memory. + * @bufsz: Size of @buffer. + * @mem: On return will have address of the buffer in memory. + * @memsz: Size for the buffer in memory. + * @buf_align: Minimum alignment needed. + * @buf_min: The buffer can't be placed below this address. + * @buf_max: The buffer can't be placed above this address. + * @top_down: Allocate from top of memory. + * @skip_checksum: Don't verify checksum for this buffer in purgatory. */ struct kexec_buf { struct kimage *image; @@ -171,6 +175,7 @@ struct kexec_buf { unsigned long buf_min; unsigned long buf_max; bool top_down; + bool skip_checksum; }; int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf, diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index f5684adfad07..0e90d1446cb0 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -584,6 +584,7 @@ int kexec_add_buffer(struct kexec_buf *kbuf) ksegment->bufsz = kbuf->bufsz; ksegment->mem = kbuf->mem; ksegment->memsz = kbuf->memsz; + ksegment->skip_checksum = kbuf->skip_checksum; kbuf->image->nr_segments++; return 0; } @@ -598,7 +599,6 @@ static int kexec_calculate_store_digests(struct kimage *image) char *digest; void *zero_buf; struct kexec_sha_region *sha_regions; - struct purgatory_info *pi = &image->purgatory_info; zero_buf = __va(page_to_pfn(ZERO_PAGE(0)) << PAGE_SHIFT); zero_buf_sz = PAGE_SIZE; @@ -638,11 +638,7 @@ static int kexec_calculate_store_digests(struct kimage *image) struct kexec_segment *ksegment; ksegment = &image->segment[i]; - /* - * Skip purgatory as it will be modified once we put digest - * info in purgatory. - */ - if (ksegment->kbuf == pi->purgatory_buf) + if (ksegment->skip_checksum) continue; ret = crypto_shash_update(desc, ksegment->kbuf, @@ -714,7 +710,7 @@ static int __kexec_load_purgatory(struct kimage *image, unsigned long min, Elf_Shdr *sechdrs = NULL; struct kexec_buf kbuf = { .image = image, .bufsz = 0, .buf_align = 1, .buf_min = min, .buf_max = max, - .top_down = top_down }; + .top_down = top_down, .skip_checksum = true }; /* * sechdrs_c points to section headers in purgatory and are read @@ -819,7 +815,10 @@ static int __kexec_load_purgatory(struct kimage *image, unsigned long min, if (kbuf.buf_align < bss_align) kbuf.buf_align = bss_align; - /* Add buffer to segment list */ + /* + * Add buffer to segment list. Don't checksum the segment as + * it will be modified once we put digest info in purgatory. + */ ret = kexec_add_buffer(&kbuf); if (ret) goto out;