Skip to content

Commit 60ee49f

Browse files
committed
Merge tag 'x86_kdump_for_v6.0_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 kdump updates from Borislav Petkov: - Add the ability to pass early an RNG seed to the kernel from the boot loader - Add the ability to pass the IMA measurement of kernel and bootloader to the kexec-ed kernel * tag 'x86_kdump_for_v6.0_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/setup: Use rng seeds from setup_data x86/kexec: Carry forward IMA measurement log on kexec
2 parents 8b70545 + 68b8e97 commit 60ee49f

File tree

9 files changed

+171
-20
lines changed

9 files changed

+171
-20
lines changed

arch/x86/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,6 +2010,7 @@ config KEXEC
20102010
config KEXEC_FILE
20112011
bool "kexec file based system call"
20122012
select KEXEC_CORE
2013+
select HAVE_IMA_KEXEC if IMA
20132014
depends on X86_64
20142015
depends on CRYPTO=y
20152016
depends on CRYPTO_SHA256=y

arch/x86/include/uapi/asm/bootparam.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
#define SETUP_APPLE_PROPERTIES 5
1212
#define SETUP_JAILHOUSE 6
1313
#define SETUP_CC_BLOB 7
14+
#define SETUP_IMA 8
15+
#define SETUP_RNG_SEED 9
16+
#define SETUP_ENUM_MAX SETUP_RNG_SEED
1417

1518
#define SETUP_INDIRECT (1<<31)
16-
17-
/* SETUP_INDIRECT | max(SETUP_*) */
18-
#define SETUP_TYPE_MAX (SETUP_INDIRECT | SETUP_CC_BLOB)
19+
#define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT)
1920

2021
/* ram_size flags */
2122
#define RAMDISK_IMAGE_START_MASK 0x07FF
@@ -172,6 +173,14 @@ struct jailhouse_setup_data {
172173
} __attribute__((packed)) v2;
173174
} __attribute__((packed));
174175

