From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A0A61C369AB for ; Wed, 16 Apr 2025 02:13:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=RebYXe6I1Y9VSO4KhCv3di0vL04EHE0LyJCCIybOssI=; b=AzWWlZm0n10tz8MoZauv7xga2x YYutd3L4qzBpUi8lGvQtWJ9Ff9ltXVAZ6MulTIX+GCxyK5d+dZocmx/LjWFTcAdzwxtZZxnAMBluu 3lAnGDApoAUkB4DSlvWNh6RlIcAo/sZcFyT1aqW2Xw7nT8v/md4AlY4k/D3TbjAwKia8otvbmtDIr ZTmyu8vHYx/7EZK19aatH7dCtoXSZRXl8bc9rT9YiQ1mSkOIbj9qRR3xJS9HG2TWNsijlm112WiSv LcKRevDz4SoJqiv6ZS+OiHprG9xe6bGtTQ1+q7uaFUGEuEFSVtYP3EQOOpxx1Ytdxtbxm1J7w2E7l 5yc/VN6g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1u4sH1-00000007uJs-0Ij2; Wed, 16 Apr 2025 02:13:11 +0000 Received: from linux.microsoft.com ([13.77.154.182]) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1u4sEl-00000007tmY-1GYf for kexec@lists.infradead.org; Wed, 16 Apr 2025 02:10:52 +0000 Received: from DESKTOP-VOT081N.hsd1.ga.comcast.net (unknown [172.200.70.13]) by linux.microsoft.com (Postfix) with ESMTPSA id A4F72210C453; Tue, 15 Apr 2025 19:10:48 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com A4F72210C453 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1744769450; bh=RebYXe6I1Y9VSO4KhCv3di0vL04EHE0LyJCCIybOssI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dT9qaqCj86WydKlVe01ANUSfjEGakwwS1qFfTq9MIPJZRXwqtS7H4b0mPHSbWOizL cl6VY2U7F2uogZX9hJmDN3KtjDvS5L8yhU7cwWE1FfbNTv7AoShX6/tQI6CpOpoiir Uee4h+g1+57xKWtjSwGWXJ2T9y8dZA3CC9tLwtWM= From: steven chen To: zohar@linux.ibm.com, stefanb@linux.ibm.com, roberto.sassu@huaweicloud.com, roberto.sassu@huawei.com, eric.snowberg@oracle.com, ebiederm@xmission.com, paul@paul-moore.com, code@tyhicks.com, bauermann@kolabnow.com, linux-integrity@vger.kernel.org, kexec@lists.infradead.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Cc: madvenka@linux.microsoft.com, nramas@linux.microsoft.com, James.Bottomley@HansenPartnership.com, bhe@redhat.com, vgoyal@redhat.com, dyoung@redhat.com Subject: [PATCH v12 2/9] ima: define and call ima_alloc_kexec_file_buf() Date: Tue, 15 Apr 2025 19:10:20 -0700 Message-ID: <20250416021028.1403-3-chenste@linux.microsoft.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250416021028.1403-1-chenste@linux.microsoft.com> References: <20250416021028.1403-1-chenste@linux.microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250415_191051_431358_2C3C1184 X-CRM114-Status: GOOD ( 17.29 ) X-BeenThere: kexec@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "kexec" Errors-To: kexec-bounces+kexec=archiver.kernel.org@lists.infradead.org From: Steven Chen In the current implementation, the ima_dump_measurement_list() API is called during the kexec "load" phase, where a buffer is allocated and the measurement records are copied. Due to this, new events added after kexec load but before kexec execute are not carried over to the new kernel during kexec operation Carrying the IMA measurement list across kexec requires allocating a buffer and copying the measurement records. Separate allocating the buffer and copying the measurement records into separate functions in order to allocate the buffer at kexec 'load' and copy the measurements at kexec 'execute'. Signed-off-by: Tushar Sugandhi Signed-off-by: Steven Chen --- security/integrity/ima/ima_kexec.c | 46 +++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 650beb74346c..b12ac3619b8f 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -15,26 +15,46 @@ #include "ima.h" #ifdef CONFIG_IMA_KEXEC +static struct seq_file ima_kexec_file; + +static void ima_free_kexec_file_buf(struct seq_file *sf) +{ + vfree(sf->buf); + sf->buf = NULL; + sf->size = 0; + sf->read_pos = 0; + sf->count = 0; +} + +static int ima_alloc_kexec_file_buf(size_t segment_size) +{ + ima_free_kexec_file_buf(&ima_kexec_file); + + /* segment size can't change between kexec load and execute */ + ima_kexec_file.buf = vmalloc(segment_size); + if (!ima_kexec_file.buf) + return -ENOMEM; + + ima_kexec_file.size = segment_size; + ima_kexec_file.read_pos = 0; + ima_kexec_file.count = sizeof(struct ima_kexec_hdr); /* reserved space */ + + return 0; +} + static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer, unsigned long segment_size) { - struct seq_file ima_kexec_file; struct ima_queue_entry *qe; struct ima_kexec_hdr khdr; int ret = 0; /* segment size can't change between kexec load and execute */ - ima_kexec_file.buf = vmalloc(segment_size); if (!ima_kexec_file.buf) { - ret = -ENOMEM; - goto out; + pr_err("Kexec file buf not allocated\n"); + return -EINVAL; } - ima_kexec_file.file = NULL; - ima_kexec_file.size = segment_size; - ima_kexec_file.read_pos = 0; - ima_kexec_file.count = sizeof(khdr); /* reserved space */ - memset(&khdr, 0, sizeof(khdr)); khdr.version = 1; /* This is an append-only list, no need to hold the RCU read lock */ @@ -71,8 +91,6 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer, *buffer_size = ima_kexec_file.count; *buffer = ima_kexec_file.buf; out: - if (ret == -EINVAL) - vfree(ima_kexec_file.buf); return ret; } @@ -111,6 +129,12 @@ void ima_add_kexec_buffer(struct kimage *image) return; } + ret = ima_alloc_kexec_file_buf(kexec_segment_size); + if (ret < 0) { + pr_err("Not enough memory for the kexec measurement buffer.\n"); + return; + } + ima_dump_measurement_list(&kexec_buffer_size, &kexec_buffer, kexec_segment_size); if (!kexec_buffer) { -- 2.43.0