On Mon, 2025-02-03 at 15:20 -0800, steven chen wrote: > 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(). Compare actual memory required to ensure > there is enough memory for the entire measurement record. > - Copy as many measurement events as possible. > - Make necessary changes to the function ima_add_kexec_buffer() to call > the above two functions. > - Compared the memory size allocated with memory size of the entire > measurement record. If there is not enough memory, it will copy as many > IMA measurement records as possible, and this situation will result > in a failure of remote attestation. > > Author: Tushar Sugandhi <tusharsu@xxxxxxxxxxxxxxxxxxx> > Reviewed-by: Stefan Berger <stefanb@xxxxxxxxxxxxx> > Suggested-by: Mimi Zohar <zohar@xxxxxxxxxxxxx> > Signed-off-by: Tushar Sugandhi <tusharsu@xxxxxxxxxxxxxxxxxxx> > Signed-off-by: steven chen <chenste@xxxxxxxxxxxxxxxxxxx> > --- > security/integrity/ima/ima.h | 1 + > security/integrity/ima/ima_kexec.c | 105 +++++++++++++++++++++-------- > security/integrity/ima/ima_queue.c | 4 +- > 3 files changed, 80 insertions(+), 30 deletions(-) > > diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h > index 3c323ca213d4..447a6eb07c2d 100644 > --- a/security/integrity/ima/ima.h > +++ b/security/integrity/ima/ima.h > @@ -274,6 +274,7 @@ bool ima_template_has_modsig(const struct ima_template_desc > *ima_template); > int ima_restore_measurement_entry(struct ima_template_entry *entry); > int ima_restore_measurement_list(loff_t bufsize, void *buf); > int ima_measurements_show(struct seq_file *m, void *v); > +int ima_get_binary_runtime_entry_size(struct ima_template_entry *entry); > unsigned long ima_get_binary_runtime_size(void); > int ima_init_template(void); > void ima_init_template_list(void); > diff --git a/security/integrity/ima/ima_kexec.c > b/security/integrity/ima/ima_kexec.c > index 52e00332defe..b60a902460e2 100644 > --- a/security/integrity/ima/ima_kexec.c > +++ b/security/integrity/ima/ima_kexec.c > @@ -15,62 +15,99 @@ > #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; > + } Nice cleanup from v5. The line doesn't doesn't need to be split. Both the parenthesis and the brackets can be removed. In the future, before posting patches, please use scripts/checkpatch.pl. CHECK: Unnecessary parentheses around 'ima_kexec_file.size == segment_size' #82: FILE: security/integrity/ima/ima_kexec.c:41: + if (ima_kexec_file.buf && + (ima_kexec_file.size == segment_size)) { CHECK: Alignment should match open parenthesis #83: FILE: security/integrity/ima/ima_kexec.c:42: + if (ima_kexec_file.buf && + (ima_kexec_file.size == segment_size)) { Or simply join the two lines. thanks, Mimi > + > + 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; > +} >