Re: [PATCHC v7 02/10] ima: on soft reboot, restore the measurement list

2016-11-16 Thread Dmitry Kasatkin
On Thu, Nov 10, 2016 at 4:56 PM, Mimi Zohar  wrote:
> The TPM PCRs are only reset on a hard reboot.  In order to validate a
> TPM's quote after a soft reboot (eg. kexec -e), the IMA measurement list
> of the running kernel must be saved and restored on boot.  This patch
> restores the measurement list.
>
> Changelog v7:
> - add and fix missing buffer length checking (reported by D. Kasatkin)
> - clean up ima_restore_measurement_list() a bit
>
> Changelog v5:
> - replace CONFIG_KEXEC_FILE with architecture CONFIG_HAVE_IMA_KEXEC (Thiago)
> - replace kexec_get_handover_buffer() with ima_get_kexec_buffer() (Thiago)
> - replace kexec_free_handover_buffer() with ima_free_kexec_buffer() (Thiago)
> - remove unnecessary includes from ima_kexec.c (Thiago)
> - fix off-by-one error when checking hdr_v1->template_name_len (Colin King)
>
> Changelog v2:
> - redefined ima_kexec_hdr to use types with well defined sizes (M. Ellerman)
> - defined missing ima_load_kexec_buffer() stub function
>
> Changelog v1:
> - call ima_load_kexec_buffer() (Thiago)
>
> Signed-off-by: Mimi Zohar 
> ---
>  security/integrity/ima/Makefile   |   1 +
>  security/integrity/ima/ima.h  |  21 
>  security/integrity/ima/ima_init.c |   2 +
>  security/integrity/ima/ima_kexec.c|  44 +
>  security/integrity/ima/ima_queue.c|  10 ++
>  security/integrity/ima/ima_template.c | 177 
> ++
>  6 files changed, 255 insertions(+)
>  create mode 100644 security/integrity/ima/ima_kexec.c
>
> diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
> index 9aeaedad1e2b..29f198bde02b 100644
> --- a/security/integrity/ima/Makefile
> +++ b/security/integrity/ima/Makefile
> @@ -8,4 +8,5 @@ obj-$(CONFIG_IMA) += ima.o
>  ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
>  ima_policy.o ima_template.o ima_template_lib.o
>  ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
> +ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
>  obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index db25f54a04fe..51dc8d57d64d 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -28,6 +28,10 @@
>
>  #include "../integrity.h"
>
> +#ifdef CONFIG_HAVE_IMA_KEXEC
> +#include 
> +#endif
> +
>  enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN,
>  IMA_SHOW_BINARY_OLD_STRING_FMT, IMA_SHOW_ASCII };
>  enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
> @@ -102,6 +106,21 @@ struct ima_queue_entry {
>  };
>  extern struct list_head ima_measurements;  /* list of all measurements */
>
> +/* Some details preceding the binary serialized measurement list */
> +struct ima_kexec_hdr {
> +   u16 version;
> +   u16 _reserved0;
> +   u32 _reserved1;
> +   u64 buffer_size;
> +   u64 count;
> +};
> +
> +#ifdef CONFIG_HAVE_IMA_KEXEC
> +void ima_load_kexec_buffer(void);
> +#else
> +static inline void ima_load_kexec_buffer(void) {}
> +#endif /* CONFIG_HAVE_IMA_KEXEC */
> +
>  /* Internal IMA function definitions */
>  int ima_init(void);
>  int ima_fs_init(void);
> @@ -122,6 +141,8 @@ int ima_init_crypto(void);
>  void ima_putc(struct seq_file *m, void *data, int datalen);
>  void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
>  struct ima_template_desc *ima_template_desc_current(void);
> +int ima_restore_measurement_entry(struct ima_template_entry *entry);
> +int ima_restore_measurement_list(loff_t bufsize, void *buf);
>  int ima_init_template(void);
>
>  /*
> diff --git a/security/integrity/ima/ima_init.c 
> b/security/integrity/ima/ima_init.c
> index 2ac1f41db5c0..2967d497a665 100644
> --- a/security/integrity/ima/ima_init.c
> +++ b/security/integrity/ima/ima_init.c
> @@ -129,6 +129,8 @@ int __init ima_init(void)
> if (rc != 0)
> return rc;
>
> +   ima_load_kexec_buffer();
> +
> rc = ima_add_boot_aggregate();  /* boot aggregate must be first entry 
> */
> if (rc != 0)
> return rc;
> diff --git a/security/integrity/ima/ima_kexec.c 
> b/security/integrity/ima/ima_kexec.c
> new file mode 100644
> index ..36afd0fe9747
> --- /dev/null
> +++ b/security/integrity/ima/ima_kexec.c
> @@ -0,0 +1,44 @@
> +/*
> + * Copyright (C) 2016 IBM Corporation
> + *
> + * Authors:
> + * Thiago Jung Bauermann 
> + * Mimi Zohar 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +#include "ima.h"
> +
> +/*
> + * Restore the measurement list from the previous kernel.
> + */
> +void ima_load_kexec_buffer(void)
> +{
> +   void *kexec_buffer = NULL;

Re: [PATCHC v7 02/10] ima: on soft reboot, restore the measurement list

2016-11-16 Thread Dmitry Kasatkin
On Thu, Nov 10, 2016 at 4:56 PM, Mimi Zohar  wrote:
> The TPM PCRs are only reset on a hard reboot.  In order to validate a
> TPM's quote after a soft reboot (eg. kexec -e), the IMA measurement list
> of the running kernel must be saved and restored on boot.  This patch
> restores the measurement list.
>
> Changelog v7:
> - add and fix missing buffer length checking (reported by D. Kasatkin)
> - clean up ima_restore_measurement_list() a bit
>
> Changelog v5:
> - replace CONFIG_KEXEC_FILE with architecture CONFIG_HAVE_IMA_KEXEC (Thiago)
> - replace kexec_get_handover_buffer() with ima_get_kexec_buffer() (Thiago)
> - replace kexec_free_handover_buffer() with ima_free_kexec_buffer() (Thiago)
> - remove unnecessary includes from ima_kexec.c (Thiago)
> - fix off-by-one error when checking hdr_v1->template_name_len (Colin King)
>
> Changelog v2:
> - redefined ima_kexec_hdr to use types with well defined sizes (M. Ellerman)
> - defined missing ima_load_kexec_buffer() stub function
>
> Changelog v1:
> - call ima_load_kexec_buffer() (Thiago)
>
> Signed-off-by: Mimi Zohar 
> ---
>  security/integrity/ima/Makefile   |   1 +
>  security/integrity/ima/ima.h  |  21 
>  security/integrity/ima/ima_init.c |   2 +
>  security/integrity/ima/ima_kexec.c|  44 +
>  security/integrity/ima/ima_queue.c|  10 ++
>  security/integrity/ima/ima_template.c | 177 
> ++
>  6 files changed, 255 insertions(+)
>  create mode 100644 security/integrity/ima/ima_kexec.c
>
> diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
> index 9aeaedad1e2b..29f198bde02b 100644
> --- a/security/integrity/ima/Makefile
> +++ b/security/integrity/ima/Makefile
> @@ -8,4 +8,5 @@ obj-$(CONFIG_IMA) += ima.o
>  ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
>  ima_policy.o ima_template.o ima_template_lib.o
>  ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
> +ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
>  obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index db25f54a04fe..51dc8d57d64d 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -28,6 +28,10 @@
>
>  #include "../integrity.h"
>
> +#ifdef CONFIG_HAVE_IMA_KEXEC
> +#include 
> +#endif
> +
>  enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN,
>  IMA_SHOW_BINARY_OLD_STRING_FMT, IMA_SHOW_ASCII };
>  enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
> @@ -102,6 +106,21 @@ struct ima_queue_entry {
>  };
>  extern struct list_head ima_measurements;  /* list of all measurements */
>
> +/* Some details preceding the binary serialized measurement list */
> +struct ima_kexec_hdr {
> +   u16 version;
> +   u16 _reserved0;
> +   u32 _reserved1;
> +   u64 buffer_size;
> +   u64 count;
> +};
> +
> +#ifdef CONFIG_HAVE_IMA_KEXEC
> +void ima_load_kexec_buffer(void);
> +#else
> +static inline void ima_load_kexec_buffer(void) {}
> +#endif /* CONFIG_HAVE_IMA_KEXEC */
> +
>  /* Internal IMA function definitions */
>  int ima_init(void);
>  int ima_fs_init(void);
> @@ -122,6 +141,8 @@ int ima_init_crypto(void);
>  void ima_putc(struct seq_file *m, void *data, int datalen);
>  void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
>  struct ima_template_desc *ima_template_desc_current(void);
> +int ima_restore_measurement_entry(struct ima_template_entry *entry);
> +int ima_restore_measurement_list(loff_t bufsize, void *buf);
>  int ima_init_template(void);
>
>  /*
> diff --git a/security/integrity/ima/ima_init.c 
> b/security/integrity/ima/ima_init.c
> index 2ac1f41db5c0..2967d497a665 100644
> --- a/security/integrity/ima/ima_init.c
> +++ b/security/integrity/ima/ima_init.c
> @@ -129,6 +129,8 @@ int __init ima_init(void)
> if (rc != 0)
> return rc;
>
> +   ima_load_kexec_buffer();
> +
> rc = ima_add_boot_aggregate();  /* boot aggregate must be first entry 
> */
> if (rc != 0)
> return rc;
> diff --git a/security/integrity/ima/ima_kexec.c 
> b/security/integrity/ima/ima_kexec.c
> new file mode 100644
> index ..36afd0fe9747
> --- /dev/null
> +++ b/security/integrity/ima/ima_kexec.c
> @@ -0,0 +1,44 @@
> +/*
> + * Copyright (C) 2016 IBM Corporation
> + *
> + * Authors:
> + * Thiago Jung Bauermann 
> + * Mimi Zohar 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +#include "ima.h"
> +
> +/*
> + * Restore the measurement list from the previous kernel.
> + */
> +void ima_load_kexec_buffer(void)
> +{
> +   void *kexec_buffer = NULL;
> +   size_t kexec_buffer_size = 0;
> +   int rc;
> +
> +   rc = ima_get_kexec_buffer(_buffer, 

[PATCHC v7 02/10] ima: on soft reboot, restore the measurement list

2016-11-10 Thread Mimi Zohar
The TPM PCRs are only reset on a hard reboot.  In order to validate a
TPM's quote after a soft reboot (eg. kexec -e), the IMA measurement list
of the running kernel must be saved and restored on boot.  This patch
restores the measurement list.

Changelog v7:
- add and fix missing buffer length checking (reported by D. Kasatkin)
- clean up ima_restore_measurement_list() a bit

Changelog v5:
- replace CONFIG_KEXEC_FILE with architecture CONFIG_HAVE_IMA_KEXEC (Thiago)
- replace kexec_get_handover_buffer() with ima_get_kexec_buffer() (Thiago)
- replace kexec_free_handover_buffer() with ima_free_kexec_buffer() (Thiago)
- remove unnecessary includes from ima_kexec.c (Thiago)
- fix off-by-one error when checking hdr_v1->template_name_len (Colin King)

Changelog v2:
- redefined ima_kexec_hdr to use types with well defined sizes (M. Ellerman)
- defined missing ima_load_kexec_buffer() stub function

Changelog v1:
- call ima_load_kexec_buffer() (Thiago)

Signed-off-by: Mimi Zohar 
---
 security/integrity/ima/Makefile   |   1 +
 security/integrity/ima/ima.h  |  21 
 security/integrity/ima/ima_init.c |   2 +
 security/integrity/ima/ima_kexec.c|  44 +
 security/integrity/ima/ima_queue.c|  10 ++
 security/integrity/ima/ima_template.c | 177 ++
 6 files changed, 255 insertions(+)
 create mode 100644 security/integrity/ima/ima_kexec.c

diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 9aeaedad1e2b..29f198bde02b 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -8,4 +8,5 @@ obj-$(CONFIG_IMA) += ima.o
 ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
 ima_policy.o ima_template.o ima_template_lib.o
 ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
+ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
 obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index db25f54a04fe..51dc8d57d64d 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -28,6 +28,10 @@
 
 #include "../integrity.h"
 
+#ifdef CONFIG_HAVE_IMA_KEXEC
+#include 
+#endif
+
 enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN,
 IMA_SHOW_BINARY_OLD_STRING_FMT, IMA_SHOW_ASCII };
 enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
@@ -102,6 +106,21 @@ struct ima_queue_entry {
 };
 extern struct list_head ima_measurements;  /* list of all measurements */
 
+/* Some details preceding the binary serialized measurement list */
+struct ima_kexec_hdr {
+   u16 version;
+   u16 _reserved0;
+   u32 _reserved1;
+   u64 buffer_size;
+   u64 count;
+};
+
+#ifdef CONFIG_HAVE_IMA_KEXEC
+void ima_load_kexec_buffer(void);
+#else
+static inline void ima_load_kexec_buffer(void) {}
+#endif /* CONFIG_HAVE_IMA_KEXEC */
+
 /* Internal IMA function definitions */
 int ima_init(void);
 int ima_fs_init(void);
@@ -122,6 +141,8 @@ int ima_init_crypto(void);
 void ima_putc(struct seq_file *m, void *data, int datalen);
 void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
 struct ima_template_desc *ima_template_desc_current(void);
+int ima_restore_measurement_entry(struct ima_template_entry *entry);
+int ima_restore_measurement_list(loff_t bufsize, void *buf);
 int ima_init_template(void);
 
 /*
diff --git a/security/integrity/ima/ima_init.c 
b/security/integrity/ima/ima_init.c
index 2ac1f41db5c0..2967d497a665 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -129,6 +129,8 @@ int __init ima_init(void)
if (rc != 0)
return rc;
 
+   ima_load_kexec_buffer();
+
rc = ima_add_boot_aggregate();  /* boot aggregate must be first entry */
if (rc != 0)
return rc;
diff --git a/security/integrity/ima/ima_kexec.c 
b/security/integrity/ima/ima_kexec.c
new file mode 100644
index ..36afd0fe9747
--- /dev/null
+++ b/security/integrity/ima/ima_kexec.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 IBM Corporation
+ *
+ * Authors:
+ * Thiago Jung Bauermann 
+ * Mimi Zohar 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include "ima.h"
+
+/*
+ * Restore the measurement list from the previous kernel.
+ */
+void ima_load_kexec_buffer(void)
+{
+   void *kexec_buffer = NULL;
+   size_t kexec_buffer_size = 0;
+   int rc;
+
+   rc = ima_get_kexec_buffer(_buffer, _buffer_size);
+   switch (rc) {
+   case 0:
+   rc = ima_restore_measurement_list(kexec_buffer_size,
+ kexec_buffer);
+   if (rc != 0)
+  

[PATCHC v7 02/10] ima: on soft reboot, restore the measurement list

2016-11-10 Thread Mimi Zohar
The TPM PCRs are only reset on a hard reboot.  In order to validate a
TPM's quote after a soft reboot (eg. kexec -e), the IMA measurement list
of the running kernel must be saved and restored on boot.  This patch
restores the measurement list.

Changelog v7:
- add and fix missing buffer length checking (reported by D. Kasatkin)
- clean up ima_restore_measurement_list() a bit

Changelog v5:
- replace CONFIG_KEXEC_FILE with architecture CONFIG_HAVE_IMA_KEXEC (Thiago)
- replace kexec_get_handover_buffer() with ima_get_kexec_buffer() (Thiago)
- replace kexec_free_handover_buffer() with ima_free_kexec_buffer() (Thiago)
- remove unnecessary includes from ima_kexec.c (Thiago)
- fix off-by-one error when checking hdr_v1->template_name_len (Colin King)

Changelog v2:
- redefined ima_kexec_hdr to use types with well defined sizes (M. Ellerman)
- defined missing ima_load_kexec_buffer() stub function

Changelog v1:
- call ima_load_kexec_buffer() (Thiago)

Signed-off-by: Mimi Zohar 
---
 security/integrity/ima/Makefile   |   1 +
 security/integrity/ima/ima.h  |  21 
 security/integrity/ima/ima_init.c |   2 +
 security/integrity/ima/ima_kexec.c|  44 +
 security/integrity/ima/ima_queue.c|  10 ++
 security/integrity/ima/ima_template.c | 177 ++
 6 files changed, 255 insertions(+)
 create mode 100644 security/integrity/ima/ima_kexec.c

diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 9aeaedad1e2b..29f198bde02b 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -8,4 +8,5 @@ obj-$(CONFIG_IMA) += ima.o
 ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
 ima_policy.o ima_template.o ima_template_lib.o
 ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
+ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
 obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index db25f54a04fe..51dc8d57d64d 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -28,6 +28,10 @@
 
 #include "../integrity.h"
 
+#ifdef CONFIG_HAVE_IMA_KEXEC
+#include 
+#endif
+
 enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN,
 IMA_SHOW_BINARY_OLD_STRING_FMT, IMA_SHOW_ASCII };
 enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
@@ -102,6 +106,21 @@ struct ima_queue_entry {
 };
 extern struct list_head ima_measurements;  /* list of all measurements */
 
+/* Some details preceding the binary serialized measurement list */
+struct ima_kexec_hdr {
+   u16 version;
+   u16 _reserved0;
+   u32 _reserved1;
+   u64 buffer_size;
+   u64 count;
+};
+
+#ifdef CONFIG_HAVE_IMA_KEXEC
+void ima_load_kexec_buffer(void);
+#else
+static inline void ima_load_kexec_buffer(void) {}
+#endif /* CONFIG_HAVE_IMA_KEXEC */
+
 /* Internal IMA function definitions */
 int ima_init(void);
 int ima_fs_init(void);
@@ -122,6 +141,8 @@ int ima_init_crypto(void);
 void ima_putc(struct seq_file *m, void *data, int datalen);
 void ima_print_digest(struct seq_file *m, u8 *digest, u32 size);
 struct ima_template_desc *ima_template_desc_current(void);
+int ima_restore_measurement_entry(struct ima_template_entry *entry);
+int ima_restore_measurement_list(loff_t bufsize, void *buf);
 int ima_init_template(void);
 
 /*
diff --git a/security/integrity/ima/ima_init.c 
b/security/integrity/ima/ima_init.c
index 2ac1f41db5c0..2967d497a665 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -129,6 +129,8 @@ int __init ima_init(void)
if (rc != 0)
return rc;
 
+   ima_load_kexec_buffer();
+
rc = ima_add_boot_aggregate();  /* boot aggregate must be first entry */
if (rc != 0)
return rc;
diff --git a/security/integrity/ima/ima_kexec.c 
b/security/integrity/ima/ima_kexec.c
new file mode 100644
index ..36afd0fe9747
--- /dev/null
+++ b/security/integrity/ima/ima_kexec.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 IBM Corporation
+ *
+ * Authors:
+ * Thiago Jung Bauermann 
+ * Mimi Zohar 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include "ima.h"
+
+/*
+ * Restore the measurement list from the previous kernel.
+ */
+void ima_load_kexec_buffer(void)
+{
+   void *kexec_buffer = NULL;
+   size_t kexec_buffer_size = 0;
+   int rc;
+
+   rc = ima_get_kexec_buffer(_buffer, _buffer_size);
+   switch (rc) {
+   case 0:
+   rc = ima_restore_measurement_list(kexec_buffer_size,
+ kexec_buffer);
+   if (rc != 0)
+   pr_err("Failed to restore the measurement list: %d\n",
+