176+
/*
177+
* IMA buffer setup data information from the previous kernel during kexec
178+
*/
179+
struct ima_setup_data {
180+
__u64 addr;
181+
__u64 size;
182+
} __attribute__((packed));
183+
175184
/* The so-called "zeropage" */
176185
struct boot_params {
177186
struct screen_info screen_info; /* 0x000 */

arch/x86/kernel/e820.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,10 +1017,10 @@ void __init e820__reserve_setup_data(void)
10171017
e820__range_update(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
10181018

10191019
/*
1020-
* SETUP_EFI is supplied by kexec and does not need to be
1021-
* reserved.
1020+
* SETUP_EFI and SETUP_IMA are supplied by kexec and do not need
1021+
* to be reserved.
10221022
*/
1023-
if (data->type != SETUP_EFI)
1023+
if (data->type != SETUP_EFI && data->type != SETUP_IMA)
10241024
e820__range_update_kexec(pa_data,
10251025
sizeof(*data) + data->len,
10261026
E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);

arch/x86/kernel/kexec-bzimage64.c

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/mm.h>
1919
#include <linux/efi.h>
2020
#include <linux/verification.h>
21+
#include <linux/random.h>
2122

2223
#include <asm/bootparam.h>
2324
#include <asm/setup.h>
@@ -110,6 +111,26 @@ static int setup_e820_entries(struct boot_params *params)
110111
return 0;
111112
}
112113

114+
enum { RNG_SEED_LENGTH = 32 };
115+
116+
static void
117+
setup_rng_seed(struct boot_params *params, unsigned long params_load_addr,
118+
unsigned int rng_seed_setup_data_offset)
119+
{
120+
struct setup_data *sd = (void *)params + rng_seed_setup_data_offset;
121+
unsigned long setup_data_phys;
122+
123+
if (!rng_is_initialized())
124+
return;
125+
126+
sd->type = SETUP_RNG_SEED;
127+
sd->len = RNG_SEED_LENGTH;
128+
get_random_bytes(sd->data, RNG_SEED_LENGTH);
129+
setup_data_phys = params_load_addr + rng_seed_setup_data_offset;
130+
sd->next = params->hdr.setup_data;
131+
params->hdr.setup_data = setup_data_phys;
132+
}
133+
113134
#ifdef CONFIG_EFI
114135
static int setup_efi_info_memmap(struct boot_params *params,
115136
unsigned long params_load_addr,
@@ -186,11 +207,38 @@ setup_efi_state(struct boot_params *params, unsigned long params_load_addr,
186207
}
187208
#endif /* CONFIG_EFI */
188209

210+
static void
211+
setup_ima_state(const struct kimage *image, struct boot_params *params,
212+
unsigned long params_load_addr,
213+
unsigned int ima_setup_data_offset)
214+
{
215+
#ifdef CONFIG_IMA_KEXEC
216+
struct setup_data *sd = (void *)params + ima_setup_data_offset;
217+
unsigned long setup_data_phys;
218+
struct ima_setup_data *ima;
219+
220+
if (!image->ima_buffer_size)
221+
return;
222+
223+
sd->type = SETUP_IMA;
224+
sd->len = sizeof(*ima);
225+
226+
ima = (void *)sd + sizeof(struct setup_data);
227+
ima->addr = image->ima_buffer_addr;
228+
ima->size = image->ima_buffer_size;
229+
230+
/* Add setup data */
231+
setup_data_phys = params_load_addr + ima_setup_data_offset;
232+
sd->next = params->hdr.setup_data;
233+
params->hdr.setup_data = setup_data_phys;
234+
#endif /* CONFIG_IMA_KEXEC */
235+
}
236+
189237
static int
190238
setup_boot_parameters(struct kimage *image, struct boot_params *params,
191239
unsigned long params_load_addr,
192240
unsigned int efi_map_offset, unsigned int efi_map_sz,
193-
unsigned int efi_setup_data_offset)
241+
unsigned int setup_data_offset)
194242
{
195243
unsigned int nr_e820_entries;
196244
unsigned long long mem_k, start, end;
@@ -245,8 +293,22 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params,
245293
#ifdef CONFIG_EFI
246294
/* Setup EFI state */
247295
setup_efi_state(params, params_load_addr, efi_map_offset, efi_map_sz,
248-
efi_setup_data_offset);
296+
setup_data_offset);
297+
setup_data_offset += sizeof(struct setup_data) +
298+
sizeof(struct efi_setup_data);
249299
#endif
300+
301+
if (IS_ENABLED(CONFIG_IMA_KEXEC)) {
302+
/* Setup IMA log buffer state */
303+
setup_ima_state(image, params, params_load_addr,
304+
setup_data_offset);
305+
setup_data_offset += sizeof(struct setup_data) +
306+
sizeof(struct ima_setup_data);
307+
}
308+
309+
/* Setup RNG seed */
310+
setup_rng_seed(params, params_load_addr, setup_data_offset);
311+
250312
/* Setup EDD info */
251313
memcpy(params->eddbuf, boot_params.eddbuf,
252314
EDDMAXNR * sizeof(struct edd_info));
@@ -401,7 +463,13 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
401463
params_cmdline_sz = ALIGN(params_cmdline_sz, 16);
402464
kbuf.bufsz = params_cmdline_sz + ALIGN(efi_map_sz, 16) +
403465
sizeof(struct setup_data) +
404-
sizeof(struct efi_setup_data);
466+
sizeof(struct efi_setup_data) +
467+
sizeof(struct setup_data) +
468+
RNG_SEED_LENGTH;
469+
470+
if (IS_ENABLED(CONFIG_IMA_KEXEC))
471+
kbuf.bufsz += sizeof(struct setup_data) +
472+
sizeof(struct ima_setup_data);
405473

406474
params = kzalloc(kbuf.bufsz, GFP_KERNEL);
407475
if (!params)

arch/x86/kernel/setup.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/dma-map-ops.h>
1212
#include <linux/dmi.h>
1313
#include <linux/efi.h>
14+
#include <linux/ima.h>
1415
#include <linux/init_ohci1394_dma.h>
1516
#include <linux/initrd.h>
1617
#include <linux/iscsi_ibft.h>
@@ -23,6 +24,7 @@
2324
#include <linux/usb/xhci-dbgp.h>
2425
#include <linux/static_call.h>
2526
#include <linux/swiotlb.h>
27+
#include <linux/random.h>
2628

2729
#include <uapi/linux/mount.h>
2830

@@ -140,6 +142,11 @@ __visible unsigned long mmu_cr4_features __ro_after_init;
140142
__visible unsigned long mmu_cr4_features __ro_after_init = X86_CR4_PAE;
141143
#endif
142144

145+
#ifdef CONFIG_IMA
146+
static phys_addr_t ima_kexec_buffer_phys;
147+
static size_t ima_kexec_buffer_size;
148+
#endif
149+
143150
/* Boot loader ID and version as integers, for the benefit of proc_dointvec */
144151
int bootloader_type, bootloader_version;
145152

@@ -330,6 +337,60 @@ static void __init reserve_initrd(void)
330337
}
331338
#endif /* CONFIG_BLK_DEV_INITRD */
332339

