From patchwork Tue Mar 18 01:04:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: steven chen X-Patchwork-Id: 14020128 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 509515336D; Tue, 18 Mar 2025 01:05:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259919; cv=none; b=Wd8wKtZDgW+Ydr4/KOAUSYvLH932ATb2eHRkewKICxkjXPyNCbCdXCP+NIwCbpYGqF9nNOO4JpMhv9XCQYP9v41Z7cYsq3MbBMbuLYWkgVfjhXzK9LxSgeu6qSDHMbTXv+ao90xWkfJTTUpdSgQbYxcXCD3dsBlczNtDJEtb03M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259919; c=relaxed/simple; bh=yK1riHF9dxLj547iAGZZrUaCYJljyL3rt36X8RQ68xc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hm6KUcseMxyvOHTYJeQBwL3inKfL9IVxXhRHve8NuQUvpbvYEX8Mo+sQT7E7kuchlcMg/RPyLHFqZQz9Gko21pRWoZkQQPIvkUqvfibrvEW8pYlc9hfksffs4pbLMP56deOFujiHFuEQHHexC6ITnMKBWMNU1jZENO6sUGGCzdI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=I416MuSY; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="I416MuSY" Received: from localhost.localdomain (unknown [131.107.147.236]) by linux.microsoft.com (Postfix) with ESMTPSA id 292F3204601D; Mon, 17 Mar 2025 18:05:15 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 292F3204601D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1742259915; bh=evLBIs6rtcFkt9DDIKHTl8Kl84ENTBx9wiB3QZH+KPo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I416MuSYf98m6Mywzw+uyr272H+ws5gOQd6A2ClSeIuk+rS84SseHRlP6EVy/I0a4 JNUlZo7LMZb28z2E/CJhiRa3mTTNYPfEJGyTuTqSK0VPcJz+y6YCIAwBzxiUnOaHKZ tMFBtEmWR+UdyVnnnrAeNZjTSvmcmNT6+36/PGR8= 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 v10 1/8] ima: rename variable the ser_file "file" to "ima_kexec_file" Date: Mon, 17 Mar 2025 18:04:39 -0700 Message-ID: <20250318010448.954-2-chenste@linux.microsoft.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250318010448.954-1-chenste@linux.microsoft.com> References: <20250318010448.954-1-chenste@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The name of the local variable "file" of type seq_file defined in the ima_dump_measurement_list function is too generic. To better reflect the purpose of the variable, rename it to "ima_kexec_file". This change will help improve code readability and maintainability by making the variable's role more explicit. The variable ima_kexec_file is indeed the memory allocated for copying IMA measurement records. The ima_dump_measurement_list function calculates the actual memory occupied by the IMA logs and compares it with the allocated memory. If there is enough memory, it copies all IMA measurement records; otherwise, it does not copy any records, which would result in a failure of remote attestation. Suggested-by: Mimi Zohar Signed-off-by: steven chen Reviewed-by: Stefan Berger --- security/integrity/ima/ima_kexec.c | 39 ++++++++++++++++++------------ 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 9d45f4d26f73..8567619889d1 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -15,33 +15,41 @@ #include "ima.h" #ifdef CONFIG_IMA_KEXEC +/* + * Copy the measurement list to the allocated memory + * compare the size of IMA measurement list with the size of the allocated memory + * if the size of the allocated memory is not less than the size of IMA measurement list + * copy the measurement list to the allocated memory. + * else + * return error + */ 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 seq_file file; struct ima_kexec_hdr khdr; int ret = 0; /* segment size can't change between kexec load and execute */ - file.buf = vmalloc(segment_size); - if (!file.buf) { + ima_kexec_file.buf = vmalloc(segment_size); + if (!ima_kexec_file.buf) { ret = -ENOMEM; goto out; } - file.file = NULL; - file.size = segment_size; - file.read_pos = 0; - file.count = sizeof(khdr); /* reserved space */ + 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 */ list_for_each_entry_rcu(qe, &ima_measurements, later, true) { - if (file.count < file.size) { + if (ima_kexec_file.count < ima_kexec_file.size) { khdr.count++; - ima_measurements_show(&file, qe); + ima_measurements_show(&ima_kexec_file, qe); } else { ret = -EINVAL; break; @@ -55,23 +63,24 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer, * fill in reserved space with some buffer details * (eg. version, buffer size, number of measurements) */ - khdr.buffer_size = file.count; + khdr.buffer_size = ima_kexec_file.count; if (ima_canonical_fmt) { khdr.version = cpu_to_le16(khdr.version); khdr.count = cpu_to_le64(khdr.count); khdr.buffer_size = cpu_to_le64(khdr.buffer_size); } - memcpy(file.buf, &khdr, sizeof(khdr)); + memcpy(ima_kexec_file.buf, &khdr, sizeof(khdr)); print_hex_dump_debug("ima dump: ", DUMP_PREFIX_NONE, 16, 1, - file.buf, file.count < 100 ? file.count : 100, + ima_kexec_file.buf, ima_kexec_file.count < 100 ? + ima_kexec_file.count : 100, true); - *buffer_size = file.count; - *buffer = file.buf; + *buffer_size = ima_kexec_file.count; + *buffer = ima_kexec_file.buf; out: if (ret == -EINVAL) - vfree(file.buf); + vfree(ima_kexec_file.buf); return ret; } From patchwork Tue Mar 18 01:04:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: steven chen X-Patchwork-Id: 14020126 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5099861FF2; Tue, 18 Mar 2025 01:05:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259917; cv=none; b=jYMlTZ6U2oPL702owLK3uDgkp+ySQMUzQJWckKqjrDHOJPqLvwSycO9BZYfbYqPMGhpkTwgbbg4qpP0vlccjfJGlboOXlxkzaRM+OGLb5k+ZTnmDAGbJW3fGZ6ZQI9cIoOX5w2PUlbIgxLCuV7JRA0YgMvYptzNHXBVwW3P3A8g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259917; c=relaxed/simple; bh=9KWK2FcWXHseT+s0YEdr/0gMrJjOMqYfBNEnnpe5iAA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WD6jpTmPgM5FouHr7IDWZzHL1KgBi/ahtMhCqzw3TLUIaSuinsbBm1PVwt8vY89DsQevRPuX16b2a3OprtsrYVeD5+YeAQoisWB4KCI7vcuqRmqI7H+qVhL7GVgWGn5TFcCxTini9OsfoKu+OD03pe7xc3nrGG3O8LubsNs8I4k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=XGfeZNzG; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="XGfeZNzG" Received: from localhost.localdomain (unknown [131.107.147.236]) by linux.microsoft.com (Postfix) with ESMTPSA id 882462054907; Mon, 17 Mar 2025 18:05:15 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 882462054907 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1742259915; bh=Hba2DOQnhbvoH4xYJ6tdp7GM4mE8Rz1dOv3r0bEUwkc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XGfeZNzGJwVw640d4nK+kqVBvm16nM90ndpOCXPTkd1ygw8Rw+iWLpAIcjQMY8V/e V93x3VXF8zS3Nl2wfxcbTQJgz/L/jh6EdeDY1rQIurqbJL3P1LBYO7YaFNq3Qc9t52 LCZy8KpkyPyNTsYuMXs2YQeHFaXd6dZKckwzVkSg= 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 v10 2/8] ima: define and call ima_alloc_kexec_file_buf() Date: Mon, 17 Mar 2025 18:04:40 -0700 Message-ID: <20250318010448.954-3-chenste@linux.microsoft.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250318010448.954-1-chenste@linux.microsoft.com> References: <20250318010448.954-1-chenste@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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'. This patch includes the following changes: - Refactor ima_dump_measurement_list() to move the memory allocation to a separate function ima_alloc_kexec_file_buf() which allocates buffer of size 'kexec_segment_size' at kexec 'load'. - Make the local variable ima_kexec_file in ima_dump_measurement_list() a local static to the file, so that it can be accessed from ima_alloc_kexec_file_buf(). - Make necessary changes to the function ima_add_kexec_buffer() to call the above two functions. Signed-off-by: Tushar Sugandhi Signed-off-by: steven chen --- security/integrity/ima/ima_kexec.c | 67 +++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 8567619889d1..45170e283272 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -15,6 +15,48 @@ #include "ima.h" #ifdef CONFIG_IMA_KEXEC +static struct seq_file ima_kexec_file; + +static void ima_reset_kexec_file(struct seq_file *sf) +{ + sf->buf = NULL; + sf->size = 0; + sf->read_pos = 0; + sf->count = 0; +} + +static void ima_free_kexec_file_buf(struct seq_file *sf) +{ + vfree(sf->buf); + ima_reset_kexec_file(sf); +} + +static int ima_alloc_kexec_file_buf(size_t segment_size) +{ + /* + * kexec 'load' may be called multiple times. + * Free and realloc the buffer only if the segment_size is + * changed from the previous kexec 'load' call. + */ + if (ima_kexec_file.buf && ima_kexec_file.size == segment_size) + goto out; + + 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; + +out: + ima_kexec_file.read_pos = 0; + ima_kexec_file.count = sizeof(struct ima_kexec_hdr); /* reserved space */ + + return 0; +} + /* * Copy the measurement list to the allocated memory * compare the size of IMA measurement list with the size of the allocated memory @@ -26,23 +68,16 @@ 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 */ @@ -79,8 +114,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; } @@ -119,6 +152,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) { @@ -140,6 +179,12 @@ void ima_add_kexec_buffer(struct kimage *image) image->ima_buffer_size = kexec_segment_size; image->ima_buffer = kexec_buffer; + /* + * kexec owns kexec_buffer after kexec_add_buffer() is called + * and it will vfree() that buffer. + */ + ima_reset_kexec_file(&ima_kexec_file); + kexec_dprintk("kexec measurement buffer for the loaded kernel at 0x%lx.\n", kbuf.mem); } From patchwork Tue Mar 18 01:04:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: steven chen X-Patchwork-Id: 14020127 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E752A81749; Tue, 18 Mar 2025 01:05:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259918; cv=none; b=HpO21EuMBoWQBcnoQWhLMrq/zp6wwqDIXfNnilDRwsb0pj/LnwMpeMYJ2jsH5sTQiILgcX9AAStFn/M7BlHaUSjlaMGF3AU5Srb5kgsis/sswFMK//mOJgOk0pZskjz9DrXHnIHSouJ9FPzoil2vNeXtVRwoHBVYCdKG9gJCBsc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259918; c=relaxed/simple; bh=nHEZG8veSqB9nUZLO4ADK8dNExqiZn4gO5s+TKBMqLo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VouiWyWKP1PVnVyaJOMVgxYIshm6hkpm/RatNuQPyv4AHT75qsb3SP9amPCXvr5ifn+qwZ5+6IS05aZq1TEs9qojZdfFGJNJDLbzVzbD4o2E5xTdRbWEn6XYrokqMTbzTMunkqQlGlDZFfEGQpAEgKJVwO2QxIn171Jo4ad/nAU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=Y8VRk5HB; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="Y8VRk5HB" Received: from localhost.localdomain (unknown [131.107.147.236]) by linux.microsoft.com (Postfix) with ESMTPSA id E7AB7208A7B9; Mon, 17 Mar 2025 18:05:15 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com E7AB7208A7B9 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1742259916; bh=flNXXHF2r6sfBwmg9xSqUuz4QpRdUQO7adXhUP+TABI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y8VRk5HBdWkPV2fHgItfVrHxEkn64jc59+T+8XI6Y0aXtQgv5i3yPzGSrbMfX2gKf IYQGkuJH/dHlUDGojtjl02WrkbfslkK7Dc2eym3K1VQVYcKHkoqOpckSev/Byzdnnk j59yQn1o4NPgC8SJc61YvNji1J3Qn4PXfaw8aE1E= 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 v10 3/8] kexec: define functions to map and unmap segments Date: Mon, 17 Mar 2025 18:04:41 -0700 Message-ID: <20250318010448.954-4-chenste@linux.microsoft.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250318010448.954-1-chenste@linux.microsoft.com> References: <20250318010448.954-1-chenste@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Currently, the kernel behavior during kexec load is to fetch the IMA measurements log from TPM PCRs and store it in a buffer. When a kexec reboot is triggered, this stored log buffer is carried over to the second kernel. However, the time gap between kexec load and kexec reboot can be very long. During this time window, new events extended into TPM PCRs miss the chance to be carried over to the second kernel. This results in a mismatch between TPM PCR quotes and the actual IMA measurements list after kexec reboot, leading to remote attestation failure. To solve this problem, the new design defers reading TPM PCRs content into the kexec buffer to the kexec reboot phase, while still allocating the necessary buffer at kexec load time because it is not appropriate to allocate memory at the kexec reboot moment. The content of memory segments carried over to the new kernel during the kexec system call can be changed at the kexec 'execute' stage, but the size of the memory segments cannot be changed at the kexec 'execute' stage. To copy IMA measurement logs during the kexec operation, IMA allocates memory at the kexec 'load' stage and map the segments to the kimage structure. The mapped address will then be used to copy IMA measurements during the kexec 'execute' stage. Currently, the mechanism to map and unmap segments to the kimage structure is not available to subsystems outside of kexec. Implement kimage_map_segment() to enable IMA to map the measurement log list to the kimage structure during the kexec 'load' stage. This function takes a kimage pointer, a memory address, and a size, then gathers the source pages within the specified address range, creates an array of page pointers, and maps these to a contiguous virtual address range. The function returns the start virtual address of this range if successful, or NULL on failure. Implement kimage_unmap_segment() for unmapping segments using vunmap(). From: Tushar Sugandhi Signed-off-by: Tushar Sugandhi Cc: Eric Biederman Cc: Baoquan He Cc: Vivek Goyal Cc: Dave Young Signed-off-by: steven chen Acked-by: Baoquan He --- include/linux/kexec.h | 6 +++++ kernel/kexec_core.c | 54 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/include/linux/kexec.h b/include/linux/kexec.h index f0e9f8eda7a3..7d6b12f8b8d0 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -467,13 +467,19 @@ extern bool kexec_file_dbg_print; #define kexec_dprintk(fmt, arg...) \ do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0) +extern void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size); +extern void kimage_unmap_segment(void *buffer); #else /* !CONFIG_KEXEC_CORE */ struct pt_regs; struct task_struct; +struct kimage; static inline void __crash_kexec(struct pt_regs *regs) { } static inline void crash_kexec(struct pt_regs *regs) { } static inline int kexec_should_crash(struct task_struct *p) { return 0; } static inline int kexec_crash_loaded(void) { return 0; } +static inline void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size) +{ return NULL; } +static inline void kimage_unmap_segment(void *buffer) { } #define kexec_in_progress false #endif /* CONFIG_KEXEC_CORE */ diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index c0bdc1686154..a5e378e1dc7f 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -867,6 +867,60 @@ int kimage_load_segment(struct kimage *image, return result; } +void *kimage_map_segment(struct kimage *image, + unsigned long addr, unsigned long size) +{ + unsigned long src_page_addr, dest_page_addr = 0; + unsigned long eaddr = addr + size; + kimage_entry_t *ptr, entry; + struct page **src_pages; + unsigned int npages; + void *vaddr = NULL; + int i; + + /* + * Collect the source pages and map them in a contiguous VA range. + */ + npages = PFN_UP(eaddr) - PFN_DOWN(addr); + src_pages = kmalloc_array(npages, sizeof(*src_pages), GFP_KERNEL); + if (!src_pages) { + pr_err("Could not allocate ima pages array.\n"); + return NULL; + } + + i = 0; + for_each_kimage_entry(image, ptr, entry) { + if (entry & IND_DESTINATION) { + dest_page_addr = entry & PAGE_MASK; + } else if (entry & IND_SOURCE) { + if (dest_page_addr >= addr && dest_page_addr < eaddr) { + src_page_addr = entry & PAGE_MASK; + src_pages[i++] = + virt_to_page(__va(src_page_addr)); + if (i == npages) + break; + dest_page_addr += PAGE_SIZE; + } + } + } + + /* Sanity check. */ + WARN_ON(i < npages); + + vaddr = vmap(src_pages, npages, VM_MAP, PAGE_KERNEL); + kfree(src_pages); + + if (!vaddr) + pr_err("Could not map ima buffer.\n"); + + return vaddr; +} + +void kimage_unmap_segment(void *segment_buffer) +{ + vunmap(segment_buffer); +} + struct kexec_load_limit { /* Mutex protects the limit count. */ struct mutex mutex; From patchwork Tue Mar 18 01:04:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: steven chen X-Patchwork-Id: 14020130 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E757A85260; Tue, 18 Mar 2025 01:05:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259920; cv=none; b=DFO2Kk4+acLbqnDxMPZvekGf0Ow5aw2eCFHWRlf+RMfhyjDCsH1B/wxNW+DLIlBeOSUJsCcYExVbdgE8IRUowdM7cBsKWYAks1HWsfhg4WxChGsfRvfNxzRFeuNS/Z6Hk9gnjWtjYxz8+nv1Mj51t1TX5uAc4Zp08RmcJ5kggqY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259920; c=relaxed/simple; bh=NBhGuyEV6W1cV138SkZx8h2wrIln83y+JVZqhzer2QU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=otE8uGQs956T4uKHq3KyJ+Jr7cAbBQ1fc3ZK5JRyA+JnDC9x/PNagcIw0Q+3PeTChsT/4Bg82eAxWnaKum9o+gMTH/zGMDv5X6U309EWIIh1r6rKFyWZLCuOTR9KHg7vJqu7aek/R2yH4H/7JsKwqT6M1slbkXE2Krnqf3stimo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=eJHzzqSs; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="eJHzzqSs" Received: from localhost.localdomain (unknown [131.107.147.236]) by linux.microsoft.com (Postfix) with ESMTPSA id 3EDB220DEAC8; Mon, 17 Mar 2025 18:05:16 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 3EDB220DEAC8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1742259916; bh=ChPJc5DONIaBIynmnXN9T7sDKpkYPTV76HK61XuJeLY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eJHzzqSszRZ4adMZNCUevuB1bEuRkGJl5Zowh35kpLSiVk7TFGjXHO81cb4SFrT6e 9w3Z+gQdMuEKRDUkLiqISP7wJNS9JLy87AdECpJhW7m98w1FBAFKHjE3GXYhLSg69U Sm0xl45PXu5pzzj7enIT5LRiSW+ioqQNRU1Skeio= 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 v10 4/8] ima: kexec: skip IMA segment validation after kexec soft reboot Date: Mon, 17 Mar 2025 18:04:42 -0700 Message-ID: <20250318010448.954-5-chenste@linux.microsoft.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250318010448.954-1-chenste@linux.microsoft.com> References: <20250318010448.954-1-chenste@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 With this series, the IMA segment will be updated with the measurement log at the kexec execute stage when a soft reboot is initiated. Therefore, the digests should be updated for the IMA segment in the normal case. The content of memory segments carried over to the new kernel during the kexec systemcall can be changed at kexec 'execute' stage, but the size and the location of the memory segments cannot be changed at kexec 'execute' stage. However, during the kexec execute stage, if kexec_calculate_store_digests() API is called to update the digest, it does not reuse the same memory segment allocated during the kexec 'load' stage and the new memory segment required cannot be transferred/mapped to the new kernel. As a result, digest verification will fail in verify_sha256_digest() after a kexec soft reboot into the new kernel. Therefore, the digest calculation/verification of the IMA segment needs to be skipped. To address this, skip the calculation and storage of the digest for the IMA segment in kexec_calculate_store_digests() so that it is not added to the purgatory_sha_regions. Since verify_sha256_digest() only verifies 'purgatory_sha_regions', no change is needed in verify_sha256_digest() in this context. With this change, the IMA segment is not included in the digest calculation, storage, and verification. Signed-off-by: Tushar Sugandhi Cc: Eric Biederman Cc: Baoquan He Cc: Vivek Goyal Cc: Dave Young Signed-off-by: steven chen Reviewed-by: Stefan Berger Reviewed-by: Mimi Zohar Acked-by: Baoquan He --- include/linux/kexec.h | 3 +++ kernel/kexec_file.c | 22 ++++++++++++++++++++++ security/integrity/ima/ima_kexec.c | 3 +++ 3 files changed, 28 insertions(+) diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 7d6b12f8b8d0..107e726f2ef3 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -362,6 +362,9 @@ struct kimage { phys_addr_t ima_buffer_addr; size_t ima_buffer_size; + + unsigned long ima_segment_index; + bool is_ima_segment_index_set; #endif /* Core ELF header buffer */ diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 3eedb8c226ad..606132253c79 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -38,6 +38,21 @@ void set_kexec_sig_enforced(void) } #endif +#ifdef CONFIG_IMA_KEXEC +static bool check_ima_segment_index(struct kimage *image, int i) +{ + if (image->is_ima_segment_index_set && i == image->ima_segment_index) + return true; + else + return false; +} +#else +static bool check_ima_segment_index(struct kimage *image, int i) +{ + return false; +} +#endif + static int kexec_calculate_store_digests(struct kimage *image); /* Maximum size in bytes for kernel/initrd files. */ @@ -764,6 +779,13 @@ static int kexec_calculate_store_digests(struct kimage *image) if (ksegment->kbuf == pi->purgatory_buf) continue; + /* + * Skip the segment if ima_segment_index is set and matches + * the current index + */ + if (check_ima_segment_index(image, i)) + continue; + ret = crypto_shash_update(desc, ksegment->kbuf, ksegment->bufsz); if (ret) diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 45170e283272..34020b1513b0 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -168,6 +168,7 @@ void ima_add_kexec_buffer(struct kimage *image) kbuf.buffer = kexec_buffer; kbuf.bufsz = kexec_buffer_size; kbuf.memsz = kexec_segment_size; + image->is_ima_segment_index_set = false; ret = kexec_add_buffer(&kbuf); if (ret) { pr_err("Error passing over kexec measurement buffer.\n"); @@ -178,6 +179,8 @@ void ima_add_kexec_buffer(struct kimage *image) image->ima_buffer_addr = kbuf.mem; image->ima_buffer_size = kexec_segment_size; image->ima_buffer = kexec_buffer; + image->ima_segment_index = image->nr_segments - 1; + image->is_ima_segment_index_set = true; /* * kexec owns kexec_buffer after kexec_add_buffer() is called From patchwork Tue Mar 18 01:04:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: steven chen X-Patchwork-Id: 14020129 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EABB114900F; Tue, 18 Mar 2025 01:05:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259919; cv=none; b=eEbjaOhE4tXjdPqIuzwNe+YztUL8SsHEKzCiO3tNYsLa9LDwJu0JkgCThTZo1Yej7tenq9hniJ0oWt+Fs4QLckm+hBKFwgoCQ5Hm0amltBTPzZzqDOtKafTRmFVFkfREUl0orSTg1el2BWIzQOTUccSqGdLXKmzHXqJJKSS5jAA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259919; c=relaxed/simple; bh=5nZEY0j7i8mG4u8/1CGV9wSIM5zPgjiJtsL7mh9u+14=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=heDk5UYLluHmNSFxFr1XQD4M6cB9bkyta7ufzck+PpUVlBVogxKjlQRjTJtk0epcYY8k4NqpPcZfJsAg2600kH4RPD+xSj3PyjXyAXAu8bOZ5QtdOrxFm7D4q/sldxbVtDD59F/OLTP+Crn2O4BuGEnaG7tgRMV3fntS8xo9yVA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=jbwYYcq3; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="jbwYYcq3" Received: from localhost.localdomain (unknown [131.107.147.236]) by linux.microsoft.com (Postfix) with ESMTPSA id 9CBC420DEACD; Mon, 17 Mar 2025 18:05:16 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 9CBC420DEACD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1742259916; bh=IW0Tu0Ypw9GySYV1UEKgWFwAzFcQAPCZdi7ximAPf+k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jbwYYcq3e97cftHkYSAVt3lU/Dj/B8sjz4cZGM2uYIqNGl2qNuFCtIeTHHXgPIRaZ IKNJclGefNBl9okI8i70sKcBeolZid1rXmm9hIBVDNU+vAlfF9w3aeV+47qbMRt65E PeadlIkzXZQO4H0N4liWWeS75PH0MXgyJQlXZfo0= 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 v10 5/8] ima: kexec: define functions to copy IMA log at soft boot Date: Mon, 17 Mar 2025 18:04:43 -0700 Message-ID: <20250318010448.954-6-chenste@linux.microsoft.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250318010448.954-1-chenste@linux.microsoft.com> References: <20250318010448.954-1-chenste@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The IMA log is currently copied to the new kernel during kexec 'load' using ima_dump_measurement_list(). However, the log copied at kexec 'load' may result in loss of IMA measurements that only occurred after kexec "load'. Therefore, the log needs to be copied during kexec 'execute'. Setup the needed infrastructure to move the IMA log copy from kexec 'load' to 'execute'. Define a new IMA hook ima_update_kexec_buffer() as a stub function. It will be used to call ima_dump_measurement_list() during kexec 'execute'. Implement ima_kexec_post_load() function to be invoked after the new Kernel image has been loaded for kexec. ima_kexec_post_load() maps the IMA buffer to a segment in the newly loaded Kernel. It also registers the reboot notifier_block to trigger ima_update_kexec_buffer() at kexec 'execute'. Signed-off-by: Tushar Sugandhi Cc: Eric Biederman Cc: Baoquan He Cc: Vivek Goyal Cc: Dave Young Signed-off-by: steven chen Reviewed-by: Stefan Berger Signed-off-by: steven chen --- include/linux/ima.h | 3 ++ security/integrity/ima/ima_kexec.c | 47 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/include/linux/ima.h b/include/linux/ima.h index 0bae61a15b60..8e29cb4e6a01 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -32,6 +32,9 @@ static inline void ima_appraise_parse_cmdline(void) {} #ifdef CONFIG_IMA_KEXEC extern void ima_add_kexec_buffer(struct kimage *image); +extern void ima_kexec_post_load(struct kimage *image); +#else +static inline void ima_kexec_post_load(struct kimage *image) {} #endif #else diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 34020b1513b0..9336c4f60650 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -12,10 +12,14 @@ #include #include #include +#include +#include #include "ima.h" #ifdef CONFIG_IMA_KEXEC +static bool ima_kexec_update_registered; static struct seq_file ima_kexec_file; +static void *ima_kexec_buffer; static void ima_reset_kexec_file(struct seq_file *sf) { @@ -191,6 +195,49 @@ void ima_add_kexec_buffer(struct kimage *image) kexec_dprintk("kexec measurement buffer for the loaded kernel at 0x%lx.\n", kbuf.mem); } + +/* + * Called during kexec execute so that IMA can update the measurement list. + */ +static int ima_update_kexec_buffer(struct notifier_block *self, + unsigned long action, void *data) +{ + return NOTIFY_OK; +} + +static struct notifier_block update_buffer_nb = { + .notifier_call = ima_update_kexec_buffer, + .priority = 1, +}; + +/* + * Create a mapping for the source pages that contain the IMA buffer + * so we can update it later. + */ +void ima_kexec_post_load(struct kimage *image) +{ + if (ima_kexec_buffer) { + kimage_unmap_segment(ima_kexec_buffer); + ima_kexec_buffer = NULL; + } + + if (!image->ima_buffer_addr) + return; + + ima_kexec_buffer = kimage_map_segment(image, + image->ima_buffer_addr, + image->ima_buffer_size); + if (!ima_kexec_buffer) { + pr_err("Could not map measurements buffer.\n"); + return; + } + + if (!ima_kexec_update_registered) { + register_reboot_notifier(&update_buffer_nb); + ima_kexec_update_registered = true; + } +} + #endif /* IMA_KEXEC */ /* From patchwork Tue Mar 18 01:04:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: steven chen X-Patchwork-Id: 14020131 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 67F00175D47; Tue, 18 Mar 2025 01:05:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259921; cv=none; b=NiQ0bMku4docgw9dioAMUI2hyfBANBfREpa3NPoaBho0Z+LF/mMljK9uTXdF/jnDRdTviZY8l6B8IHnH+BqTeSgTkiEMzz5XL9frCrdj+HbJNkw2xXVG90c765VrxhogBUxHhnAJzrN7bRLVUvNENgyKdPOBboGG7T55uF/+lNQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259921; c=relaxed/simple; bh=e5ThrXupcT9ZGfFU5Tk68BqmgfQZq93gt2MnC+AqPzA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=echOpBvmKit30tz7oTp4ubk8GCPj9ElEVe5IzRrz401xceFar6tXFYPSa/sOi8xQQTnvXOZmIU13Jd4hc9NW08sFcSyXo2Ee1+Chxaq9Y7u+Vt9N1uekBJ7bCapvemVb6LNyjaNg3BJnjzXRzz602gNDRyF70W0XAgGd7nsDYxg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=EjG4CEZl; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="EjG4CEZl" Received: from localhost.localdomain (unknown [131.107.147.236]) by linux.microsoft.com (Postfix) with ESMTPSA id E567120DEACE; Mon, 17 Mar 2025 18:05:16 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com E567120DEACE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1742259919; bh=mI2ZxU7Sw/KQ7e8aWJaQUjOuf7ihC69n+BKL3G34WUQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EjG4CEZlBqfI2j+nkaayFYfsPydslFDDER9nSmJaE/qLKfnScC6BJyYppdt7187VB xqaALSzDsIamP2X2nMUPpe4Ky6UUn0sAtgEviRYFsFhl0rv9yhQqs/JfG/SkGDZ5i1 8bJ1Wf6yDDdowocxJDLdDvSQpfTQxWExL196+ODI= 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 v10 6/8] ima: kexec: move IMA log copy from kexec load to execute Date: Mon, 17 Mar 2025 18:04:44 -0700 Message-ID: <20250318010448.954-7-chenste@linux.microsoft.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250318010448.954-1-chenste@linux.microsoft.com> References: <20250318010448.954-1-chenste@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 ima_dump_measurement_list() is called during kexec 'load', which may result in loss of IMA measurements during kexec soft reboot. Due to missed measurements that only occurred after kexec 'load', this function needs to be called during kexec 'execute'. This patch includes the following changes: - Implement kimage_file_post_load() function to be invoked after the new kernel image has been loaded for kexec. - Call kimage_file_post_load() from kexec_file_load() syscall only for kexec soft reboot scenarios and not for KEXEC_FILE_ON_CRASH. It will map the IMA segment, and register reboot notifier for the function ima_update_kexec_buffer() which would copy the IMA log at kexec soft reboot. - Make kexec_segment_size variable local static to the file so that it becomes accessible both during kexec 'load' and 'execute'. - Move ima_dump_measurement_list() call from ima_add_kexec_buffer() to ima_update_kexec_buffer(). - Copy the measurement list as much as possible. - Remove ima_reset_kexec_file() call from ima_add_kexec_buffer(), now that the buffer is being copied at kexec 'execute', and resetting the file at kexec 'load' would corrupt the buffer. Signed-off-by: Tushar Sugandhi Cc: Eric Biederman Cc: Baoquan He Cc: Vivek Goyal Cc: Dave Young Signed-off-by: steven chen Reviewed-by: Stefan Berger --- kernel/kexec_file.c | 10 ++++++ security/integrity/ima/ima_kexec.c | 51 ++++++++++++++++++------------ 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 606132253c79..ab449b43aaee 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -201,6 +201,13 @@ kimage_validate_signature(struct kimage *image) } #endif +static void kimage_file_post_load(struct kimage *image) +{ +#ifdef CONFIG_IMA_KEXEC + ima_kexec_post_load(image); +#endif +} + /* * In file mode list of segments is prepared by kernel. Copy relevant * data from user space, do error checking, prepare segment list @@ -428,6 +435,9 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd, kimage_terminate(image); + if (!(flags & KEXEC_FILE_ON_CRASH)) + kimage_file_post_load(image); + ret = machine_kexec_post_load(image); if (ret) goto out; diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 9336c4f60650..c390c745f882 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -19,6 +19,7 @@ #ifdef CONFIG_IMA_KEXEC static bool ima_kexec_update_registered; static struct seq_file ima_kexec_file; +static size_t kexec_segment_size; static void *ima_kexec_buffer; static void ima_reset_kexec_file(struct seq_file *sf) @@ -67,7 +68,7 @@ static int ima_alloc_kexec_file_buf(size_t segment_size) * if the size of the allocated memory is not less than the size of IMA measurement list * copy the measurement list to the allocated memory. * else - * return error + * copy the measurement list as much as possible. */ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer, unsigned long segment_size) @@ -95,9 +96,6 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer, } } - if (ret < 0) - goto out; - /* * fill in reserved space with some buffer details * (eg. version, buffer size, number of measurements) @@ -117,7 +115,7 @@ static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer, *buffer_size = ima_kexec_file.count; *buffer = ima_kexec_file.buf; -out: + return ret; } @@ -135,9 +133,8 @@ void ima_add_kexec_buffer(struct kimage *image) unsigned long binary_runtime_size; /* use more understandable variable names than defined in kbuf */ + size_t kexec_buffer_size = 0; void *kexec_buffer = NULL; - size_t kexec_buffer_size; - size_t kexec_segment_size; int ret; /* @@ -162,13 +159,6 @@ void ima_add_kexec_buffer(struct kimage *image) return; } - ima_dump_measurement_list(&kexec_buffer_size, &kexec_buffer, - kexec_segment_size); - if (!kexec_buffer) { - pr_err("Not enough memory for the kexec measurement buffer.\n"); - return; - } - kbuf.buffer = kexec_buffer; kbuf.bufsz = kexec_buffer_size; kbuf.memsz = kexec_segment_size; @@ -186,12 +176,6 @@ void ima_add_kexec_buffer(struct kimage *image) image->ima_segment_index = image->nr_segments - 1; image->is_ima_segment_index_set = true; - /* - * kexec owns kexec_buffer after kexec_add_buffer() is called - * and it will vfree() that buffer. - */ - ima_reset_kexec_file(&ima_kexec_file); - kexec_dprintk("kexec measurement buffer for the loaded kernel at 0x%lx.\n", kbuf.mem); } @@ -202,7 +186,32 @@ void ima_add_kexec_buffer(struct kimage *image) static int ima_update_kexec_buffer(struct notifier_block *self, unsigned long action, void *data) { - return NOTIFY_OK; + size_t buf_size = 0; + int ret = NOTIFY_OK; + void *buf = NULL; + + if (!kexec_in_progress) { + pr_info("No kexec in progress.\n"); + return ret; + } + + if (!ima_kexec_buffer) { + pr_err("Kexec buffer not set.\n"); + return ret; + } + + ret = ima_dump_measurement_list(&buf_size, &buf, kexec_segment_size); + + if (ret) + pr_err("Dump measurements failed. Error:%d\n", ret); + + if (buf_size != 0) + memcpy(ima_kexec_buffer, buf, buf_size); + + kimage_unmap_segment(ima_kexec_buffer); + ima_kexec_buffer = NULL; + + return ret; } static struct notifier_block update_buffer_nb = { From patchwork Tue Mar 18 01:04:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: steven chen X-Patchwork-Id: 14020132 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9EE2017A5BE; Tue, 18 Mar 2025 01:05:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259921; cv=none; b=MUtwmv0fUy8qKygVFLEJBtRJtrP//PG1K099iBM6Yz+LPpTYSyOCM2s4BcLVzgM1RmPieQxbUymj8gkrWUGQ2wBshiARD+CQTRI/RMzXqy73DvF+6Sk4JIRuOSyF50NJh48PsNp6iTHO9NGpuZ6/OFub7NveYzBjqxqBGNUl5D4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259921; c=relaxed/simple; bh=sKE666mGCI3vZBYfEWbGUFMbvDgX07ypoWPgaCGbRNc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=s0aKVrce56eJPkJA5kC7rJYzGitSpaQtl1Zby378Aql+dKWd/vH2Yzu1/z2L9JUIQ2roR0GGxrrqpu6VO7XH104jwuTmG3kPp8mecC00GVWdbLJPuwQCtRHLtMXf1AjKxzw78npoSeVs78ZR23EbrqXqQ5/IRkQh2ptSk9tjDNM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=Bs0j/Nwh; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="Bs0j/Nwh" Received: from localhost.localdomain (unknown [131.107.147.236]) by linux.microsoft.com (Postfix) with ESMTPSA id 54B5D20DEAD0; Mon, 17 Mar 2025 18:05:19 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 54B5D20DEAD0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1742259919; bh=Ty9sv4Bp1XPvAQ5oJvrZtlIyyb6EVB/JOlZEMGsb4Xk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Bs0j/Nwhooqwv2yBhGocF745aY8riub5lBnCgJlSxMIOqzYO/Etp9tF7Cuja5Nvbv /SA0UxfWUJtII1me/Uy10/koq4PideEB2QaBvQEeR8LRNv3y1D0DJplpaqqP7mjHVE FQQO8UnkWt7uxT3AQXYfkKo3TpxN/gX07autdYwc= 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 v10 7/8] ima: make the kexec extra memory configurable Date: Mon, 17 Mar 2025 18:04:45 -0700 Message-ID: <20250318010448.954-8-chenste@linux.microsoft.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250318010448.954-1-chenste@linux.microsoft.com> References: <20250318010448.954-1-chenste@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The extra memory allocated for carrying the IMA measurement list across kexec is hard-coded as half a PAGE. Make it configurable. Define a Kconfig option, IMA_KEXEC_EXTRA_MEMORY_KB, to configure the extra memory (in kb) to be allocated for IMA measurements added during kexec soft reboot. Ensure the default value of the option is set such that extra half a page of memory for additional measurements is allocated for the additional measurements. Update ima_add_kexec_buffer() function to allocate memory based on the Kconfig option value, rather than the currently hard-coded one. Suggested-by: Stefan Berger Signed-off-by: Tushar Sugandhi Signed-off-by: steven chen Reviewed-by: Stefan Berger Reviewed-by: Mimi Zohar --- security/integrity/ima/Kconfig | 10 ++++++++++ security/integrity/ima/ima_kexec.c | 16 +++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 475c32615006..d73c96c3c1c9 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -321,4 +321,14 @@ config IMA_DISABLE_HTABLE help This option disables htable to allow measurement of duplicate records. +config IMA_KEXEC_EXTRA_MEMORY_KB + int "Extra memory for IMA measurements added during kexec soft reboot" + depends on IMA_KEXEC + default 0 + help + IMA_KEXEC_EXTRA_MEMORY_KB determines the extra memory to be + allocated (in kb) for IMA measurements added during kexec soft reboot. + If set to the default value of 0, an extra half page of memory for those + additional measurements will be allocated. + endif diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index c390c745f882..0f214e41dd33 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -131,6 +131,7 @@ void ima_add_kexec_buffer(struct kimage *image) .buf_min = 0, .buf_max = ULONG_MAX, .top_down = true }; unsigned long binary_runtime_size; + unsigned long extra_memory; /* use more understandable variable names than defined in kbuf */ size_t kexec_buffer_size = 0; @@ -138,15 +139,20 @@ void ima_add_kexec_buffer(struct kimage *image) int ret; /* - * Reserve an extra half page of memory for additional measurements - * added during the kexec load. + * Reserve extra memory for measurements added during kexec. */ - binary_runtime_size = ima_get_binary_runtime_size(); + if (CONFIG_IMA_KEXEC_EXTRA_MEMORY_KB <= 0) + extra_memory = PAGE_SIZE / 2; + else + extra_memory = CONFIG_IMA_KEXEC_EXTRA_MEMORY_KB * 1024; + + binary_runtime_size = ima_get_binary_runtime_size() + extra_memory; + if (binary_runtime_size >= ULONG_MAX - PAGE_SIZE) kexec_segment_size = ULONG_MAX; else - kexec_segment_size = ALIGN(ima_get_binary_runtime_size() + - PAGE_SIZE / 2, PAGE_SIZE); + kexec_segment_size = ALIGN(binary_runtime_size, PAGE_SIZE); + if ((kexec_segment_size == ULONG_MAX) || ((kexec_segment_size >> PAGE_SHIFT) > totalram_pages() / 2)) { pr_err("Binary measurement list too large.\n"); From patchwork Tue Mar 18 01:04:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: steven chen X-Patchwork-Id: 14020133 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id F1DE3188938; Tue, 18 Mar 2025 01:05:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259921; cv=none; b=LVo97ApF14KjoKHzKtACb18FaiSEyRx95tX6i9TWv+ab+vEGc98Z3yJJ7jq4hpOA5RFYYUNk7Z2rZLAkKhdzuean1SS7iPLaOtDgV/H0oj7VuYxT83GQZJjWb4p3pj0e75MSHCewH/8AT+ELvtNCAvTjYHzJofW+VA6/wSKN/tg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742259921; c=relaxed/simple; bh=Nz9EfW/V4d9vRhXeDuOWLwg3Gd+vG7QqYw7PN1wk/WU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EVSoW/Gpo1ymBJ2klywfeHb3OVZEBE8A8cUvgA6JPk5ic71Pj+I/ZL5tckqlRfCBulNk26YOeyuelDlG2dv+5j8+82etmR5+7epabYZyE7o3LZ/nmobvDB+eL8N+heRUsO1VEkd6HPAEXW9vwMeto/5TLo15baNO7n2uHtTntI0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=N48p2xzf; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="N48p2xzf" Received: from localhost.localdomain (unknown [131.107.147.236]) by linux.microsoft.com (Postfix) with ESMTPSA id 9A8AD210731C; Mon, 17 Mar 2025 18:05:19 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 9A8AD210731C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1742259919; bh=tSaoksgCpr/zt6e9/PPNt+iQGGb9Nj0ejv7ujQxrg2Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=N48p2xzfrti8JQnuKF0bQrv/Y3K5akEtb9qJWCLqQKMUgnXU/LMVW56z20Wi5IoGI f/rmkFKEw+Y5TIT0xKl3hSijwJ9ohRrPFEX8Q0Ks2uFVZquGyTypX9oUZoD5wY678S qLIhxtBA3SFrut3HuQEjpDHYjTagY0KC3VuczkSs= 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 v10 8/8] ima: measure kexec load and exec events as critical data Date: Mon, 17 Mar 2025 18:04:46 -0700 Message-ID: <20250318010448.954-9-chenste@linux.microsoft.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250318010448.954-1-chenste@linux.microsoft.com> References: <20250318010448.954-1-chenste@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-security-module@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The amount of memory allocated at kexec load, even with the extra memory allocated, might not be large enough for the entire measurement list. The indeterminate interval between kexec 'load' and 'execute' could exacerbate this problem. Define two new IMA events, 'kexec_load' and 'kexec_execute', to be measured as critical data at kexec 'load' and 'execute' respectively. Report the allocated kexec segment size, IMA binary log size and the runtime measurements count as part of those events. These events, and the values reported through them, serve as markers in the IMA log to verify the IMA events are captured during kexec soft reboot. The presence of a 'kexec_load' event in between the last two 'boot_aggregate' events in the IMA log implies this is a kexec soft reboot, and not a cold-boot. And the absence of 'kexec_execute' event after kexec soft reboot implies missing events in that window which results in inconsistency with TPM PCR quotes, necessitating a cold boot for a successful remote attestation. These critical data events are displayed as hex encoded ascii in the ascii_runtime_measurement_list. Verifying the critical data hash requires calculating the hash of the decoded ascii string. For example, to verify the 'kexec_load' data hash: sudo cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements | grep kexec_load | cut -d' ' -f 6 | xxd -r -p | sha256sum To verify the 'kexec_execute' data hash: sudo cat /sys/kernel/security/integrity/ima/ascii_runtime_measurements | grep kexec_execute | cut -d' ' -f 6 | xxd -r -p | sha256sum Signed-off-by: Tushar Sugandhi Signed-off-by: steven chen Reviewed-by: Stefan Berger --- security/integrity/ima/ima.h | 6 ++++++ security/integrity/ima/ima_kexec.c | 21 +++++++++++++++++++++ security/integrity/ima/ima_queue.c | 5 +++++ 3 files changed, 32 insertions(+) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 24d09ea91b87..34815baf5e21 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -240,6 +240,12 @@ void ima_post_key_create_or_update(struct key *keyring, struct key *key, unsigned long flags, bool create); #endif +#ifdef CONFIG_IMA_KEXEC +void ima_measure_kexec_event(const char *event_name); +#else +static inline void ima_measure_kexec_event(const char *event_name) {} +#endif + /* * The default binary_runtime_measurements list format is defined as the * platform native format. The canonical format is defined as little-endian. diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 0f214e41dd33..43223eb99046 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -17,6 +17,8 @@ #include "ima.h" #ifdef CONFIG_IMA_KEXEC +#define IMA_KEXEC_EVENT_LEN 256 + static bool ima_kexec_update_registered; static struct seq_file ima_kexec_file; static size_t kexec_segment_size; @@ -36,6 +38,24 @@ static void ima_free_kexec_file_buf(struct seq_file *sf) ima_reset_kexec_file(sf); } +void ima_measure_kexec_event(const char *event_name) +{ + char ima_kexec_event[IMA_KEXEC_EVENT_LEN]; + size_t buf_size = 0; + long len; + int n; + + buf_size = ima_get_binary_runtime_size(); + len = atomic_long_read(&ima_htable.len); + + n = scnprintf(ima_kexec_event, IMA_KEXEC_EVENT_LEN, + "kexec_segment_size=%lu;ima_binary_runtime_size=%lu;" + "ima_runtime_measurements_count=%ld;", + kexec_segment_size, buf_size, len); + + ima_measure_critical_data("ima_kexec", event_name, ima_kexec_event, n, false, NULL, 0); +} + static int ima_alloc_kexec_file_buf(size_t segment_size) { /* @@ -58,6 +78,7 @@ static int ima_alloc_kexec_file_buf(size_t segment_size) out: ima_kexec_file.read_pos = 0; ima_kexec_file.count = sizeof(struct ima_kexec_hdr); /* reserved space */ + ima_measure_kexec_event("kexec_load"); return 0; } diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index 83d53824aa98..590637e81ad1 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -241,6 +241,11 @@ static int ima_reboot_notifier(struct notifier_block *nb, unsigned long action, void *data) { +#ifdef CONFIG_IMA_KEXEC + if (action == SYS_RESTART && data && !strcmp(data, "kexec reboot")) + ima_measure_kexec_event("kexec_execute"); +#endif + ima_measurements_suspend(); return NOTIFY_DONE;