Commit e14555e3d0e9edfad0a6840c0152f71aba97e793

Authored by Nayna Jain
Committed by Michael Ellerman
1 parent 1917855f4e

ima: Make process_buffer_measurement() generic

process_buffer_measurement() is limited to measuring the kexec boot
command line. This patch makes process_buffer_measurement() more
generic, allowing it to measure other types of buffer data (e.g.
blacklisted binary hashes or key hashes).

process_buffer_measurement() may be called directly from an IMA hook
or as an auxiliary measurement record. In both cases the buffer
measurement is based on policy. This patch modifies the function to
conditionally retrieve the policy defined PCR and template for the IMA
hook case.

Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
[zohar@linux.ibm.com: added comment in process_buffer_measurement()]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/1572492694-6520-6-git-send-email-zohar@linux.ibm.com

Showing 2 changed files with 43 additions and 18 deletions Side-by-side Diff

security/integrity/ima/ima.h
... ... @@ -217,6 +217,9 @@
217 217 struct evm_ima_xattr_data *xattr_value,
218 218 int xattr_len, const struct modsig *modsig, int pcr,
219 219 struct ima_template_desc *template_desc);
  220 +void process_buffer_measurement(const void *buf, int size,
  221 + const char *eventname, enum ima_hooks func,
  222 + int pcr);
220 223 void ima_audit_measurement(struct integrity_iint_cache *iint,
221 224 const unsigned char *filename);
222 225 int ima_alloc_init_template(struct ima_event_data *event_data,
security/integrity/ima/ima_main.c
... ... @@ -626,14 +626,14 @@
626 626 * @buf: pointer to the buffer that needs to be added to the log.
627 627 * @size: size of buffer(in bytes).
628 628 * @eventname: event name to be used for the buffer entry.
629   - * @cred: a pointer to a credentials structure for user validation.
630   - * @secid: the secid of the task to be validated.
  629 + * @func: IMA hook
  630 + * @pcr: pcr to extend the measurement
631 631 *
632 632 * Based on policy, the buffer is measured into the ima log.
633 633 */
634   -static void process_buffer_measurement(const void *buf, int size,
635   - const char *eventname,
636   - const struct cred *cred, u32 secid)
  634 +void process_buffer_measurement(const void *buf, int size,
  635 + const char *eventname, enum ima_hooks func,
  636 + int pcr)
637 637 {
638 638 int ret = 0;
639 639 struct ima_template_entry *entry = NULL;
640 640  
641 641  
642 642  
643 643  
... ... @@ -642,20 +642,46 @@
642 642 .filename = eventname,
643 643 .buf = buf,
644 644 .buf_len = size};
645   - struct ima_template_desc *template_desc = NULL;
  645 + struct ima_template_desc *template = NULL;
646 646 struct {
647 647 struct ima_digest_data hdr;
648 648 char digest[IMA_MAX_DIGEST_SIZE];
649 649 } hash = {};
650 650 int violation = 0;
651   - int pcr = CONFIG_IMA_MEASURE_PCR_IDX;
652 651 int action = 0;
  652 + u32 secid;
653 653  
654   - action = ima_get_action(NULL, cred, secid, 0, KEXEC_CMDLINE, &pcr,
655   - &template_desc);
656   - if (!(action & IMA_MEASURE))
657   - return;
  654 + /*
  655 + * Both LSM hooks and auxilary based buffer measurements are
  656 + * based on policy. To avoid code duplication, differentiate
  657 + * between the LSM hooks and auxilary buffer measurements,
  658 + * retrieving the policy rule information only for the LSM hook
  659 + * buffer measurements.
  660 + */
  661 + if (func) {
  662 + security_task_getsecid(current, &secid);
  663 + action = ima_get_action(NULL, current_cred(), secid, 0, func,
  664 + &pcr, &template);
  665 + if (!(action & IMA_MEASURE))
  666 + return;
  667 + }
658 668  
  669 + if (!pcr)
  670 + pcr = CONFIG_IMA_MEASURE_PCR_IDX;
  671 +
  672 + if (!template) {
  673 + template = lookup_template_desc("ima-buf");
  674 + ret = template_desc_init_fields(template->fmt,
  675 + &(template->fields),
  676 + &(template->num_fields));
  677 + if (ret < 0) {
  678 + pr_err("template %s init failed, result: %d\n",
  679 + (strlen(template->name) ?
  680 + template->name : template->fmt), ret);
  681 + return;
  682 + }
  683 + }
  684 +
659 685 iint.ima_hash = &hash.hdr;
660 686 iint.ima_hash->algo = ima_hash_algo;
661 687 iint.ima_hash->length = hash_digest_size[ima_hash_algo];
... ... @@ -664,7 +690,7 @@
664 690 if (ret < 0)
665 691 goto out;
666 692  
667   - ret = ima_alloc_init_template(&event_data, &entry, template_desc);
  693 + ret = ima_alloc_init_template(&event_data, &entry, template);
668 694 if (ret < 0)
669 695 goto out;
670 696  
671 697  
... ... @@ -686,13 +712,9 @@
686 712 */
687 713 void ima_kexec_cmdline(const void *buf, int size)
688 714 {
689   - u32 secid;
690   -
691   - if (buf && size != 0) {
692   - security_task_getsecid(current, &secid);
  715 + if (buf && size != 0)
693 716 process_buffer_measurement(buf, size, "kexec-cmdline",
694   - current_cred(), secid);
695   - }
  717 + KEXEC_CMDLINE, 0);
696 718 }
697 719  
698 720 static int __init init_ima(void)