340+
static void __init add_early_ima_buffer(u64 phys_addr)
341+
{
342+
#ifdef CONFIG_IMA
343+
struct ima_setup_data *data;
344+
345+
data = early_memremap(phys_addr + sizeof(struct setup_data), sizeof(*data));
346+
if (!data) {
347+
pr_warn("setup: failed to memremap ima_setup_data entry\n");
348+
return;
349+
}
350+
351+
if (data->size) {
352+
memblock_reserve(data->addr, data->size);
353+
ima_kexec_buffer_phys = data->addr;
354+
ima_kexec_buffer_size = data->size;
355+
}
356+
357+
early_memunmap(data, sizeof(*data));
358+
#else
359+
pr_warn("Passed IMA kexec data, but CONFIG_IMA not set. Ignoring.\n");
360+
#endif
361+
}
362+
363+
#if defined(CONFIG_HAVE_IMA_KEXEC) && !defined(CONFIG_OF_FLATTREE)
364+
int __init ima_free_kexec_buffer(void)
365+
{
366+
int rc;
367+
368+
if (!ima_kexec_buffer_size)
369+
return -ENOENT;
370+
371+
rc = memblock_phys_free(ima_kexec_buffer_phys,
372+
ima_kexec_buffer_size);
373+
if (rc)
374+
return rc;
375+
376+
ima_kexec_buffer_phys = 0;
377+
ima_kexec_buffer_size = 0;
378+
379+
return 0;
380+
}
381+
382+
int __init ima_get_kexec_buffer(void **addr, size_t *size)
383+
{
384+
if (!ima_kexec_buffer_size)
385+
return -ENOENT;
386+
387+
*addr = __va(ima_kexec_buffer_phys);
388+
*size = ima_kexec_buffer_size;
389+
390+
return 0;
391+
}
392+
#endif
393+
333394
static void __init parse_setup_data(void)
334395
{
335396
struct setup_data *data;
@@ -355,6 +416,18 @@ static void __init parse_setup_data(void)
355416
case SETUP_EFI:
356417
parse_efi_setup(pa_data, data_len);
357418
break;
419+
case SETUP_IMA:
420+
add_early_ima_buffer(pa_data);
421+
break;
422+
case SETUP_RNG_SEED:
423+
data = early_memremap(pa_data, data_len);
424+
add_bootloader_randomness(data->data, data->len);
425+
/* Zero seed for forward secrecy. */
426+
memzero_explicit(data->data, data->len);
427+
/* Zero length in case we find ourselves back here by accident. */
428+
memzero_explicit(&data->len, sizeof(data->len));
429+
early_memunmap(data, data_len);
430+
break;
358431
default:
359432
break;
360433
}

