Hi Mimi, On Wed, 2026-06-24 at 21:05 -0400, Mimi Zohar wrote: > The Subject line describes "how", not "what". Consider renaming it to "ima: > measure userspace policy writes before parsing".
thank you, will fix it. > On Wed, 2026-06-17 at 17:58 +0200, Enrico Bravi wrote: > > When a signed policy is not mandatory, it is possible to write the IMA > > policy directly on the corresponding securityfs file: > > When a signed policy is not mandatory, userspace can write IMA policy rules > directly to the securityfs policy file: > > > > echo -e "measure func=BPRM_CHECK mask=MAY_EXEC\n" \ > > "audit func=BPRM_CHECK mask=MAY_EXEC\n" \ > > > /sys/kernel/security/ima/policy > > > > or by cat'ing the entire IMA custom policy file: > > > > cat ima-policy-file > /sys/kernel/security/ima/policy > > Because these rules originate from userspace and cross the userspace/kernel > trust boundary, measure the raw write buffer before parsing. Thanks for these suggestions, I'll update the patch description. > > > > Add input buffer measurement, regardless of whether the new policy > > will be accepted or not, that can be caught when > > 'measure func=POLICY_CHECK' is enabled (e.g., ima_policy=tcb). The > > measurement template is forced to ima-buf. > > > This follows the "measure & load" paradigm, exposing potential bugs in > > the policy code and detecting attempts to corrupt IMA. It also completes > > the POLICY_CHECK hook, which already measures partial policy load by file. > > > > > To verify the template data hash value, convert the buffer policy data > > to binary: > > grep "ima_policy_written" \ > > /sys/kernel/security/integrity/ima/ascii_runtime_measurements | \ > > tail -1 | cut -d' ' -f 6 | xxd -r -p | sha256sum > > > > Suggested-by: Roberto Sassu <[email protected]> > > Signed-off-by: Enrico Bravi <[email protected]> > > --- > > security/integrity/ima/ima.h | 1 + > > security/integrity/ima/ima_fs.c | 1 + > > security/integrity/ima/ima_main.c | 19 +++++++++++++++++++ > > security/integrity/ima/ima_policy.c | 3 +++ > > 4 files changed, 24 insertions(+) > > > > diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h > > index befa221716e5..d477fc06821f 100644 > > --- a/security/integrity/ima/ima.h > > +++ b/security/integrity/ima/ima.h > > @@ -455,6 +455,7 @@ void *ima_policy_next(struct seq_file *m, void *v, > > loff_t *pos); > > void ima_policy_stop(struct seq_file *m, void *v); > > int ima_policy_show(struct seq_file *m, void *v); > > void ima_measure_loaded_policy(void); > > +int ima_measure_policy_buf(const char *buf, size_t buf_len); > > > > /* Appraise integrity measurements */ > > #define IMA_APPRAISE_ENFORCE 0x01 > > diff --git a/security/integrity/ima/ima_fs.c > > b/security/integrity/ima/ima_fs.c > > index 65e7812c702f..a277c9135944 100644 > > --- a/security/integrity/ima/ima_fs.c > > +++ b/security/integrity/ima/ima_fs.c > > @@ -356,6 +356,7 @@ static ssize_t ima_write_policy(struct file *file, const > > char __user *buf, > > 1, 0); > > result = -EACCES; > > } else { > > + ima_measure_policy_buf(data, datalen); > > Should failure to measure the input policy rules be audited? process_buffer_measurement() is already auditing in case of failure before returning. Do you think it is necessary to audit also at this point? > > result = ima_parse_add_rule(data); > > } > > mutex_unlock(&ima_write_mutex); > > diff --git a/security/integrity/ima/ima_main.c > > b/security/integrity/ima/ima_main.c > > index 5cea53fc36df..599495304712 100644 > > --- a/security/integrity/ima/ima_main.c > > +++ b/security/integrity/ima/ima_main.c > > @@ -1221,6 +1221,25 @@ int ima_measure_critical_data(const char > > *event_label, > > } > > EXPORT_SYMBOL_GPL(ima_measure_critical_data); > > > > +/** > > + * ima_measure_policy_buf - Measure the policy write buffer > > Consider renaming this function to ima_measure_policy_input(), which parallels > the function ima_measure_loaded_policy() in the first patch. My intention with the previous ima_measure_policy_write() name was to highlight the fact it is not measuring every data sent to the policy file. For example, writing the path of the file from which reading the new policy does not trigger this measurement. Eventually, what do you think of ima_measure_raw_policy() or ima_measure_unparsed_policy()? Thank you very much, Enrico > Mimi > > > + * @buf: pointer to the buffer containing the policy write data > > + * @buf_len: size of the buffer > > + * > > + * Measure the buffer sent to the IMA policy securityfs file. > > + * > > + * Return 0 on success, a negative value otherwise. > > + */ > > +int ima_measure_policy_buf(const char *buf, size_t buf_len) > > +{ > > + if (!buf || !buf_len) > > + return -EINVAL; > > + > > + return process_buffer_measurement(&nop_mnt_idmap, NULL, buf, > > buf_len, > > + "ima_policy_written", > > POLICY_CHECK, 0, > > + NULL, false, NULL, 0); > > +} > > + > > #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS > > > > /**
