0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/seq_file.h>
0011 #include <linux/vmalloc.h>
0012 #include <linux/kexec.h>
0013 #include <linux/of.h>
0014 #include <linux/ima.h>
0015 #include "ima.h"
0016
0017 #ifdef CONFIG_IMA_KEXEC
0018 static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer,
0019 unsigned long segment_size)
0020 {
0021 struct ima_queue_entry *qe;
0022 struct seq_file file;
0023 struct ima_kexec_hdr khdr;
0024 int ret = 0;
0025
0026
0027 file.buf = vmalloc(segment_size);
0028 if (!file.buf) {
0029 ret = -ENOMEM;
0030 goto out;
0031 }
0032
0033 file.size = segment_size;
0034 file.read_pos = 0;
0035 file.count = sizeof(khdr);
0036
0037 memset(&khdr, 0, sizeof(khdr));
0038 khdr.version = 1;
0039 list_for_each_entry_rcu(qe, &ima_measurements, later) {
0040 if (file.count < file.size) {
0041 khdr.count++;
0042 ima_measurements_show(&file, qe);
0043 } else {
0044 ret = -EINVAL;
0045 break;
0046 }
0047 }
0048
0049 if (ret < 0)
0050 goto out;
0051
0052
0053
0054
0055
0056 khdr.buffer_size = file.count;
0057 if (ima_canonical_fmt) {
0058 khdr.version = cpu_to_le16(khdr.version);
0059 khdr.count = cpu_to_le64(khdr.count);
0060 khdr.buffer_size = cpu_to_le64(khdr.buffer_size);
0061 }
0062 memcpy(file.buf, &khdr, sizeof(khdr));
0063
0064 print_hex_dump_debug("ima dump: ", DUMP_PREFIX_NONE, 16, 1,
0065 file.buf, file.count < 100 ? file.count : 100,
0066 true);
0067
0068 *buffer_size = file.count;
0069 *buffer = file.buf;
0070 out:
0071 if (ret == -EINVAL)
0072 vfree(file.buf);
0073 return ret;
0074 }
0075
0076
0077
0078
0079
0080
0081
0082 void ima_add_kexec_buffer(struct kimage *image)
0083 {
0084 struct kexec_buf kbuf = { .image = image, .buf_align = PAGE_SIZE,
0085 .buf_min = 0, .buf_max = ULONG_MAX,
0086 .top_down = true };
0087 unsigned long binary_runtime_size;
0088
0089
0090 void *kexec_buffer = NULL;
0091 size_t kexec_buffer_size;
0092 size_t kexec_segment_size;
0093 int ret;
0094
0095
0096
0097
0098
0099 binary_runtime_size = ima_get_binary_runtime_size();
0100 if (binary_runtime_size >= ULONG_MAX - PAGE_SIZE)
0101 kexec_segment_size = ULONG_MAX;
0102 else
0103 kexec_segment_size = ALIGN(ima_get_binary_runtime_size() +
0104 PAGE_SIZE / 2, PAGE_SIZE);
0105 if ((kexec_segment_size == ULONG_MAX) ||
0106 ((kexec_segment_size >> PAGE_SHIFT) > totalram_pages() / 2)) {
0107 pr_err("Binary measurement list too large.\n");
0108 return;
0109 }
0110
0111 ima_dump_measurement_list(&kexec_buffer_size, &kexec_buffer,
0112 kexec_segment_size);
0113 if (!kexec_buffer) {
0114 pr_err("Not enough memory for the kexec measurement buffer.\n");
0115 return;
0116 }
0117
0118 kbuf.buffer = kexec_buffer;
0119 kbuf.bufsz = kexec_buffer_size;
0120 kbuf.memsz = kexec_segment_size;
0121 ret = kexec_add_buffer(&kbuf);
0122 if (ret) {
0123 pr_err("Error passing over kexec measurement buffer.\n");
0124 vfree(kexec_buffer);
0125 return;
0126 }
0127
0128 image->ima_buffer_addr = kbuf.mem;
0129 image->ima_buffer_size = kexec_segment_size;
0130 image->ima_buffer = kexec_buffer;
0131
0132 pr_debug("kexec measurement buffer for the loaded kernel at 0x%lx.\n",
0133 kbuf.mem);
0134 }
0135 #endif
0136
0137
0138
0139
0140 void __init ima_load_kexec_buffer(void)
0141 {
0142 void *kexec_buffer = NULL;
0143 size_t kexec_buffer_size = 0;
0144 int rc;
0145
0146 rc = ima_get_kexec_buffer(&kexec_buffer, &kexec_buffer_size);
0147 switch (rc) {
0148 case 0:
0149 rc = ima_restore_measurement_list(kexec_buffer_size,
0150 kexec_buffer);
0151 if (rc != 0)
0152 pr_err("Failed to restore the measurement list: %d\n",
0153 rc);
0154
0155 ima_free_kexec_buffer();
0156 break;
0157 case -ENOTSUPP:
0158 pr_debug("Restoring the measurement list not supported\n");
0159 break;
0160 case -ENOENT:
0161 pr_debug("No measurement list to restore\n");
0162 break;
0163 default:
0164 pr_debug("Error restoring the measurement list: %d\n", rc);
0165 }
0166 }