drivers/of/kexec.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* Copyright (C) 2016 IBM Corporation
1010
*/
1111

12+
#include <linux/ima.h>
1213
#include <linux/kernel.h>
1314
#include <linux/kexec.h>
1415
#include <linux/memblock.h>
@@ -115,23 +116,21 @@ static int do_get_kexec_buffer(const void *prop, int len, unsigned long *addr,
115116
return 0;
116117
}
117118

119+
#ifdef CONFIG_HAVE_IMA_KEXEC
118120
/**
119121
* ima_get_kexec_buffer - get IMA buffer from the previous kernel
120122
* @addr: On successful return, set to point to the buffer contents.
121123
* @size: On successful return, set to the buffer size.
122124
*
123125
* Return: 0 on success, negative errno on error.
124126
*/
125-
int ima_get_kexec_buffer(void **addr, size_t *size)
127+
int __init ima_get_kexec_buffer(void **addr, size_t *size)
126128
{
127129
int ret, len;
128130
unsigned long tmp_addr;
129131
size_t tmp_size;
130132
const void *prop;
131133

132-
if (!IS_ENABLED(CONFIG_HAVE_IMA_KEXEC))
133-
return -ENOTSUPP;
134-
135134
prop = of_get_property(of_chosen, "linux,ima-kexec-buffer", &len);
136135
if (!prop)
137136
return -ENOENT;
@@ -149,16 +148,13 @@ int ima_get_kexec_buffer(void **addr, size_t *size)
149148
/**
150149
* ima_free_kexec_buffer - free memory used by the IMA buffer
151150
*/
152-
int ima_free_kexec_buffer(void)
151+
int __init ima_free_kexec_buffer(void)
153152
{
154153
int ret;
155154
unsigned long addr;
156155
size_t size;
157156
struct property *prop;
158157

159-
if (!IS_ENABLED(CONFIG_HAVE_IMA_KEXEC))
160-
return -ENOTSUPP;
161-
162158
prop = of_find_property(of_chosen, "linux,ima-kexec-buffer", NULL);
163159
if (!prop)
164160
return -ENOENT;
@@ -173,6 +169,7 @@ int ima_free_kexec_buffer(void)
173169

174170
return memblock_phys_free(addr, size);
175171
}
172+
#endif
176173

177174
/**
178175
* remove_ima_buffer - remove the IMA buffer property and reservation from @fdt

include/linux/ima.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ static inline int ima_measure_critical_data(const char *event_label,
140140

141141
#endif /* CONFIG_IMA */
142142

143+
#ifdef CONFIG_HAVE_IMA_KEXEC
144+
int __init ima_free_kexec_buffer(void);
145+
int __init ima_get_kexec_buffer(void **addr, size_t *size);
146+
#endif
147+
143148
#ifdef CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT
144149
extern bool arch_ima_get_secureboot(void);
145150
extern const char * const *arch_get_ima_policy(void);

include/linux/of.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,8 +441,6 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image,
441441
unsigned long initrd_load_addr,
442442
unsigned long initrd_len,
443443
const char *cmdline, size_t extra_fdt_size);
444-
int ima_get_kexec_buffer(void **addr, size_t *size);
445-
int ima_free_kexec_buffer(void);
446444
#else /* CONFIG_OF */
447445

448446
static inline void of_core_init(void)

security/integrity/ima/ima_kexec.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ void ima_add_kexec_buffer(struct kimage *image)
137137
/*
138138
* Restore the measurement list from the previous kernel.
139139
*/
140-
void ima_load_kexec_buffer(void)
140+
void __init ima_load_kexec_buffer(void)
141141
{
142142
void *kexec_buffer = NULL;
143143
size_t kexec_buffer_size = 0;

0 commit comments

Comments
 (0)