Linux Documentation
 help / color / mirror / Atom feed
* [PATCH v7 22/27] binfmt_elf: Extract .note.gnu.property from an ELF file
From: Yu-cheng Yu @ 2019-06-06 20:06 UTC (permalink / raw)
  To: x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar, linux-kernel,
	linux-doc, linux-mm, linux-arch, linux-api, Arnd Bergmann,
	Andy Lutomirski, Balbir Singh, Borislav Petkov, Cyrill Gorcunov,
	Dave Hansen, Eugene Syromiatnikov, Florian Weimer, H.J. Lu,
	Jann Horn, Jonathan Corbet, Kees Cook, Mike Kravetz, Nadav Amit,
	Oleg Nesterov, Pavel Machek, Peter Zijlstra, Randy Dunlap,
	Ravi V. Shankar, Vedvyas Shanbhogue, Dave Martin
  Cc: Yu-cheng Yu
In-Reply-To: <20190606200646.3951-1-yu-cheng.yu@intel.com>

An ELF file's .note.gnu.property indicates features the executable file
can support.  For example, the property GNU_PROPERTY_X86_FEATURE_1_AND
indicates the file supports GNU_PROPERTY_X86_FEATURE_1_IBT and/or
GNU_PROPERTY_X86_FEATURE_1_SHSTK.

With this patch, if an arch needs to setup features from ELF properties,
it needs CONFIG_ARCH_USE_GNU_PROPERTY to be set, and a specific
arch_setup_property().

For example, for X86_64:

int arch_setup_property(void *ehdr, void *phdr, struct file *f, bool inter)
{
	int r;
	uint32_t property;

	r = get_gnu_property(ehdr, phdr, f, GNU_PROPERTY_X86_FEATURE_1_AND,
			     &property);
	...
}

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
---
 fs/Kconfig.binfmt        |   3 +
 fs/Makefile              |   1 +
 fs/binfmt_elf.c          |  13 ++
 fs/gnu_property.c        | 351 +++++++++++++++++++++++++++++++++++++++
 include/linux/elf.h      |  12 ++
 include/uapi/linux/elf.h |  14 ++
 6 files changed, 394 insertions(+)
 create mode 100644 fs/gnu_property.c

diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index f87ddd1b6d72..397138ab305b 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -36,6 +36,9 @@ config COMPAT_BINFMT_ELF
 config ARCH_BINFMT_ELF_STATE
 	bool
 
+config ARCH_USE_GNU_PROPERTY
+	bool
+
 config BINFMT_ELF_FDPIC
 	bool "Kernel support for FDPIC ELF binaries"
 	default y if !BINFMT_ELF
diff --git a/fs/Makefile b/fs/Makefile
index c9aea23aba56..b69f18c14e09 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_BINFMT_ELF)	+= binfmt_elf.o
 obj-$(CONFIG_COMPAT_BINFMT_ELF)	+= compat_binfmt_elf.o
 obj-$(CONFIG_BINFMT_ELF_FDPIC)	+= binfmt_elf_fdpic.o
 obj-$(CONFIG_BINFMT_FLAT)	+= binfmt_flat.o
+obj-$(CONFIG_ARCH_USE_GNU_PROPERTY) += gnu_property.o
 
 obj-$(CONFIG_FS_MBCACHE)	+= mbcache.o
 obj-$(CONFIG_FS_POSIX_ACL)	+= posix_acl.o
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 8264b468f283..c3ea73787e93 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1080,6 +1080,19 @@ static int load_elf_binary(struct linux_binprm *bprm)
 		goto out_free_dentry;
 	}
 
+	if (interpreter) {
+		retval = arch_setup_property(&loc->interp_elf_ex,
+					     interp_elf_phdata,
+					     interpreter, true);
+	} else {
+		retval = arch_setup_property(&loc->elf_ex,
+					     elf_phdata,
+					     bprm->file, false);
+	}
+
+	if (retval < 0)
+		goto out_free_dentry;
+
 	if (interpreter) {
 		unsigned long interp_map_addr = 0;
 
diff --git a/fs/gnu_property.c b/fs/gnu_property.c
new file mode 100644
index 000000000000..9c4d1d5ebf00
--- /dev/null
+++ b/fs/gnu_property.c
@@ -0,0 +1,351 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Extract an ELF file's .note.gnu.property.
+ *
+ * The path from the ELF header to the note section is the following:
+ * elfhdr->elf_phdr->elf_note->property[].
+ */
+
+#include <uapi/linux/elf-em.h>
+#include <linux/processor.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/string.h>
+#include <linux/compat.h>
+
+/*
+ * The .note.gnu.property layout:
+ *
+ *	struct elf_note {
+ *		u32 n_namesz; --> sizeof(n_name[]); always (4)
+ *		u32 n_ndescsz;--> sizeof(property[])
+ *		u32 n_type;   --> always NT_GNU_PROPERTY_TYPE_0
+ *	};
+ *	char n_name[4]; --> always 'GNU\0'
+ *
+ *	struct {
+ *		struct gnu_property {
+ *			u32 pr_type;
+ *			u32 pr_datasz;
+ *		};
+ *		u8 pr_data[pr_datasz];
+ *	}[];
+ */
+
+#define BUF_SIZE (PAGE_SIZE / 4)
+
+typedef bool (test_item_fn)(void *buf, u32 *arg, u32 type);
+typedef void *(next_item_fn)(void *buf, u32 *arg, u32 type);
+
+static inline bool test_note_type(void *buf, u32 *align, u32 note_type)
+{
+	struct elf_note *n = buf;
+
+	return ((n->n_type == note_type) && (n->n_namesz == 4) &&
+		(memcmp(n + 1, "GNU", 4) == 0));
+}
+
+static inline void *next_note(void *buf, u32 *align, u32 note_type)
+{
+	struct elf_note *n = buf;
+	u64 size;
+
+	if (check_add_overflow((u64)sizeof(*n), (u64)n->n_namesz, &size))
+		return NULL;
+
+	size = round_up(size, *align);
+
+	if (check_add_overflow(size, (u64)n->n_descsz, &size))
+		return NULL;
+
+	size = round_up(size, *align);
+
+	if (buf + size < buf)
+		return NULL;
+	else
+		return (buf + size);
+}
+
+static inline bool test_property(void *buf, u32 *max_type, u32 pr_type)
+{
+	struct gnu_property *pr = buf;
+
+	/*
+	 * Property types must be in ascending order.
+	 * Keep track of the max when testing each.
+	 */
+	if (pr->pr_type > *max_type)
+		*max_type = pr->pr_type;
+
+	return (pr->pr_type == pr_type);
+}
+
+static inline void *next_property(void *buf, u32 *max_type, u32 pr_type)
+{
+	struct gnu_property *pr = buf;
+
+	if ((buf + sizeof(*pr) +  pr->pr_datasz < buf) ||
+	    (pr->pr_type > pr_type) ||
+	    (pr->pr_type > *max_type))
+		return NULL;
+	else
+		return (buf + sizeof(*pr) + pr->pr_datasz);
+}
+
+/*
+ * Scan 'buf' for a pattern; return true if found.
+ * *pos is the distance from the beginning of buf to where
+ * the searched item or the next item is located.
+ */
+static int scan(u8 *buf, u32 buf_size, int item_size, test_item_fn test_item,
+		next_item_fn next_item, u32 *arg, u32 type, u32 *pos)
+{
+	int found = 0;
+	u8 *p, *max;
+
+	max = buf + buf_size;
+	if (max < buf)
+		return 0;
+
+	p = buf;
+
+	while ((p + item_size < max) && (p + item_size > buf)) {
+		if (test_item(p, arg, type)) {
+			found = 1;
+			break;
+		}
+
+		p = next_item(p, arg, type);
+	}
+
+	*pos = (p + item_size <= buf) ? 0 : (u32)(p - buf);
+	return found;
+}
+
+/*
+ * Search an NT_GNU_PROPERTY_TYPE_0 for the property of 'pr_type'.
+ */
+static int find_property(struct file *file, unsigned long desc_size,
+			 loff_t file_offset, u8 *buf,
+			 u32 pr_type, u32 *property)
+{
+	u32 buf_pos;
+	unsigned long read_size;
+	unsigned long done;
+	int found = 0;
+	int ret = 0;
+	u32 last_pr = 0;
+
+	*property = 0;
+	buf_pos = 0;
+
+	for (done = 0; done < desc_size; done += buf_pos) {
+		read_size = desc_size - done;
+		if (read_size > BUF_SIZE)
+			read_size = BUF_SIZE;
+
+		ret = kernel_read(file, buf, read_size, &file_offset);
+
+		if (ret != read_size)
+			return (ret < 0) ? ret : -EIO;
+
+		ret = 0;
+		found = scan(buf, read_size, sizeof(struct gnu_property),
+			     test_property, next_property,
+			     &last_pr, pr_type, &buf_pos);
+
+		if ((!buf_pos) || found)
+			break;
+
+		file_offset += buf_pos - read_size;
+	}
+
+	if (found) {
+		struct gnu_property *pr =
+			(struct gnu_property *)(buf + buf_pos);
+
+		if (pr->pr_datasz == 4) {
+			u32 *max =  (u32 *)(buf + read_size);
+			u32 *data = (u32 *)((u8 *)pr + sizeof(*pr));
+
+			if (data + 1 <= max) {
+				*property = *data;
+			} else {
+				file_offset += buf_pos - read_size;
+				file_offset += sizeof(*pr);
+				ret = kernel_read(file, property, 4,
+						  &file_offset);
+			}
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * Search a PT_NOTE segment for NT_GNU_PROPERTY_TYPE_0.
+ */
+static int find_note_type_0(struct file *file, loff_t file_offset,
+			    unsigned long note_size, u32 align,
+			    u32 pr_type, u32 *property)
+{
+	u8 *buf;
+	u32 buf_pos;
+	unsigned long read_size;
+	unsigned long done;
+	int found = 0;
+	int ret = 0;
+
+	buf = kmalloc(BUF_SIZE, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	*property = 0;
+	buf_pos = 0;
+
+	for (done = 0; done < note_size; done += buf_pos) {
+		read_size = note_size - done;
+		if (read_size > BUF_SIZE)
+			read_size = BUF_SIZE;
+
+		ret = kernel_read(file, buf, read_size, &file_offset);
+
+		if (ret != read_size) {
+			ret = (ret < 0) ? ret : -EIO;
+			kfree(buf);
+			return ret;
+		}
+
+		/*
+		 * item_size = sizeof(struct elf_note) + elf_note.n_namesz.
+		 * n_namesz is 4 for the note type we look for.
+		 */
+		ret = scan(buf, read_size, sizeof(struct elf_note) + 4,
+			      test_note_type, next_note,
+			      &align, NT_GNU_PROPERTY_TYPE_0, &buf_pos);
+
+		file_offset += buf_pos - read_size;
+
+		if (ret && !found) {
+			struct elf_note *n =
+				(struct elf_note *)(buf + buf_pos);
+			u64 start = round_up(sizeof(*n) + n->n_namesz, align);
+			u64 total = 0;
+
+			if (check_add_overflow(start, (u64)n->n_descsz, &total)) {
+				ret = -EINVAL;
+				break;
+			}
+			total = round_up(total, align);
+
+			ret = find_property(file, n->n_descsz,
+					    file_offset + start,
+					    buf, pr_type, property);
+			found++;
+			file_offset += total;
+			buf_pos += total;
+		} else if (!buf_pos || ret) {
+			ret = 0;
+			*property = 0;
+			break;
+		}
+	}
+
+	kfree(buf);
+	return ret;
+}
+
+/*
+ * Look at an ELF file's PT_NOTE segments, then NT_GNU_PROPERTY_TYPE_0, then
+ * the property of pr_type.
+ *
+ * Input:
+ *	file: the file to search;
+ *	phdr: the file's elf header;
+ *	phnum: number of entries in phdr;
+ *	pr_type: the property type.
+ *
+ * Output:
+ *	The property found.
+ *
+ * Return:
+ *	Zero or error.
+ */
+static int scan_segments_64(struct file *file, struct elf64_phdr *phdr,
+			    int phnum, u32 pr_type, u32 *property)
+{
+	int i;
+	int err = 0;
+
+	for (i = 0; i < phnum; i++, phdr++) {
+		if ((phdr->p_type != PT_NOTE) || (phdr->p_align != 8))
+			continue;
+
+		/*
+		 * Search the PT_NOTE segment for NT_GNU_PROPERTY_TYPE_0.
+		 */
+		err = find_note_type_0(file, phdr->p_offset, phdr->p_filesz,
+				       phdr->p_align, pr_type, property);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static int scan_segments_32(struct file *file, struct elf32_phdr *phdr,
+			    int phnum, u32 pr_type, u32 *property)
+{
+	int i;
+	int err = 0;
+
+	for (i = 0; i < phnum; i++, phdr++) {
+		if ((phdr->p_type != PT_NOTE) || (phdr->p_align != 4))
+			continue;
+
+		/*
+		 * Search the PT_NOTE segment for NT_GNU_PROPERTY_TYPE_0.
+		 */
+		err = find_note_type_0(file, phdr->p_offset, phdr->p_filesz,
+				       phdr->p_align, pr_type, property);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+int get_gnu_property(void *ehdr_p, void *phdr_p, struct file *f,
+		     u32 pr_type, u32 *property)
+{
+	struct elf64_hdr *ehdr64 = ehdr_p;
+	int err = 0;
+
+	*property = 0;
+
+	if (ehdr64->e_ident[EI_CLASS] == ELFCLASS64) {
+		struct elf64_phdr *phdr64 = phdr_p;
+
+		err = scan_segments_64(f, phdr64, ehdr64->e_phnum,
+				       pr_type, property);
+		if (err < 0)
+			goto out;
+	} else {
+		struct elf32_hdr *ehdr32 = ehdr_p;
+
+		if (ehdr32->e_ident[EI_CLASS] == ELFCLASS32) {
+			struct elf32_phdr *phdr32 = phdr_p;
+
+			err = scan_segments_32(f, phdr32, ehdr32->e_phnum,
+					       pr_type, property);
+			if (err < 0)
+				goto out;
+		}
+	}
+
+out:
+	return err;
+}
diff --git a/include/linux/elf.h b/include/linux/elf.h
index e3649b3e970e..c15febebe7f2 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -56,4 +56,16 @@ static inline int elf_coredump_extra_notes_write(struct coredump_params *cprm) {
 extern int elf_coredump_extra_notes_size(void);
 extern int elf_coredump_extra_notes_write(struct coredump_params *cprm);
 #endif
+
+#ifdef CONFIG_ARCH_USE_GNU_PROPERTY
+extern int arch_setup_property(void *ehdr, void *phdr, struct file *f,
+			       bool interp);
+extern int get_gnu_property(void *ehdr_p, void *phdr_p, struct file *f,
+			    u32 pr_type, u32 *feature);
+#else
+static inline int arch_setup_property(void *ehdr, void *phdr, struct file *f,
+				      bool interp) { return 0; }
+static inline int get_gnu_property(void *ehdr_p, void *phdr_p, struct file *f,
+				   u32 pr_type, u32 *feature) { return 0; }
+#endif
 #endif /* _LINUX_ELF_H */
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index 34c02e4290fe..316177ce9e76 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -372,6 +372,7 @@ typedef struct elf64_shdr {
 #define NT_PRFPREG	2
 #define NT_PRPSINFO	3
 #define NT_TASKSTRUCT	4
+#define NT_GNU_PROPERTY_TYPE_0 5
 #define NT_AUXV		6
 /*
  * Note to userspace developers: size of NT_SIGINFO note may increase
@@ -443,4 +444,17 @@ typedef struct elf64_note {
   Elf64_Word n_type;	/* Content type */
 } Elf64_Nhdr;
 
+/* NT_GNU_PROPERTY_TYPE_0 header */
+struct gnu_property {
+  __u32 pr_type;
+  __u32 pr_datasz;
+};
+
+/* .note.gnu.property types */
+#define GNU_PROPERTY_X86_FEATURE_1_AND		(0xc0000002)
+
+/* Bits of GNU_PROPERTY_X86_FEATURE_1_AND */
+#define GNU_PROPERTY_X86_FEATURE_1_IBT		(0x00000001)
+#define GNU_PROPERTY_X86_FEATURE_1_SHSTK	(0x00000002)
+
 #endif /* _UAPI_LINUX_ELF_H */
-- 
2.17.1


^ permalink raw reply related

* [PATCH v7 19/27] x86/cet/shstk: User-mode shadow stack support
From: Yu-cheng Yu @ 2019-06-06 20:06 UTC (permalink / raw)
  To: x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar, linux-kernel,
	linux-doc, linux-mm, linux-arch, linux-api, Arnd Bergmann,
	Andy Lutomirski, Balbir Singh, Borislav Petkov, Cyrill Gorcunov,
	Dave Hansen, Eugene Syromiatnikov, Florian Weimer, H.J. Lu,
	Jann Horn, Jonathan Corbet, Kees Cook, Mike Kravetz, Nadav Amit,
	Oleg Nesterov, Pavel Machek, Peter Zijlstra, Randy Dunlap,
	Ravi V. Shankar, Vedvyas Shanbhogue, Dave Martin
  Cc: Yu-cheng Yu
In-Reply-To: <20190606200646.3951-1-yu-cheng.yu@intel.com>

This patch adds basic shadow stack enabling/disabling routines.
A task's shadow stack is allocated from memory with VM_SHSTK flag set
and read-only protection.  It has a fixed size of RLIMIT_STACK.

Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
---
 arch/x86/include/asm/cet.h                    |  34 +++++
 arch/x86/include/asm/disabled-features.h      |   8 +-
 arch/x86/include/asm/msr-index.h              |  18 +++
 arch/x86/include/asm/processor.h              |   5 +
 arch/x86/kernel/Makefile                      |   2 +
 arch/x86/kernel/cet.c                         | 116 ++++++++++++++++++
 arch/x86/kernel/cpu/common.c                  |  25 ++++
 arch/x86/kernel/process.c                     |   1 +
 .../arch/x86/include/asm/disabled-features.h  |   8 +-
 9 files changed, 215 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/include/asm/cet.h
 create mode 100644 arch/x86/kernel/cet.c

diff --git a/arch/x86/include/asm/cet.h b/arch/x86/include/asm/cet.h
new file mode 100644
index 000000000000..c952a2ec65fe
--- /dev/null
+++ b/arch/x86/include/asm/cet.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_CET_H
+#define _ASM_X86_CET_H
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+struct task_struct;
+/*
+ * Per-thread CET status
+ */
+struct cet_status {
+	unsigned long	shstk_base;
+	unsigned long	shstk_size;
+	unsigned int	shstk_enabled:1;
+};
+
+#ifdef CONFIG_X86_INTEL_CET
+int cet_setup_shstk(void);
+void cet_disable_shstk(void);
+void cet_disable_free_shstk(struct task_struct *p);
+#else
+static inline int cet_setup_shstk(void) { return -EINVAL; }
+static inline void cet_disable_shstk(void) {}
+static inline void cet_disable_free_shstk(struct task_struct *p) {}
+#endif
+
+#define cpu_x86_cet_enabled() \
+	(cpu_feature_enabled(X86_FEATURE_SHSTK) || \
+	 cpu_feature_enabled(X86_FEATURE_IBT))
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_X86_CET_H */
diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h
index a5ea841cc6d2..06323ebed643 100644
--- a/arch/x86/include/asm/disabled-features.h
+++ b/arch/x86/include/asm/disabled-features.h
@@ -62,6 +62,12 @@
 # define DISABLE_PTI		(1 << (X86_FEATURE_PTI & 31))
 #endif
 
+#ifdef CONFIG_X86_INTEL_SHADOW_STACK_USER
+#define DISABLE_SHSTK	0
+#else
+#define DISABLE_SHSTK	(1<<(X86_FEATURE_SHSTK & 31))
+#endif
+
 /*
  * Make sure to add features to the correct mask
  */
@@ -81,7 +87,7 @@
 #define DISABLED_MASK13	0
 #define DISABLED_MASK14	0
 #define DISABLED_MASK15	0
-#define DISABLED_MASK16	(DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57|DISABLE_UMIP)
+#define DISABLED_MASK16	(DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57|DISABLE_UMIP|DISABLE_SHSTK)
 #define DISABLED_MASK17	0
 #define DISABLED_MASK18	0
 #define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 979ef971cc78..30e9107974fa 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -839,4 +839,22 @@
 #define MSR_VM_IGNNE                    0xc0010115
 #define MSR_VM_HSAVE_PA                 0xc0010117
 
+/* Control-flow Enforcement Technology MSRs */
+#define MSR_IA32_U_CET		0x6a0 /* user mode cet setting */
+#define MSR_IA32_S_CET		0x6a2 /* kernel mode cet setting */
+#define MSR_IA32_PL0_SSP	0x6a4 /* kernel shstk pointer */
+#define MSR_IA32_PL1_SSP	0x6a5 /* ring-1 shstk pointer */
+#define MSR_IA32_PL2_SSP	0x6a6 /* ring-2 shstk pointer */
+#define MSR_IA32_PL3_SSP	0x6a7 /* user shstk pointer */
+#define MSR_IA32_INT_SSP_TAB	0x6a8 /* exception shstk table */
+
+/* MSR_IA32_U_CET and MSR_IA32_S_CET bits */
+#define MSR_IA32_CET_SHSTK_EN		0x0000000000000001ULL
+#define MSR_IA32_CET_WRSS_EN		0x0000000000000002ULL
+#define MSR_IA32_CET_ENDBR_EN		0x0000000000000004ULL
+#define MSR_IA32_CET_LEG_IW_EN		0x0000000000000008ULL
+#define MSR_IA32_CET_NO_TRACK_EN	0x0000000000000010ULL
+#define MSR_IA32_CET_WAIT_ENDBR	0x00000000000000800UL
+#define MSR_IA32_CET_BITMAP_MASK	0xfffffffffffff000ULL
+
 #endif /* _ASM_X86_MSR_INDEX_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index c34a35c78618..2ae7c1bf4e43 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -24,6 +24,7 @@ struct vm86;
 #include <asm/special_insns.h>
 #include <asm/fpu/types.h>
 #include <asm/unwind_hints.h>
+#include <asm/cet.h>
 
 #include <linux/personality.h>
 #include <linux/cache.h>
@@ -487,6 +488,10 @@ struct thread_struct {
 	unsigned int		sig_on_uaccess_err:1;
 	unsigned int		uaccess_err:1;	/* uaccess failed */
 
+#ifdef CONFIG_X86_INTEL_CET
+	struct cet_status	cet;
+#endif
+
 	/* Floating point and extended processor state */
 	struct fpu		fpu;
 	/*
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index ce1b5cc360a2..584ed7e9a599 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -140,6 +140,8 @@ obj-$(CONFIG_UNWINDER_ORC)		+= unwind_orc.o
 obj-$(CONFIG_UNWINDER_FRAME_POINTER)	+= unwind_frame.o
 obj-$(CONFIG_UNWINDER_GUESS)		+= unwind_guess.o
 
+obj-$(CONFIG_X86_INTEL_CET)		+= cet.o
+
 ###
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
diff --git a/arch/x86/kernel/cet.c b/arch/x86/kernel/cet.c
new file mode 100644
index 000000000000..2a48634aa6ce
--- /dev/null
+++ b/arch/x86/kernel/cet.c
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * cet.c - Control-flow Enforcement (CET)
+ *
+ * Copyright (c) 2018, Intel Corporation.
+ * Yu-cheng Yu <yu-cheng.yu@intel.com>
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/sched/signal.h>
+#include <linux/compat.h>
+#include <asm/msr.h>
+#include <asm/user.h>
+#include <asm/fpu/internal.h>
+#include <asm/fpu/xstate.h>
+#include <asm/fpu/types.h>
+#include <asm/cet.h>
+
+static int set_shstk_ptr(unsigned long addr)
+{
+	u64 r;
+
+	if (!cpu_feature_enabled(X86_FEATURE_SHSTK))
+		return -1;
+
+	if ((addr >= TASK_SIZE_MAX) || (!IS_ALIGNED(addr, 4)))
+		return -1;
+
+	modify_fpu_regs_begin();
+	rdmsrl(MSR_IA32_U_CET, r);
+	wrmsrl(MSR_IA32_PL3_SSP, addr);
+	wrmsrl(MSR_IA32_U_CET, r | MSR_IA32_CET_SHSTK_EN);
+	modify_fpu_regs_end();
+	return 0;
+}
+
+static unsigned long get_shstk_addr(void)
+{
+	unsigned long ptr;
+
+	if (!current->thread.cet.shstk_enabled)
+		return 0;
+
+	modify_fpu_regs_begin();
+	rdmsrl(MSR_IA32_PL3_SSP, ptr);
+	modify_fpu_regs_end();
+	return ptr;
+}
+
+int cet_setup_shstk(void)
+{
+	unsigned long addr, size;
+
+	if (!cpu_feature_enabled(X86_FEATURE_SHSTK))
+		return -EOPNOTSUPP;
+
+	size = rlimit(RLIMIT_STACK);
+	addr = do_mmap_locked(0, size, PROT_READ,
+			      MAP_ANONYMOUS | MAP_PRIVATE, VM_SHSTK);
+
+	/*
+	 * Return actual error from do_mmap().
+	 */
+	if (addr >= TASK_SIZE_MAX)
+		return addr;
+
+	set_shstk_ptr(addr + size - sizeof(u64));
+	current->thread.cet.shstk_base = addr;
+	current->thread.cet.shstk_size = size;
+	current->thread.cet.shstk_enabled = 1;
+	return 0;
+}
+
+void cet_disable_shstk(void)
+{
+	u64 r;
+
+	if (!cpu_feature_enabled(X86_FEATURE_SHSTK))
+		return;
+
+	modify_fpu_regs_begin();
+	rdmsrl(MSR_IA32_U_CET, r);
+	r &= ~(MSR_IA32_CET_SHSTK_EN);
+	wrmsrl(MSR_IA32_U_CET, r);
+	wrmsrl(MSR_IA32_PL3_SSP, 0);
+	modify_fpu_regs_end();
+	current->thread.cet.shstk_enabled = 0;
+}
+
+void cet_disable_free_shstk(struct task_struct *tsk)
+{
+	if (!cpu_feature_enabled(X86_FEATURE_SHSTK) ||
+	    !tsk->thread.cet.shstk_enabled)
+		return;
+
+	if (tsk->mm && (tsk == current))
+		cet_disable_shstk();
+
+	/*
+	 * Free only when tsk is current or shares mm
+	 * with current but has its own shstk.
+	 */
+	if (tsk->mm && (tsk->mm == current->mm) &&
+	    (tsk->thread.cet.shstk_base)) {
+		vm_munmap(tsk->thread.cet.shstk_base,
+			  tsk->thread.cet.shstk_size);
+		tsk->thread.cet.shstk_base = 0;
+		tsk->thread.cet.shstk_size = 0;
+	}
+
+	tsk->thread.cet.shstk_enabled = 0;
+}
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 2c57fffebf9b..b0780fe8717e 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -53,6 +53,7 @@
 #include <asm/microcode_intel.h>
 #include <asm/intel-family.h>
 #include <asm/cpu_device_id.h>
+#include <asm/cet.h>
 
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/uv/uv.h>
@@ -417,6 +418,29 @@ static __init int setup_disable_pku(char *arg)
 __setup("nopku", setup_disable_pku);
 #endif /* CONFIG_X86_64 */
 
+static __always_inline void setup_cet(struct cpuinfo_x86 *c)
+{
+	if (cpu_x86_cet_enabled())
+		cr4_set_bits(X86_CR4_CET);
+}
+
+#ifdef CONFIG_X86_INTEL_SHADOW_STACK_USER
+static __init int setup_disable_shstk(char *s)
+{
+	/* require an exact match without trailing characters */
+	if (s[0] != '\0')
+		return 0;
+
+	if (!boot_cpu_has(X86_FEATURE_SHSTK))
+		return 1;
+
+	setup_clear_cpu_cap(X86_FEATURE_SHSTK);
+	pr_info("x86: 'no_cet_shstk' specified, disabling Shadow Stack\n");
+	return 1;
+}
+__setup("no_cet_shstk", setup_disable_shstk);
+#endif
+
 /*
  * Some CPU features depend on higher CPUID levels, which may not always
  * be available due to CPUID level capping or broken virtualization
@@ -1393,6 +1417,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)
 	x86_init_rdrand(c);
 	x86_init_cache_qos(c);
 	setup_pku(c);
+	setup_cet(c);
 
 	/*
 	 * Clear/Set all flags overridden by options, need do it
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index d360bf4d696b..a4deb79b1089 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -42,6 +42,7 @@
 #include <asm/prctl.h>
 #include <asm/spec-ctrl.h>
 #include <asm/proto.h>
+#include <asm/cet.h>
 
 #include "process.h"
 
diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h
index a5ea841cc6d2..06323ebed643 100644
--- a/tools/arch/x86/include/asm/disabled-features.h
+++ b/tools/arch/x86/include/asm/disabled-features.h
@@ -62,6 +62,12 @@
 # define DISABLE_PTI		(1 << (X86_FEATURE_PTI & 31))
 #endif
 
+#ifdef CONFIG_X86_INTEL_SHADOW_STACK_USER
+#define DISABLE_SHSTK	0
+#else
+#define DISABLE_SHSTK	(1<<(X86_FEATURE_SHSTK & 31))
+#endif
+
 /*
  * Make sure to add features to the correct mask
  */
@@ -81,7 +87,7 @@
 #define DISABLED_MASK13	0
 #define DISABLED_MASK14	0
 #define DISABLED_MASK15	0
-#define DISABLED_MASK16	(DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57|DISABLE_UMIP)
+#define DISABLED_MASK16	(DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57|DISABLE_UMIP|DISABLE_SHSTK)
 #define DISABLED_MASK17	0
 #define DISABLED_MASK18	0
 #define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
-- 
2.17.1


^ permalink raw reply related

* [PATCH v7 18/27] mm: Introduce do_mmap_locked()
From: Yu-cheng Yu @ 2019-06-06 20:06 UTC (permalink / raw)
  To: x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar, linux-kernel,
	linux-doc, linux-mm, linux-arch, linux-api, Arnd Bergmann,
	Andy Lutomirski, Balbir Singh, Borislav Petkov, Cyrill Gorcunov,
	Dave Hansen, Eugene Syromiatnikov, Florian Weimer, H.J. Lu,
	Jann Horn, Jonathan Corbet, Kees Cook, Mike Kravetz, Nadav Amit,
	Oleg Nesterov, Pavel Machek, Peter Zijlstra, Randy Dunlap,
	Ravi V. Shankar, Vedvyas Shanbhogue, Dave Martin
  Cc: Yu-cheng Yu
In-Reply-To: <20190606200646.3951-1-yu-cheng.yu@intel.com>

There are a few places that need do_mmap() with mm->mmap_sem held.
Create an in-line function for that.

Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
---
 include/linux/mm.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 398f1e1c35e5..7cf014604848 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2411,6 +2411,24 @@ static inline void mm_populate(unsigned long addr, unsigned long len)
 static inline void mm_populate(unsigned long addr, unsigned long len) {}
 #endif
 
+static inline unsigned long do_mmap_locked(unsigned long addr,
+	unsigned long len, unsigned long prot, unsigned long flags,
+	vm_flags_t vm_flags)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long populate;
+
+	down_write(&mm->mmap_sem);
+	addr = do_mmap(NULL, addr, len, prot, flags, vm_flags, 0,
+		       &populate, NULL);
+	up_write(&mm->mmap_sem);
+
+	if (populate)
+		mm_populate(addr, populate);
+
+	return addr;
+}
+
 /* These take the mm semaphore themselves */
 extern int __must_check vm_brk(unsigned long, unsigned long);
 extern int __must_check vm_brk_flags(unsigned long, unsigned long, unsigned long);
-- 
2.17.1


^ permalink raw reply related

* [PATCH v7 09/27] mm/mmap: Prevent Shadow Stack VMA merges
From: Yu-cheng Yu @ 2019-06-06 20:06 UTC (permalink / raw)
  To: x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar, linux-kernel,
	linux-doc, linux-mm, linux-arch, linux-api, Arnd Bergmann,
	Andy Lutomirski, Balbir Singh, Borislav Petkov, Cyrill Gorcunov,
	Dave Hansen, Eugene Syromiatnikov, Florian Weimer, H.J. Lu,
	Jann Horn, Jonathan Corbet, Kees Cook, Mike Kravetz, Nadav Amit,
	Oleg Nesterov, Pavel Machek, Peter Zijlstra, Randy Dunlap,
	Ravi V. Shankar, Vedvyas Shanbhogue, Dave Martin
  Cc: Yu-cheng Yu
In-Reply-To: <20190606200646.3951-1-yu-cheng.yu@intel.com>

To prevent function call/return spills into the next shadow stack
area, do not merge shadow stack areas.

Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
---
 mm/mmap.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/mm/mmap.c b/mm/mmap.c
index 7e8c3e8ae75f..b1a921c0de63 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1149,6 +1149,12 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
 	if (vm_flags & VM_SPECIAL)
 		return NULL;
 
+	/*
+	 * Do not merge shadow stack areas.
+	 */
+	if (vm_flags & VM_SHSTK)
+		return NULL;
+
 	if (prev)
 		next = prev->vm_next;
 	else
-- 
2.17.1


^ permalink raw reply related

* [PATCH v7 01/27] Documentation/x86: Add CET description
From: Yu-cheng Yu @ 2019-06-06 20:06 UTC (permalink / raw)
  To: x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar, linux-kernel,
	linux-doc, linux-mm, linux-arch, linux-api, Arnd Bergmann,
	Andy Lutomirski, Balbir Singh, Borislav Petkov, Cyrill Gorcunov,
	Dave Hansen, Eugene Syromiatnikov, Florian Weimer, H.J. Lu,
	Jann Horn, Jonathan Corbet, Kees Cook, Mike Kravetz, Nadav Amit,
	Oleg Nesterov, Pavel Machek, Peter Zijlstra, Randy Dunlap,
	Ravi V. Shankar, Vedvyas Shanbhogue, Dave Martin
  Cc: Yu-cheng Yu
In-Reply-To: <20190606200646.3951-1-yu-cheng.yu@intel.com>

Explain how CET works and the no_cet_shstk/no_cet_ibt kernel
parameters.

Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
---
 .../admin-guide/kernel-parameters.txt         |   6 +
 Documentation/x86/index.rst                   |   1 +
 Documentation/x86/intel_cet.rst               | 268 ++++++++++++++++++
 3 files changed, 275 insertions(+)
 create mode 100644 Documentation/x86/intel_cet.rst

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 138f6664b2e2..b9b054f6c732 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2906,6 +2906,12 @@
 			noexec=on: enable non-executable mappings (default)
 			noexec=off: disable non-executable mappings
 
+	no_cet_ibt	[X86-64] Disable indirect branch tracking for user-mode
+			applications
+
+	no_cet_shstk	[X86-64] Disable shadow stack support for user-mode
+			applications
+
 	nosmap		[X86,PPC]
 			Disable SMAP (Supervisor Mode Access Prevention)
 			even if it is supported by processor.
diff --git a/Documentation/x86/index.rst b/Documentation/x86/index.rst
index ae36fc5fc649..47822ac02fe0 100644
--- a/Documentation/x86/index.rst
+++ b/Documentation/x86/index.rst
@@ -21,6 +21,7 @@ x86-specific Documentation
    pat
    protection-keys
    intel_mpx
+   intel_cet
    amd-memory-encryption
    pti
    mds
diff --git a/Documentation/x86/intel_cet.rst b/Documentation/x86/intel_cet.rst
new file mode 100644
index 000000000000..dac83bbf8a24
--- /dev/null
+++ b/Documentation/x86/intel_cet.rst
@@ -0,0 +1,268 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=========================================
+Control-flow Enforcement Technology (CET)
+=========================================
+
+[1] Overview
+============
+
+Control-flow Enforcement Technology (CET) provides protection against
+return/jump-oriented programming (ROP) attacks.  It can be setup to
+protect both the kernel and applications.  In the first phase,
+only the user-mode protection is implemented in 64-bit mode; 32-bit
+applications are supported in compatibility mode.
+
+CET introduces shadow stack (SHSTK) and indirect branch tracking
+(IBT).  SHSTK is a secondary stack allocated from memory and cannot
+be directly modified by applications.  When executing a CALL, the
+processor pushes a copy of the return address to SHSTK.  Upon
+function return, the processor pops the SHSTK copy and compares it
+to the one from the program stack.  If the two copies differ, the
+processor raises a control-protection exception.  IBT verifies all
+indirect CALL/JMP targets are intended as marked by the compiler
+with 'ENDBR' opcodes (see CET instructions below).
+
+There are two kernel configuration options:
+
+    INTEL_X86_SHADOW_STACK_USER, and
+    INTEL_X86_BRANCH_TRACKING_USER.
+
+To build a CET-enabled kernel, Binutils v2.31 and GCC v8.1 or later
+are required.  To build a CET-enabled application, GLIBC v2.28 or
+later is also required.
+
+There are two command-line options for disabling CET features:
+
+    no_cet_shstk - disables SHSTK, and
+    no_cet_ibt - disables IBT.
+
+At run time, /proc/cpuinfo shows the availability of SHSTK and IBT.
+
+[2] CET assembly instructions
+=============================
+
+RDSSP %r
+    Read the SHSTK pointer into %r.
+
+INCSSP %r
+    Unwind (increment) the SHSTK pointer (0 ~ 255) steps as indicated
+    in the operand register.  The GLIBC longjmp uses INCSSP to unwind
+    the SHSTK until that matches the program stack.  When it is
+    necessary to unwind beyond 255 steps, longjmp divides and repeats
+    the process.
+
+RSTORSSP (%r)
+    Switch to the SHSTK indicated in the 'restore token' pointed by
+    the operand register and replace the 'restore token' with a new
+    token to be saved (with SAVEPREVSSP) for the outgoing SHSTK.
+
+::
+
+                               Before RSTORSSP
+
+             Incoming SHSTK                   Current/Outgoing SHSTK
+
+        |----------------------|             |----------------------|
+ addr=x |                      |       ssp-> |                      |
+        |----------------------|             |----------------------|
+ (%r)-> | rstor_token=(x|Lg)   |    addr=y-8 |                      |
+        |----------------------|             |----------------------|
+
+                               After RSTORSSP
+
+        |----------------------|             |----------------------|
+        |                      |             |                      |
+        |----------------------|             |----------------------|
+  ssp-> | rstor_token=(y|Bz|Lg)|    addr=y-8 |                      |
+        |----------------------|             |----------------------|
+
+    note:
+        1. Only valid addresses and restore tokens can be on the
+           user-mode SHSTK.
+        2. A token is always of type u64 and must align to u64.
+        3. The incoming SHSTK pointer in a rstor_token must point to
+           immediately above the token.
+        4. 'Lg' is bit[0] of a rstor_token indicating a 64-bit SHSTK.
+        5. 'Bz' is bit[1] of a rstor_token indicating the token is to
+           be used only for the next SAVEPREVSSP and invalid for the
+           RSTORSSP.
+
+SAVEPREVSSP
+    Store the SHSTK 'restore token' pointed by
+        (current_SHSTK_pointer + 8).
+
+::
+
+                             After SAVEPREVSSP
+
+        |----------------------|             |----------------------|
+  ssp-> |                      |             |                      |
+        |----------------------|             |----------------------|
+        | rstor_token=(y|Bz|Lg)|    addr=y-8 | rstor_token(y|Lg)    |
+        |----------------------|             |----------------------|
+
+WRUSS %r0, (%r1)
+    Write the value in %r0 to the SHSTK address pointed by (%r1).
+    This is a kernel-mode only instruction.
+
+ENDBR
+    The compiler inserts an ENDBR at all valid branch targets.  Any
+    CALL/JMP to a target without an ENDBR triggers a control
+    protection fault.
+
+[3] Application Enabling
+========================
+
+An application's CET capability is marked in its ELF header and can
+be verified from the following command output, in the
+NT_GNU_PROPERTY_TYPE_0 field:
+
+    readelf -n <application>
+
+If an application supports CET and is statically linked, it will run
+with CET protection.  If the application needs any shared libraries,
+the loader checks all dependencies and enables CET only when all
+requirements are met.
+
+[4] Legacy Libraries
+====================
+
+GLIBC provides a few tunables for backward compatibility.
+
+GLIBC_TUNABLES=glibc.tune.hwcaps=-SHSTK,-IBT
+    Turn off SHSTK/IBT for the current shell.
+
+GLIBC_TUNABLES=glibc.tune.x86_shstk=<on, permissive>
+    This controls how dlopen() handles SHSTK legacy libraries:
+        on: continue with SHSTK enabled;
+        permissive: continue with SHSTK off.
+
+[5] CET system calls
+====================
+
+The following arch_prctl() system calls are added for CET:
+
+arch_prctl(ARCH_X86_CET_STATUS, unsigned long *addr)
+    Return CET feature status.
+
+    The parameter 'addr' is a pointer to a user buffer.
+    On returning to the caller, the kernel fills the following
+    information:
+
+    *addr = SHSTK/IBT status
+    *(addr + 1) = SHSTK base address
+    *(addr + 2) = SHSTK size
+
+arch_prctl(ARCH_X86_CET_DISABLE, unsigned long features)
+    Disable SHSTK and/or IBT specified in 'features'.  Return -EPERM
+    if CET is locked.
+
+arch_prctl(ARCH_X86_CET_LOCK)
+    Lock in CET feature.
+
+arch_prctl(ARCH_X86_CET_ALLOC_SHSTK, unsigned long *addr)
+    Allocate a new SHSTK and put a restore token at top.
+
+    The parameter 'addr' is a pointer to a user buffer and indicates
+    the desired SHSTK size to allocate.  On returning to the caller,
+    the kernel fills *addr with the base address of the new SHSTK.
+
+arch_prctl(ARCH_X86_CET_SET_LEGACY_BITMAP, unsigned long *addr)
+    Setup an IBT legacy code bitmap.
+
+    The parameter 'addr' is a pointer to a user buffer that has the
+    following information:
+
+    *addr = IBT bitmap base address
+    *(addr + 1) = IBT bitmap size
+
+Note:
+  There is no CET enabling arch_prctl function.  By design, CET is
+  enabled automatically if the binary and the system can support it.
+
+  The parameters passed are always unsigned 64-bit.  When an ia32
+  application passing pointers, it should only use the lower 32 bits.
+
+[6] The implementation of the SHSTK
+===================================
+
+SHSTK size
+----------
+
+A task's SHSTK is allocated from memory to a fixed size of
+RLIMIT_STACK.  A compat-mode thread's SHSTK size is 1/4 of
+RLIMIT_STACK.  The smaller 32-bit thread SHSTK allows more threads to
+share a 32-bit address space.
+
+Signal
+------
+
+The main program and its signal handlers use the same SHSTK.  Because
+the SHSTK stores only return addresses, a large SHSTK will cover the
+condition that both the program stack and the sigaltstack run out.
+
+The kernel creates a restore token at the SHSTK restoring address and
+verifies that token when restoring from the signal handler.
+
+Fork
+----
+
+The SHSTK's vma has VM_SHSTK flag set; its PTEs are required to be
+read-only and dirty.  When a SHSTK PTE is not present, RO, and dirty,
+a SHSTK access triggers a page fault with an additional SHSTK bit set
+in the page fault error code.
+
+When a task forks a child, its SHSTK PTEs are copied and both the
+parent's and the child's SHSTK PTEs are cleared of the dirty bit.
+Upon the next SHSTK access, the resulting SHSTK page fault is handled
+by page copy/re-use.
+
+When a pthread child is created, the kernel allocates a new SHSTK for
+the new thread.
+
+Setjmp/Longjmp
+--------------
+
+Longjmp unwinds SHSTK until it matches the program stack.
+
+Ucontext
+--------
+
+In GLIBC, getcontext/setcontext is implemented in similar way as
+setjmp/longjmp.
+
+When makecontext creates a new ucontext, a new SHSTK is allocated for
+that context with ARCH_X86_CET_ALLOC_SHSTK the syscall.  The kernel
+creates a restore token at the top of the new SHSTK and the user-mode
+code switches to the new SHSTK with the RSTORSSP instruction.
+
+[7] The management of read-only & dirty PTEs for SHSTK
+======================================================
+
+A RO and dirty PTE exists in the following cases:
+
+(a) A page is modified and then shared with a fork()'ed child;
+(b) A R/O page that has been COW'ed;
+(c) A SHSTK page.
+
+The processor only checks the dirty bit for (c).  To prevent the use
+of non-SHSTK memory as SHSTK, we use a spare bit of the 64-bit PTE as
+DIRTY_SW for (a) and (b) above.  This results to the following PTE
+settings:
+
+Modified PTE:             (R/W + DIRTY_HW)
+Modified and shared PTE:  (R/O + DIRTY_SW)
+R/O PTE, COW'ed:          (R/O + DIRTY_SW)
+SHSTK PTE:                (R/O + DIRTY_HW)
+SHSTK PTE, COW'ed:        (R/O + DIRTY_HW)
+SHSTK PTE, shared:        (R/O + DIRTY_SW)
+
+Note that DIRTY_SW is only used in R/O PTEs but not R/W PTEs.
+
+[8] The implementation of IBT
+=============================
+
+The kernel provides IBT support in mmap() of the legacy code bit map.
+However, the management of the bitmap is done in the GLIBC or the
+application.
-- 
2.17.1


^ permalink raw reply related

* [PATCH v7 00/27] Control-flow Enforcement: Shadow Stack
From: Yu-cheng Yu @ 2019-06-06 20:06 UTC (permalink / raw)
  To: x86, H. Peter Anvin, Thomas Gleixner, Ingo Molnar, linux-kernel,
	linux-doc, linux-mm, linux-arch, linux-api, Arnd Bergmann,
	Andy Lutomirski, Balbir Singh, Borislav Petkov, Cyrill Gorcunov,
	Dave Hansen, Eugene Syromiatnikov, Florian Weimer, H.J. Lu,
	Jann Horn, Jonathan Corbet, Kees Cook, Mike Kravetz, Nadav Amit,
	Oleg Nesterov, Pavel Machek, Peter Zijlstra, Randy Dunlap,
	Ravi V. Shankar, Vedvyas Shanbhogue, Dave Martin
  Cc: Yu-cheng Yu

Intel has published Control-flow Enforcement (CET) in the Architecture
Instruction Set Extensions Programming Reference:

  https://software.intel.com/en-us/download/intel-architecture-instruction-set-
  extensions-programming-reference

The previous version (v6) of CET Shadow Stack patches is here:

  https://lkml.org/lkml/2018/11/20/225

Summary of changes from v6:

  Rebase to v5.2-rc3.

  Adapt XSAVES system state changes to the recent FPU changes:
    - Add modify_fpu_regs_begin(), modify_fpu_regs_end() to protect
      CET MSR changes.
    - Update signal handling.

  Move ELF header-parsing out of x86.

  Other small fixes in response to comments.

This version passed GLIBC built-in tests.

Hi Maintainers,

What else is needed before this series can be merged?

Thanks,
Yu-cheng


Yu-cheng Yu (27):
  Documentation/x86: Add CET description
  x86/cpufeatures: Add CET CPU feature flags for Control-flow
    Enforcement Technology (CET)
  x86/fpu/xstate: Change names to separate XSAVES system and user states
  x86/fpu/xstate: Introduce XSAVES system states
  x86/fpu/xstate: Add XSAVES system states for shadow stack
  x86/cet: Add control protection exception handler
  x86/cet/shstk: Add Kconfig option for user-mode shadow stack
  mm: Introduce VM_SHSTK for shadow stack memory
  mm/mmap: Prevent Shadow Stack VMA merges
  x86/mm: Change _PAGE_DIRTY to _PAGE_DIRTY_HW
  x86/mm: Introduce _PAGE_DIRTY_SW
  drm/i915/gvt: Update _PAGE_DIRTY to _PAGE_DIRTY_BITS
  x86/mm: Modify ptep_set_wrprotect and pmdp_set_wrprotect for
    _PAGE_DIRTY_SW
  x86/mm: Shadow stack page fault error checking
  mm: Handle shadow stack page fault
  mm: Handle THP/HugeTLB shadow stack page fault
  mm: Update can_follow_write_pte/pmd for shadow stack
  mm: Introduce do_mmap_locked()
  x86/cet/shstk: User-mode shadow stack support
  x86/cet/shstk: Introduce WRUSS instruction
  x86/cet/shstk: Handle signals for shadow stack
  binfmt_elf: Extract .note.gnu.property from an ELF file
  x86/cet/shstk: ELF header parsing of Shadow Stack
  x86/cet/shstk: Handle thread shadow stack
  mm/mmap: Add Shadow stack pages to memory accounting
  x86/cet/shstk: Add arch_prctl functions for Shadow Stack
  x86/cet/shstk: Add Shadow Stack instructions to opcode map

 .../admin-guide/kernel-parameters.txt         |   6 +
 Documentation/x86/index.rst                   |   1 +
 Documentation/x86/intel_cet.rst               | 268 +++++++++++++
 arch/x86/Kconfig                              |  26 ++
 arch/x86/Makefile                             |   7 +
 arch/x86/entry/entry_64.S                     |   2 +-
 arch/x86/ia32/ia32_signal.c                   |   8 +
 arch/x86/include/asm/cet.h                    |  48 +++
 arch/x86/include/asm/cpufeatures.h            |   2 +
 arch/x86/include/asm/disabled-features.h      |   8 +-
 arch/x86/include/asm/fpu/internal.h           |  25 +-
 arch/x86/include/asm/fpu/signal.h             |   2 +
 arch/x86/include/asm/fpu/types.h              |  22 ++
 arch/x86/include/asm/fpu/xstate.h             |  26 +-
 arch/x86/include/asm/mmu_context.h            |   3 +
 arch/x86/include/asm/msr-index.h              |  18 +
 arch/x86/include/asm/pgtable.h                | 191 ++++++++--
 arch/x86/include/asm/pgtable_types.h          |  38 +-
 arch/x86/include/asm/processor.h              |   5 +
 arch/x86/include/asm/special_insns.h          |  32 ++
 arch/x86/include/asm/traps.h                  |   5 +
 arch/x86/include/uapi/asm/prctl.h             |   5 +
 arch/x86/include/uapi/asm/processor-flags.h   |   2 +
 arch/x86/include/uapi/asm/sigcontext.h        |  15 +
 arch/x86/kernel/Makefile                      |   2 +
 arch/x86/kernel/cet.c                         | 327 ++++++++++++++++
 arch/x86/kernel/cet_prctl.c                   |  85 +++++
 arch/x86/kernel/cpu/common.c                  |  25 ++
 arch/x86/kernel/cpu/cpuid-deps.c              |   2 +
 arch/x86/kernel/fpu/core.c                    |  26 +-
 arch/x86/kernel/fpu/init.c                    |  10 -
 arch/x86/kernel/fpu/signal.c                  |  81 +++-
 arch/x86/kernel/fpu/xstate.c                  | 156 +++++---
 arch/x86/kernel/idt.c                         |   4 +
 arch/x86/kernel/process.c                     |   8 +-
 arch/x86/kernel/process_64.c                  |  31 ++
 arch/x86/kernel/relocate_kernel_64.S          |   2 +-
 arch/x86/kernel/signal.c                      |  10 +-
 arch/x86/kernel/signal_compat.c               |   2 +-
 arch/x86/kernel/traps.c                       |  57 +++
 arch/x86/kvm/vmx/vmx.c                        |   2 +-
 arch/x86/lib/x86-opcode-map.txt               |  26 +-
 arch/x86/mm/fault.c                           |  18 +
 arch/x86/mm/pgtable.c                         |  41 ++
 drivers/gpu/drm/i915/gvt/gtt.c                |   2 +-
 fs/Kconfig.binfmt                             |   3 +
 fs/Makefile                                   |   1 +
 fs/binfmt_elf.c                               |  13 +
 fs/gnu_property.c                             | 351 ++++++++++++++++++
 fs/proc/task_mmu.c                            |   3 +
 include/asm-generic/pgtable.h                 |  14 +
 include/linux/elf.h                           |  12 +
 include/linux/mm.h                            |  26 ++
 include/uapi/asm-generic/siginfo.h            |   3 +-
 include/uapi/linux/elf.h                      |  14 +
 mm/gup.c                                      |   8 +-
 mm/huge_memory.c                              |  12 +-
 mm/memory.c                                   |   7 +-
 mm/mmap.c                                     |  11 +
 .../arch/x86/include/asm/disabled-features.h  |   8 +-
 tools/objtool/arch/x86/lib/x86-opcode-map.txt |  26 +-
 61 files changed, 2029 insertions(+), 165 deletions(-)
 create mode 100644 Documentation/x86/intel_cet.rst
 create mode 100644 arch/x86/include/asm/cet.h
 create mode 100644 arch/x86/kernel/cet.c
 create mode 100644 arch/x86/kernel/cet_prctl.c
 create mode 100644 fs/gnu_property.c

-- 
2.17.1


^ permalink raw reply

* Re: [PATCH v2 1/2] hwmon: pmbus: Add Infineon PXE1610 VR driver
From: Vijay Khemka @ 2019-06-06 18:49 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Jean Delvare, Jonathan Corbet, linux-hwmon@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	joel@jms.id.au, linux-aspeed@lists.ozlabs.org, Sai Dasari,
	Greg Kroah-Hartman
In-Reply-To: <20190605204659.GA32329@roeck-us.net>



On 6/5/19, 1:47 PM, "Guenter Roeck" <groeck7@gmail.com on behalf of linux@roeck-us.net> wrote:

    On Thu, May 30, 2019 at 04:11:56PM -0700, Vijay Khemka wrote:
    > Added pmbus driver for the new device Infineon pxe1610
    > voltage regulator. It also supports similar family device
    > PXE1110 and PXM1310.
    > 
    > Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
    
    Applied.
Thanks
    
    Thanks,
    Guenter
    
    > ---
    > Changes in v2:
    > incorporated all the feedback from Guenter Roeck <linux@roeck-us.net>
    > 
    >  drivers/hwmon/pmbus/Kconfig   |   9 +++
    >  drivers/hwmon/pmbus/Makefile  |   1 +
    >  drivers/hwmon/pmbus/pxe1610.c | 139 ++++++++++++++++++++++++++++++++++
    >  3 files changed, 149 insertions(+)
    >  create mode 100644 drivers/hwmon/pmbus/pxe1610.c
    > 
    > diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
    > index 30751eb9550a..338ef9b5a395 100644
    > --- a/drivers/hwmon/pmbus/Kconfig
    > +++ b/drivers/hwmon/pmbus/Kconfig
    > @@ -154,6 +154,15 @@ config SENSORS_MAX8688
    >  	  This driver can also be built as a module. If so, the module will
    >  	  be called max8688.
    >  
    > +config SENSORS_PXE1610
    > +	tristate "Infineon PXE1610"
    > +	help
    > +	  If you say yes here you get hardware monitoring support for Infineon
    > +	  PXE1610.
    > +
    > +	  This driver can also be built as a module. If so, the module will
    > +	  be called pxe1610.
    > +
    >  config SENSORS_TPS40422
    >  	tristate "TI TPS40422"
    >  	help
    > diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
    > index 2219b9300316..b0fbd017a91a 100644
    > --- a/drivers/hwmon/pmbus/Makefile
    > +++ b/drivers/hwmon/pmbus/Makefile
    > @@ -18,6 +18,7 @@ obj-$(CONFIG_SENSORS_MAX20751)	+= max20751.o
    >  obj-$(CONFIG_SENSORS_MAX31785)	+= max31785.o
    >  obj-$(CONFIG_SENSORS_MAX34440)	+= max34440.o
    >  obj-$(CONFIG_SENSORS_MAX8688)	+= max8688.o
    > +obj-$(CONFIG_SENSORS_PXE1610)	+= pxe1610.o
    >  obj-$(CONFIG_SENSORS_TPS40422)	+= tps40422.o
    >  obj-$(CONFIG_SENSORS_TPS53679)	+= tps53679.o
    >  obj-$(CONFIG_SENSORS_UCD9000)	+= ucd9000.o
    > diff --git a/drivers/hwmon/pmbus/pxe1610.c b/drivers/hwmon/pmbus/pxe1610.c
    > new file mode 100644
    > index 000000000000..ebe3f023f840
    > --- /dev/null
    > +++ b/drivers/hwmon/pmbus/pxe1610.c
    > @@ -0,0 +1,139 @@
    > +// SPDX-License-Identifier: GPL-2.0+
    > +/*
    > + * Hardware monitoring driver for Infineon PXE1610
    > + *
    > + * Copyright (c) 2019 Facebook Inc
    > + *
    > + */
    > +
    > +#include <linux/err.h>
    > +#include <linux/i2c.h>
    > +#include <linux/init.h>
    > +#include <linux/kernel.h>
    > +#include <linux/module.h>
    > +#include "pmbus.h"
    > +
    > +#define PXE1610_NUM_PAGES 3
    > +
    > +/* Identify chip parameters. */
    > +static int pxe1610_identify(struct i2c_client *client,
    > +			     struct pmbus_driver_info *info)
    > +{
    > +	if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) {
    > +		u8 vout_mode;
    > +		int ret;
    > +
    > +		/* Read the register with VOUT scaling value.*/
    > +		ret = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE);
    > +		if (ret < 0)
    > +			return ret;
    > +
    > +		vout_mode = ret & GENMASK(4, 0);
    > +
    > +		switch (vout_mode) {
    > +		case 1:
    > +			info->vrm_version = vr12;
    > +			break;
    > +		case 2:
    > +			info->vrm_version = vr13;
    > +			break;
    > +		default:
    > +			return -ENODEV;
    > +		}
    > +	}
    > +
    > +	return 0;
    > +}
    > +
    > +static struct pmbus_driver_info pxe1610_info = {
    > +	.pages = PXE1610_NUM_PAGES,
    > +	.format[PSC_VOLTAGE_IN] = linear,
    > +	.format[PSC_VOLTAGE_OUT] = vid,
    > +	.format[PSC_CURRENT_IN] = linear,
    > +	.format[PSC_CURRENT_OUT] = linear,
    > +	.format[PSC_TEMPERATURE] = linear,
    > +	.format[PSC_POWER] = linear,
    > +	.func[0] = PMBUS_HAVE_VIN
    > +		| PMBUS_HAVE_VOUT | PMBUS_HAVE_IIN
    > +		| PMBUS_HAVE_IOUT | PMBUS_HAVE_PIN
    > +		| PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
    > +		| PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT
    > +		| PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP,
    > +	.func[1] = PMBUS_HAVE_VIN
    > +		| PMBUS_HAVE_VOUT | PMBUS_HAVE_IIN
    > +		| PMBUS_HAVE_IOUT | PMBUS_HAVE_PIN
    > +		| PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
    > +		| PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT
    > +		| PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP,
    > +	.func[2] = PMBUS_HAVE_VIN
    > +		| PMBUS_HAVE_VOUT | PMBUS_HAVE_IIN
    > +		| PMBUS_HAVE_IOUT | PMBUS_HAVE_PIN
    > +		| PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
    > +		| PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT
    > +		| PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP,
    > +	.identify = pxe1610_identify,
    > +};
    > +
    > +static int pxe1610_probe(struct i2c_client *client,
    > +			  const struct i2c_device_id *id)
    > +{
    > +	struct pmbus_driver_info *info;
    > +	u8 buf[I2C_SMBUS_BLOCK_MAX];
    > +	int ret;
    > +
    > +	if (!i2c_check_functionality(
    > +			client->adapter,
    > +			I2C_FUNC_SMBUS_READ_BYTE_DATA
    > +			| I2C_FUNC_SMBUS_READ_WORD_DATA
    > +			| I2C_FUNC_SMBUS_READ_BLOCK_DATA))
    > +		return -ENODEV;
    > +
    > +	/*
    > +	 * By default this device doesn't boot to page 0, so set page 0
    > +	 * to access all pmbus registers.
    > +	 */
    > +	i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
    > +
    > +	/* Read Manufacturer id */
    > +	ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf);
    > +	if (ret < 0) {
    > +		dev_err(&client->dev, "Failed to read PMBUS_MFR_ID\n");
    > +		return ret;
    > +	}
    > +	if (ret != 2 || strncmp(buf, "XP", 2)) {
    > +		dev_err(&client->dev, "MFR_ID unrecognized\n");
    > +		return -ENODEV;
    > +	}
    > +
    > +	info = devm_kmemdup(&client->dev, &pxe1610_info,
    > +			    sizeof(struct pmbus_driver_info),
    > +			    GFP_KERNEL);
    > +	if (!info)
    > +		return -ENOMEM;
    > +
    > +	return pmbus_do_probe(client, id, info);
    > +}
    > +
    > +static const struct i2c_device_id pxe1610_id[] = {
    > +	{"pxe1610", 0},
    > +	{"pxe1110", 0},
    > +	{"pxm1310", 0},
    > +	{}
    > +};
    > +
    > +MODULE_DEVICE_TABLE(i2c, pxe1610_id);
    > +
    > +static struct i2c_driver pxe1610_driver = {
    > +	.driver = {
    > +			.name = "pxe1610",
    > +			},
    > +	.probe = pxe1610_probe,
    > +	.remove = pmbus_do_remove,
    > +	.id_table = pxe1610_id,
    > +};
    > +
    > +module_i2c_driver(pxe1610_driver);
    > +
    > +MODULE_AUTHOR("Vijay Khemka <vijaykhemka@fb.com>");
    > +MODULE_DESCRIPTION("PMBus driver for Infineon PXE1610, PXE1110 and PXM1310");
    > +MODULE_LICENSE("GPL");
    


^ permalink raw reply

* Re: [PATCH v2 2/2] Docs: hwmon: pmbus: Add PXE1610 driver
From: Vijay Khemka @ 2019-06-06 18:49 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Jean Delvare, Jonathan Corbet, linux-hwmon@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	joel@jms.id.au, linux-aspeed@lists.ozlabs.org, Sai Dasari,
	Greg Kroah-Hartman
In-Reply-To: <20190605204811.GA32379@roeck-us.net>



On 6/5/19, 1:48 PM, "Guenter Roeck" <groeck7@gmail.com on behalf of linux@roeck-us.net> wrote:

    On Thu, May 30, 2019 at 04:11:57PM -0700, Vijay Khemka wrote:
    > Added support for Infenion PXE1610 driver
    > 
    Applied, after fixing
    	s/Infenion/Infineon/
    	s/Infinion/Infineon/
Thanks
    
    Guenter
    
    > Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
    > ---
    > Changes in v2:
    > incorporated all the feedback from Guenter Roeck <linux@roeck-us.net>
    > 
    >  Documentation/hwmon/pxe1610 | 90 +++++++++++++++++++++++++++++++++++++
    >  1 file changed, 90 insertions(+)
    >  create mode 100644 Documentation/hwmon/pxe1610
    > 
    > diff --git a/Documentation/hwmon/pxe1610 b/Documentation/hwmon/pxe1610
    > new file mode 100644
    > index 000000000000..24825db8736f
    > --- /dev/null
    > +++ b/Documentation/hwmon/pxe1610
    > @@ -0,0 +1,90 @@
    > +Kernel driver pxe1610
    > +=====================
    > +
    > +Supported chips:
    > +  * Infinion PXE1610
    > +    Prefix: 'pxe1610'
    > +    Addresses scanned: -
    > +    Datasheet: Datasheet is not publicly available.
    > +
    > +  * Infinion PXE1110
    > +    Prefix: 'pxe1110'
    > +    Addresses scanned: -
    > +    Datasheet: Datasheet is not publicly available.
    > +
    > +  * Infinion PXM1310
    > +    Prefix: 'pxm1310'
    > +    Addresses scanned: -
    > +    Datasheet: Datasheet is not publicly available.
    > +
    > +Author: Vijay Khemka <vijaykhemka@fb.com>
    > +
    > +
    > +Description
    > +-----------
    > +
    > +PXE1610/PXE1110 are Multi-rail/Multiphase Digital Controllers
    > +and compliant to
    > +	-- Intel VR13 DC-DC converter specifications.
    > +	-- Intel SVID protocol.
    > +Used for Vcore power regulation for Intel VR13 based microprocessors
    > +	-- Servers, Workstations, and High-end desktops
    > +
    > +PXM1310 is a Multi-rail Controllers and it is compliant to
    > +	-- Intel VR13 DC-DC converter specifications.
    > +	-- Intel SVID protocol.
    > +Used for DDR3/DDR4 Memory power regulation for Intel VR13 and
    > +IMVP8 based systems
    > +
    > +
    > +Usage Notes
    > +-----------
    > +
    > +This driver does not probe for PMBus devices. You will have
    > +to instantiate devices explicitly.
    > +
    > +Example: the following commands will load the driver for an PXE1610
    > +at address 0x70 on I2C bus #4:
    > +
    > +# modprobe pxe1610
    > +# echo pxe1610 0x70 > /sys/bus/i2c/devices/i2c-4/new_device
    > +
    > +It can also be instantiated by declaring in device tree
    > +
    > +
    > +Sysfs attributes
    > +----------------
    > +
    > +curr1_label		"iin"
    > +curr1_input		Measured input current
    > +curr1_alarm		Current high alarm
    > +
    > +curr[2-4]_label		"iout[1-3]"
    > +curr[2-4]_input		Measured output current
    > +curr[2-4]_crit		Critical maximum current
    > +curr[2-4]_crit_alarm	Current critical high alarm
    > +
    > +in1_label		"vin"
    > +in1_input		Measured input voltage
    > +in1_crit		Critical maximum input voltage
    > +in1_crit_alarm		Input voltage critical high alarm
    > +
    > +in[2-4]_label		"vout[1-3]"
    > +in[2-4]_input		Measured output voltage
    > +in[2-4]_lcrit		Critical minimum output voltage
    > +in[2-4]_lcrit_alarm	Output voltage critical low alarm
    > +in[2-4]_crit		Critical maximum output voltage
    > +in[2-4]_crit_alarm	Output voltage critical high alarm
    > +
    > +power1_label		"pin"
    > +power1_input		Measured input power
    > +power1_alarm		Input power high alarm
    > +
    > +power[2-4]_label	"pout[1-3]"
    > +power[2-4]_input	Measured output power
    > +
    > +temp[1-3]_input		Measured temperature
    > +temp[1-3]_crit		Critical high temperature
    > +temp[1-3]_crit_alarm	Chip temperature critical high alarm
    > +temp[1-3]_max		Maximum temperature
    > +temp[1-3]_max_alarm	Chip temperature high alarm
    


^ permalink raw reply

* Re: [PATCH v1] docs/core-api: Add string helpers API to the list
From: Jonathan Corbet @ 2019-06-06 16:01 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: linux-doc, Andrew Morton, Mike Rapoport
In-Reply-To: <20190605163944.50803-1-andriy.shevchenko@linux.intel.com>

On Wed,  5 Jun 2019 19:39:44 +0300
Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:

> Some times string helpers are needed, but there is nothing about them
> in the generated documentation.
> 
> Fill the gap by adding a reference to string_helpers.c exported functions.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

So I've applied this (and the integer power functions one too), but let me
grumble for just a moment...

This patch adds a set of new warnings to the docs build:

> +./lib/string_helpers.c:236: WARNING: Unexpected indentation.
> +./lib/string_helpers.c:241: WARNING: Block quote ends without a blank line; unexpected unindent.
> +./lib/string_helpers.c:446: WARNING: Unexpected indentation.
> +./lib/string_helpers.c:451: WARNING: Block quote ends without a blank line; unexpected unindent.
> +./lib/string_helpers.c:474: WARNING: Unexpected indentation.

It would be *really* nice if folks would check for these things and fix
them when they arise.  The docs build is a horrific mess of warnings that
will never get better if we keep adding more.  This one is an easy fix;
I'll toss together a patch to do it.

Beyond that (and this is in no way your fault, I'm just whining)
kernel-api.rst has become a huge dumping ground.  Someday it would sure be
nice if we could create a bit more order there...

Thanks,

jon

^ permalink raw reply

* Re: [PATCH] docs: filesystems: vfs: Render method descriptions
From: Jonathan Corbet @ 2019-06-06 15:46 UTC (permalink / raw)
  To: Tobin C. Harding
  Cc: Al Viro, Neil Brown, Randy Dunlap, linux-doc, linux-fsdevel,
	linux-kernel
In-Reply-To: <20190604002656.30925-1-tobin@kernel.org>

On Tue,  4 Jun 2019 10:26:56 +1000
"Tobin C. Harding" <tobin@kernel.org> wrote:

> Currently vfs.rst does not render well into HTML the method descriptions
> for VFS data structures.  We can improve the HTML output by putting the
> description string on a new line following the method name.
> 
> Suggested-by: Jonathan Corbet <corbet@lwn.net>
> Signed-off-by: Tobin C. Harding <tobin@kernel.org>
> ---
> 
> Jon,
> 
> As discussed on LKML; this patch applies on top of the series
> 
> 	[PATCH v4 0/9] docs: Convert VFS doc to RST
> 
> If it does not apply cleanly to your branch please feel free to ask me
> to fix it.

There was one merge conflict, but nothing too serious.  I've applied it,
and things look a lot better - thanks!

jon

^ permalink raw reply

* Re: [PATCH v3 0/2] ima/evm fixes for v5.2
From: Roberto Sassu @ 2019-06-06 15:22 UTC (permalink / raw)
  To: Mimi Zohar, dmitry.kasatkin, mjg59
  Cc: linux-integrity, linux-security-module, linux-doc, stable,
	linux-kernel, silviu.vlasceanu
In-Reply-To: <1559832596.4278.124.camel@linux.ibm.com>

On 6/6/2019 4:49 PM, Mimi Zohar wrote:
> On Thu, 2019-06-06 at 13:43 +0200, Roberto Sassu wrote:
>> On 6/6/2019 1:26 PM, Roberto Sassu wrote:
>>> Previous versions included the patch 'ima: don't ignore INTEGRITY_UNKNOWN
>>> EVM status'. However, I realized that this patch cannot be accepted alone
>>> because IMA-Appraisal would deny access to new files created during the
>>> boot. With the current behavior, those files are accessible because they
>>> have a valid security.ima (not protected by EVM) created after the first
>>> write.
>>>
>>> A solution for this problem is to initialize EVM very early with a random
>>> key. Access to created files will be granted, even with the strict
>>> appraisal, because after the first write those files will have both
>>> security.ima and security.evm (HMAC calculated with the random key).
>>>
>>> Strict appraisal will work only if it is done with signatures until the
>>> persistent HMAC key is loaded.
>>
>> Changelog
>>
>> v2:
>> - remove patch 1/3 (evm: check hash algorithm passed to init_desc());
>>     already accepted
>> - remove patch 3/3 (ima: show rules with IMA_INMASK correctly);
>>     already accepted
>> - add new patch (evm: add option to set a random HMAC key at early boot)
>> - patch 2/3: modify patch description
> 
> Roberto, as I tried explaining previously, this feature is not a
> simple bug fix.  These patches, if upstreamed, will be upstreamed the
> normal way, during an open window.  Whether they are classified as a
> bug fix has yet to be decided.

Sorry, I understood that I can claim that there is a bug. I provided a
motivation in patch 2/2.


> Please stop Cc'ing stable.  If I don't Cc stable before sending the pull request, then Greg and Sasha have been really good about deciding which patches should be backported.  (Please refer to the comment on "Cc'ing stable" in section "5) Select the recipients for your patch" in Documentation/process/submitting-patches.rst.)
> 
> I'll review these patches, but in the future please use an appropriate patch set cover letter title in the subject line.

Ok.

Thanks

Roberto

-- 
HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Bo PENG, Jian LI, Yanli SHI

^ permalink raw reply

* Re: [PATCH 03/10] mfd / platform: cros_ec: Miscellaneous character device to talk with the EC
From: Ezequiel Garcia @ 2019-06-06 15:12 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Guenter Roeck, Enric Balletbo i Serra, linux-kernel,
	Gwendal Grignou, Guenter Roeck, Benson Leung, Lee Jones, kernel,
	Dmitry Torokhov, Gustavo Pimentel, Randy Dunlap,
	Lorenzo Pieralisi, linux-doc, Enno Luebbers, Guido Kiener,
	Thomas Gleixner, Kishon Vijay Abraham I, Jonathan Corbet, Wu Hao,
	Kate Stewart, Tycho Andersen, Gerd Hoffmann, Jilayne Lovejoy
In-Reply-To: <20190606145121.GA13048@kroah.com>

On Thu, 2019-06-06 at 16:51 +0200, Greg Kroah-Hartman wrote:
> On Thu, Jun 06, 2019 at 11:01:17AM -0300, Ezequiel Garcia wrote:
> > On Tue, 2019-06-04 at 20:59 +0200, Greg Kroah-Hartman wrote:
> > > On Tue, Jun 04, 2019 at 11:39:21AM -0700, Guenter Roeck wrote:
> > > > On Tue, Jun 4, 2019 at 11:35 AM Greg Kroah-Hartman
> > > > <gregkh@linuxfoundation.org> wrote:
> > > > > On Tue, Jun 04, 2019 at 01:58:38PM -0300, Ezequiel Garcia wrote:
> > > > > > Hey Greg,
> > > > > > 
> > > > > > > > + dev_info(&pdev->dev, "Created misc device /dev/%s\n",
> > > > > > > > +          data->misc.name);
> > > > > > > 
> > > > > > > No need to be noisy, if all goes well, your code should be quiet.
> > > > > > > 
> > > > > > 
> > > > > > I sometimes wonder about this being noise or not, so I will slightly
> > > > > > hijack this thread for this discussion.
> > > > > > 
> > > > > > > From a kernel developer point-of-view, or even from a platform
> > > > > > developer or user with a debugging hat point-of-view, having
> > > > > > a "device created" or "device registered" message is often very useful.
> > > > > 
> > > > > For you, yes.  For someone with 30000 devices attached to their system,
> > > > > it is not, and causes booting to take longer than it should be.
> > > > > 
> > > > > > In fact, I wish people would do this more often, so I don't have to
> > > > > > deal with dynamic debug, or hack my way:
> > > > > > 
> > > > > > diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
> > > > > > index 4589631798c9..473549b26bb2 100644
> > > > > > --- a/drivers/media/i2c/ov5647.c
> > > > > > +++ b/drivers/media/i2c/ov5647.c
> > > > > > @@ -603,7 +603,7 @@ static int ov5647_probe(struct i2c_client *client,
> > > > > >         if (ret < 0)
> > > > > >                 goto error;
> > > > > > 
> > > > > > -       dev_dbg(dev, "OmniVision OV5647 camera driver probed\n");
> > > > > > +       dev_info(dev, "OmniVision OV5647 camera driver probed\n");
> > > > > >         return 0;
> > > > > >  error:
> > > > > >         media_entity_cleanup(&sd->entity);
> > > > > > 
> > > > > > In some subsystems, it's even a behavior I'm more or less relying on:
> > > > > > 
> > > > > > $ git grep v4l2_info.*registered drivers/media/ | wc -l
> > > > > > 26
> > > > > > 
> > > > > > And on the downsides, I can't find much. It's just one little line,
> > > > > > that is not even noticed unless you have logging turned on.
> > > > > 
> > > > > Its better to be quiet, which is why the "default driver registration"
> > > > > macros do not have any printk messages in them.  When converting drivers
> > > > > over to it, we made the boot process much more sane, don't try to go and
> > > > > add messages for no good reason back in please.
> > > > > 
> > > > > dynamic debugging can be enabled on a module and line-by-line basis,
> > > > > even from the boot command line.  So if you need debugging, you can
> > > > > always ask someone to just reboot or unload/load the module and get the
> > > > > message that way.
> > > > > 
> > > > 
> > > > Can we by any chance make this an official policy ? I am kind of tired
> > > > having to argue about this over and over again.
> > > 
> > > Sure, but how does anyone make any "official policy" in the kernel?  :)
> > > 
> > > I could just go through and delete all "look ma, a new driver/device!"
> > > messages, but that might be annoying...
> > > 
> > 
> > Well, I really need to task.
> 
> ???
> 

Oops, typo: s/task/ask :-)

> > If it's not an official policy (and won't be anytime soon?),
> 
> The ":)" there was that we really have very few "official" policies,
> only things that we all strongly encourage to happen.  And get grumpy if
> we see them in code reviews.  Like I did here.
> 

Well, not everyone gets grumpy. As I pointed out, we use this "registered"
messages (messages or noise, seems this lie in the eye of the beholder),
consistently across entire subsystems.

> > then what's preventing Enric from pushing this print on this driver,
> > given he is the one maintaining the code?
> 
> Given that he wants people to review his code, why would you tell him to
> ignore what people are trying to tell him?
> 

I'm not suggesting to ignore anyone, rather to consider all voices
involved in each review comment.

> Again, don't be noisy, it's not hard, and is how things have been
> trending for many years now.
> 

Thanks,
Eze


^ permalink raw reply

* Re: [char-misc-next 3/7 RESEND] mei: docs: update mei documentation
From: Greg Kroah-Hartman @ 2019-06-06 14:51 UTC (permalink / raw)
  To: Tomas Winkler; +Cc: Alexander Usyskin, linux-kernel, Jonathan Corbet, linux-doc
In-Reply-To: <20190606133108.26964-1-tomas.winkler@intel.com>

On Thu, Jun 06, 2019 at 04:31:08PM +0300, Tomas Winkler wrote:
> The mei driver went via multiple changes, update
> the documentation and fix formatting.
> 
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> ---
>  Documentation/driver-api/mei/mei.rst | 96 ++++++++++++++++++----------
>  1 file changed, 61 insertions(+), 35 deletions(-)

that worked, thanks!

greg k-h

^ permalink raw reply

* Re: [PATCH 03/10] mfd / platform: cros_ec: Miscellaneous character device to talk with the EC
From: Greg Kroah-Hartman @ 2019-06-06 14:51 UTC (permalink / raw)
  To: Ezequiel Garcia
  Cc: Guenter Roeck, Enric Balletbo i Serra, linux-kernel,
	Gwendal Grignou, Guenter Roeck, Benson Leung, Lee Jones, kernel,
	Dmitry Torokhov, Gustavo Pimentel, Randy Dunlap,
	Lorenzo Pieralisi, linux-doc, Enno Luebbers, Guido Kiener,
	Thomas Gleixner, Kishon Vijay Abraham I, Jonathan Corbet, Wu Hao,
	Kate Stewart, Tycho Andersen, Gerd Hoffmann, Jilayne Lovejoy
In-Reply-To: <bda48bf80add26153e531912fbfca25071934c94.camel@collabora.com>

On Thu, Jun 06, 2019 at 11:01:17AM -0300, Ezequiel Garcia wrote:
> On Tue, 2019-06-04 at 20:59 +0200, Greg Kroah-Hartman wrote:
> > On Tue, Jun 04, 2019 at 11:39:21AM -0700, Guenter Roeck wrote:
> > > On Tue, Jun 4, 2019 at 11:35 AM Greg Kroah-Hartman
> > > <gregkh@linuxfoundation.org> wrote:
> > > > On Tue, Jun 04, 2019 at 01:58:38PM -0300, Ezequiel Garcia wrote:
> > > > > Hey Greg,
> > > > > 
> > > > > > > + dev_info(&pdev->dev, "Created misc device /dev/%s\n",
> > > > > > > +          data->misc.name);
> > > > > > 
> > > > > > No need to be noisy, if all goes well, your code should be quiet.
> > > > > > 
> > > > > 
> > > > > I sometimes wonder about this being noise or not, so I will slightly
> > > > > hijack this thread for this discussion.
> > > > > 
> > > > > > From a kernel developer point-of-view, or even from a platform
> > > > > developer or user with a debugging hat point-of-view, having
> > > > > a "device created" or "device registered" message is often very useful.
> > > > 
> > > > For you, yes.  For someone with 30000 devices attached to their system,
> > > > it is not, and causes booting to take longer than it should be.
> > > > 
> > > > > In fact, I wish people would do this more often, so I don't have to
> > > > > deal with dynamic debug, or hack my way:
> > > > > 
> > > > > diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
> > > > > index 4589631798c9..473549b26bb2 100644
> > > > > --- a/drivers/media/i2c/ov5647.c
> > > > > +++ b/drivers/media/i2c/ov5647.c
> > > > > @@ -603,7 +603,7 @@ static int ov5647_probe(struct i2c_client *client,
> > > > >         if (ret < 0)
> > > > >                 goto error;
> > > > > 
> > > > > -       dev_dbg(dev, "OmniVision OV5647 camera driver probed\n");
> > > > > +       dev_info(dev, "OmniVision OV5647 camera driver probed\n");
> > > > >         return 0;
> > > > >  error:
> > > > >         media_entity_cleanup(&sd->entity);
> > > > > 
> > > > > In some subsystems, it's even a behavior I'm more or less relying on:
> > > > > 
> > > > > $ git grep v4l2_info.*registered drivers/media/ | wc -l
> > > > > 26
> > > > > 
> > > > > And on the downsides, I can't find much. It's just one little line,
> > > > > that is not even noticed unless you have logging turned on.
> > > > 
> > > > Its better to be quiet, which is why the "default driver registration"
> > > > macros do not have any printk messages in them.  When converting drivers
> > > > over to it, we made the boot process much more sane, don't try to go and
> > > > add messages for no good reason back in please.
> > > > 
> > > > dynamic debugging can be enabled on a module and line-by-line basis,
> > > > even from the boot command line.  So if you need debugging, you can
> > > > always ask someone to just reboot or unload/load the module and get the
> > > > message that way.
> > > > 
> > > 
> > > Can we by any chance make this an official policy ? I am kind of tired
> > > having to argue about this over and over again.
> > 
> > Sure, but how does anyone make any "official policy" in the kernel?  :)
> > 
> > I could just go through and delete all "look ma, a new driver/device!"
> > messages, but that might be annoying...
> > 
> 
> Well, I really need to task.

???

> If it's not an official policy (and won't be anytime soon?),

The ":)" there was that we really have very few "official" policies,
only things that we all strongly encourage to happen.  And get grumpy if
we see them in code reviews.  Like I did here.

> then what's preventing Enric from pushing this print on this driver,
> given he is the one maintaining the code?

Given that he wants people to review his code, why would you tell him to
ignore what people are trying to tell him?

Again, don't be noisy, it's not hard, and is how things have been
trending for many years now.

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH v3 0/2] ima/evm fixes for v5.2
From: Mimi Zohar @ 2019-06-06 14:49 UTC (permalink / raw)
  To: Roberto Sassu, dmitry.kasatkin, mjg59
  Cc: linux-integrity, linux-security-module, linux-doc, stable,
	linux-kernel, silviu.vlasceanu
In-Reply-To: <3711f387-3aef-9fbb-1bb4-dded6807b033@huawei.com>

On Thu, 2019-06-06 at 13:43 +0200, Roberto Sassu wrote:
> On 6/6/2019 1:26 PM, Roberto Sassu wrote:
> > Previous versions included the patch 'ima: don't ignore INTEGRITY_UNKNOWN
> > EVM status'. However, I realized that this patch cannot be accepted alone
> > because IMA-Appraisal would deny access to new files created during the
> > boot. With the current behavior, those files are accessible because they
> > have a valid security.ima (not protected by EVM) created after the first
> > write.
> > 
> > A solution for this problem is to initialize EVM very early with a random
> > key. Access to created files will be granted, even with the strict
> > appraisal, because after the first write those files will have both
> > security.ima and security.evm (HMAC calculated with the random key).
> > 
> > Strict appraisal will work only if it is done with signatures until the
> > persistent HMAC key is loaded.
> 
> Changelog
> 
> v2:
> - remove patch 1/3 (evm: check hash algorithm passed to init_desc());
>    already accepted
> - remove patch 3/3 (ima: show rules with IMA_INMASK correctly);
>    already accepted
> - add new patch (evm: add option to set a random HMAC key at early boot)
> - patch 2/3: modify patch description

Roberto, as I tried explaining previously, this feature is not a
simple bug fix.  These patches, if upstreamed, will be upstreamed the
normal way, during an open window.  Whether they are classified as a
bug fix has yet to be decided.

Please stop Cc'ing stable.  If I don't Cc stable before sending the pull request, then Greg and Sasha have been really good about deciding which patches should be backported.  (Please refer to the comment on "Cc'ing stable" in section "5) Select the recipients for your patch" in Documentation/process/submitting-patches.rst.)

I'll review these patches, but in the future please use an appropriate patch set cover letter title in the subject line.

thanks,

Mimi


> 
> v1:
> - remove patch 2/4 (evm: reset status in evm_inode_post_setattr()); file
>    attributes cannot be set if the signature is portable and immutable
> - patch 3/4: add __ro_after_init to ima_appraise_req_evm variable
>    declaration
> - patch 3/4: remove ima_appraise_req_evm kernel option and introduce
>    'enforce-evm' and 'log-evm' as possible values for ima_appraise=
> - remove patch 4/4 (ima: only audit failed appraisal verifications)
> - add new patch (ima: show rules with IMA_INMASK correctly)
> 
> 
> > Roberto Sassu (2):
> >    evm: add option to set a random HMAC key at early boot
> >    ima: add enforce-evm and log-evm modes to strictly check EVM status
> > 
> >   .../admin-guide/kernel-parameters.txt         | 11 ++--
> >   security/integrity/evm/evm.h                  | 10 +++-
> >   security/integrity/evm/evm_crypto.c           | 57 ++++++++++++++++---
> >   security/integrity/evm/evm_main.c             | 41 ++++++++++---
> >   security/integrity/ima/ima_appraise.c         |  8 +++
> >   security/integrity/integrity.h                |  1 +
> >   6 files changed, 106 insertions(+), 22 deletions(-)
> > 
> 


^ permalink raw reply

* Re: [PATCH 03/10] mfd / platform: cros_ec: Miscellaneous character device to talk with the EC
From: Ezequiel Garcia @ 2019-06-06 14:01 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Guenter Roeck
  Cc: Enric Balletbo i Serra, linux-kernel, Gwendal Grignou,
	Guenter Roeck, Benson Leung, Lee Jones, kernel, Dmitry Torokhov,
	Gustavo Pimentel, Randy Dunlap, Lorenzo Pieralisi, linux-doc,
	Enno Luebbers, Guido Kiener, Thomas Gleixner,
	Kishon Vijay Abraham I, Jonathan Corbet, Wu Hao, Kate Stewart,
	Tycho Andersen, Gerd Hoffmann, Jilayne Lovejoy
In-Reply-To: <20190604185953.GA2061@kroah.com>

On Tue, 2019-06-04 at 20:59 +0200, Greg Kroah-Hartman wrote:
> On Tue, Jun 04, 2019 at 11:39:21AM -0700, Guenter Roeck wrote:
> > On Tue, Jun 4, 2019 at 11:35 AM Greg Kroah-Hartman
> > <gregkh@linuxfoundation.org> wrote:
> > > On Tue, Jun 04, 2019 at 01:58:38PM -0300, Ezequiel Garcia wrote:
> > > > Hey Greg,
> > > > 
> > > > > > + dev_info(&pdev->dev, "Created misc device /dev/%s\n",
> > > > > > +          data->misc.name);
> > > > > 
> > > > > No need to be noisy, if all goes well, your code should be quiet.
> > > > > 
> > > > 
> > > > I sometimes wonder about this being noise or not, so I will slightly
> > > > hijack this thread for this discussion.
> > > > 
> > > > > From a kernel developer point-of-view, or even from a platform
> > > > developer or user with a debugging hat point-of-view, having
> > > > a "device created" or "device registered" message is often very useful.
> > > 
> > > For you, yes.  For someone with 30000 devices attached to their system,
> > > it is not, and causes booting to take longer than it should be.
> > > 
> > > > In fact, I wish people would do this more often, so I don't have to
> > > > deal with dynamic debug, or hack my way:
> > > > 
> > > > diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
> > > > index 4589631798c9..473549b26bb2 100644
> > > > --- a/drivers/media/i2c/ov5647.c
> > > > +++ b/drivers/media/i2c/ov5647.c
> > > > @@ -603,7 +603,7 @@ static int ov5647_probe(struct i2c_client *client,
> > > >         if (ret < 0)
> > > >                 goto error;
> > > > 
> > > > -       dev_dbg(dev, "OmniVision OV5647 camera driver probed\n");
> > > > +       dev_info(dev, "OmniVision OV5647 camera driver probed\n");
> > > >         return 0;
> > > >  error:
> > > >         media_entity_cleanup(&sd->entity);
> > > > 
> > > > In some subsystems, it's even a behavior I'm more or less relying on:
> > > > 
> > > > $ git grep v4l2_info.*registered drivers/media/ | wc -l
> > > > 26
> > > > 
> > > > And on the downsides, I can't find much. It's just one little line,
> > > > that is not even noticed unless you have logging turned on.
> > > 
> > > Its better to be quiet, which is why the "default driver registration"
> > > macros do not have any printk messages in them.  When converting drivers
> > > over to it, we made the boot process much more sane, don't try to go and
> > > add messages for no good reason back in please.
> > > 
> > > dynamic debugging can be enabled on a module and line-by-line basis,
> > > even from the boot command line.  So if you need debugging, you can
> > > always ask someone to just reboot or unload/load the module and get the
> > > message that way.
> > > 
> > 
> > Can we by any chance make this an official policy ? I am kind of tired
> > having to argue about this over and over again.
> 
> Sure, but how does anyone make any "official policy" in the kernel?  :)
> 
> I could just go through and delete all "look ma, a new driver/device!"
> messages, but that might be annoying...
> 

Well, I really need to task.

If it's not an official policy (and won't be anytime soon?), then
what's preventing Enric from pushing this print on this driver,
given he is the one maintaining the code?

Thanks,
Eze


^ permalink raw reply

* [char-misc-next 3/7 RESEND] mei: docs: update mei documentation
From: Tomas Winkler @ 2019-06-06 13:31 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Alexander Usyskin, linux-kernel, Tomas Winkler, Jonathan Corbet,
	linux-doc

The mei driver went via multiple changes, update
the documentation and fix formatting.

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
 Documentation/driver-api/mei/mei.rst | 96 ++++++++++++++++++----------
 1 file changed, 61 insertions(+), 35 deletions(-)

diff --git a/Documentation/driver-api/mei/mei.rst b/Documentation/driver-api/mei/mei.rst
index c7f10a4b46ff..c800d8e5f422 100644
--- a/Documentation/driver-api/mei/mei.rst
+++ b/Documentation/driver-api/mei/mei.rst
@@ -5,34 +5,32 @@ Introduction
 
 The Intel Management Engine (Intel ME) is an isolated and protected computing
 resource (Co-processor) residing inside certain Intel chipsets. The Intel ME
-provides support for computer/IT management features. The feature set
-depends on the Intel chipset SKU.
+provides support for computer/IT management and security features.
+The actual feature set depends on the Intel chipset SKU.
 
 The Intel Management Engine Interface (Intel MEI, previously known as HECI)
 is the interface between the Host and Intel ME. This interface is exposed
-to the host as a PCI device. The Intel MEI Driver is in charge of the
-communication channel between a host application and the Intel ME feature.
+to the host as a PCI device, actually multiple PCI devices might be exposed.
+The Intel MEI Driver is in charge of the communication channel between
+a host application and the Intel ME features.
 
-Each Intel ME feature (Intel ME Client) is addressed by a GUID/UUID and
+Each Intel ME feature, or Intel ME Client is addressed by a unique GUID and
 each client has its own protocol. The protocol is message-based with a
-header and payload up to 512 bytes.
+header and payload up to maximal number of bytes advertised by the client,
+upon connection.
 
 Intel MEI Driver
 ================
 
-The driver exposes a misc device called /dev/mei.
+The driver exposes a character device with device nodes /dev/meiX.
 
 An application maintains communication with an Intel ME feature while
-/dev/mei is open. The binding to a specific feature is performed by calling
-MEI_CONNECT_CLIENT_IOCTL, which passes the desired UUID.
+/dev/meiX is open. The binding to a specific feature is performed by calling
+:c:macro:`MEI_CONNECT_CLIENT_IOCTL`, which passes the desired GUID.
 The number of instances of an Intel ME feature that can be opened
 at the same time depends on the Intel ME feature, but most of the
 features allow only a single instance.
 
-The Intel AMT Host Interface (Intel AMTHI) feature supports multiple
-simultaneous user connected applications. The Intel MEI driver
-handles this internally by maintaining request queues for the applications.
-
 The driver is transparent to data that are passed between firmware feature
 and host application.
 
@@ -40,6 +38,8 @@ Because some of the Intel ME features can change the system
 configuration, the driver by default allows only a privileged
 user to access it.
 
+The session is terminated calling :c:func:`close(int fd)`.
+
 A code snippet for an application communicating with Intel AMTHI client:
 
 .. code-block:: C
@@ -47,13 +47,13 @@ A code snippet for an application communicating with Intel AMTHI client:
 	struct mei_connect_client_data data;
 	fd = open(MEI_DEVICE);
 
-	data.d.in_client_uuid = AMTHI_UUID;
+	data.d.in_client_uuid = AMTHI_GUID;
 
 	ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &data);
 
 	printf("Ver=%d, MaxLen=%ld\n",
-			data.d.in_client_uuid.protocol_version,
-			data.d.in_client_uuid.max_msg_length);
+	       data.d.in_client_uuid.protocol_version,
+	       data.d.in_client_uuid.max_msg_length);
 
 	[...]
 
@@ -67,60 +67,86 @@ A code snippet for an application communicating with Intel AMTHI client:
 	close(fd);
 
 
-IOCTLs
-======
+User space API
+
+IOCTLs:
+=======
 
 The Intel MEI Driver supports the following IOCTL commands:
-	IOCTL_MEI_CONNECT_CLIENT	Connect to firmware Feature (client).
 
-	usage:
-		struct mei_connect_client_data clientData;
-		ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &clientData);
+IOCTL_MEI_CONNECT_CLIENT
+-------------------------
+Connect to firmware Feature/Client.
+
+.. code-block:: none
+
+	Usage:
 
-	inputs:
-		mei_connect_client_data struct contain the following
-		input field:
+        struct mei_connect_client_data client_data;
 
-		in_client_uuid -	UUID of the FW Feature that needs
+        ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &client_data);
+
+	Inputs:
+
+        struct mei_connect_client_data - contain the following
+	Input field:
+
+		in_client_uuid -	GUID of the FW Feature that needs
 					to connect to.
-	outputs:
+         Outputs:
 		out_client_properties - Client Properties: MTU and Protocol Version.
 
-	error returns:
+         Error returns:
+
+                ENOTTY  No such client (i.e. wrong GUID) or connection is not allowed.
 		EINVAL	Wrong IOCTL Number
-		ENODEV	Device or Connection is not initialized or ready. (e.g. Wrong UUID)
+		ENODEV	Device or Connection is not initialized or ready.
 		ENOMEM	Unable to allocate memory to client internal data.
 		EFAULT	Fatal Error (e.g. Unable to access user input data)
 		EBUSY	Connection Already Open
 
-	Notes:
+:Note:
         max_msg_length (MTU) in client properties describes the maximum
         data that can be sent or received. (e.g. if MTU=2K, can send
         requests up to bytes 2k and received responses up to 2k bytes).
 
-	IOCTL_MEI_NOTIFY_SET: enable or disable event notifications
+
+IOCTL_MEI_NOTIFY_SET
+---------------------
+Enable or disable event notifications.
+
+
+.. code-block:: none
 
 	Usage:
+
 		uint32_t enable;
+
 		ioctl(fd, IOCTL_MEI_NOTIFY_SET, &enable);
 
-	Inputs:
+
 		uint32_t enable = 1;
 		or
 		uint32_t enable[disable] = 0;
 
 	Error returns:
+
+
 		EINVAL	Wrong IOCTL Number
 		ENODEV	Device  is not initialized or the client not connected
 		ENOMEM	Unable to allocate memory to client internal data.
 		EFAULT	Fatal Error (e.g. Unable to access user input data)
 		EOPNOTSUPP if the device doesn't support the feature
 
-	Notes:
+:Note:
 	The client must be connected in order to enable notification events
 
 
-	IOCTL_MEI_NOTIFY_GET : retrieve event
+IOCTL_MEI_NOTIFY_GET
+--------------------
+Retrieve event
+
+.. code-block:: none
 
 	Usage:
 		uint32_t event;
@@ -137,7 +163,7 @@ The Intel MEI Driver supports the following IOCTL commands:
 		EFAULT	Fatal Error (e.g. Unable to access user input data)
 		EOPNOTSUPP if the device doesn't support the feature
 
-	Notes:
+:Note:
 	The client must be connected and event notification has to be enabled
 	in order to receive an event
 
-- 
2.20.1


^ permalink raw reply related

* RE: [char-misc-next 3/7] mei: docs: update mei documentation
From: Winkler, Tomas @ 2019-06-06 13:38 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Usyskin, Alexander, linux-kernel@vger.kernel.org, Jonathan Corbet,
	linux-doc@vger.kernel.org
In-Reply-To: <20190606131633.GA6083@kroah.com>



> -----Original Message-----
> From: Greg Kroah-Hartman [mailto:gregkh@linuxfoundation.org]
> Sent: Thursday, June 06, 2019 16:17
> To: Winkler, Tomas <tomas.winkler@intel.com>
> Cc: Usyskin, Alexander <alexander.usyskin@intel.com>; linux-
> kernel@vger.kernel.org; Jonathan Corbet <corbet@lwn.net>; linux-
> doc@vger.kernel.org
> Subject: Re: [char-misc-next 3/7] mei: docs: update mei documentation
> 
> On Mon, Jun 03, 2019 at 12:14:02PM +0300, Tomas Winkler wrote:
> > The mei driver went via multiple changes, update the documentation and
> > fix formatting.
> >
> > Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> > ---
> >  Documentation/driver-api/mei/mei.rst | 96
> > ++++++++++++++++++----------
> >  1 file changed, 61 insertions(+), 35 deletions(-)
> 
> This patch is corrupted and can not apply.  Did you try to edit it by hand after
> generating it?

I have a script that strips some internal metadata, now I see it has some issues with 'Notes:' keywords. 
I've checked sand only this patch is affected. 

> Can you resend it alone?
On the way.
Thanks
Tomas


^ permalink raw reply

* Re: [char-misc-next 3/7] mei: docs: update mei documentation
From: Greg Kroah-Hartman @ 2019-06-06 13:16 UTC (permalink / raw)
  To: Tomas Winkler; +Cc: Alexander Usyskin, linux-kernel, Jonathan Corbet, linux-doc
In-Reply-To: <20190603091406.28915-4-tomas.winkler@intel.com>

On Mon, Jun 03, 2019 at 12:14:02PM +0300, Tomas Winkler wrote:
> The mei driver went via multiple changes, update
> the documentation and fix formatting.
> 
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> ---
>  Documentation/driver-api/mei/mei.rst | 96 ++++++++++++++++++----------
>  1 file changed, 61 insertions(+), 35 deletions(-)

This patch is corrupted and can not apply.  Did you try to edit it by
hand after generating it?

Can you resend it alone?

thanks,

greg k-h

^ permalink raw reply

* RE: [PATCH v2 0/5] stm32-ddr-pmu driver creation
From: Gerald BAEZA @ 2019-06-06 12:14 UTC (permalink / raw)
  To: will.deacon@arm.com, mark.rutland@arm.com, robh+dt@kernel.org,
	mcoquelin.stm32@gmail.com, Alexandre TORGUE, corbet@lwn.net,
	linux@armlinux.org.uk, olof@lixom.net, horms+renesas@verge.net.au,
	arnd@arndb.de
  Cc: linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
	linux-stm32@st-md-mailman.stormreply.com,
	linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org
In-Reply-To: <1558366019-24214-1-git-send-email-gerald.baeza@st.com>

Dear all

A gentle reminder to get your feedbacks on the series below.

Best regards

Gérald



> -----Original Message-----
> From: Gerald BAEZA <gerald.baeza@st.com>
> Sent: lundi 20 mai 2019 17:27
> To: will.deacon@arm.com; mark.rutland@arm.com; robh+dt@kernel.org;
> mcoquelin.stm32@gmail.com; Alexandre TORGUE
> <alexandre.torgue@st.com>; corbet@lwn.net; linux@armlinux.org.uk;
> olof@lixom.net; horms+renesas@verge.net.au; arnd@arndb.de
> Cc: linux-arm-kernel@lists.infradead.org; devicetree@vger.kernel.org; linux-
> stm32@st-md-mailman.stormreply.com; linux-kernel@vger.kernel.org;
> linux-doc@vger.kernel.org; Gerald BAEZA <gerald.baeza@st.com>
> Subject: [PATCH v2 0/5] stm32-ddr-pmu driver creation
> 
> The DDRPERFM is the DDR Performance Monitor embedded in STM32MP1
> SOC.
> 
> This series adds support for the DDRPERFM via a new stm32-ddr-pmu driver,
> registered into the perf framework.
> 
> This driver is inspired from arch/arm/mm/cache-l2x0-pmu.c
> 
> ---
> Changes from v1:
> - add 'resets' description (bindings) and using (driver). Thanks Rob.
> - rebase on 5.2-rc1 (that includes the ddrperfm clock control patch).
> 
> Gerald Baeza (5):
>   Documentation: perf: stm32: ddrperfm support
>   dt-bindings: perf: stm32: ddrperfm support
>   perf: stm32: ddrperfm driver creation
>   ARM: configs: enable STM32_DDR_PMU
>   ARM: dts: stm32: add ddrperfm on stm32mp157c
> 
>  .../devicetree/bindings/perf/stm32-ddr-pmu.txt     |  20 +
>  Documentation/perf/stm32-ddr-pmu.txt               |  41 ++
>  arch/arm/boot/dts/stm32mp157c.dtsi                 |   9 +
>  arch/arm/configs/multi_v7_defconfig                |   1 +
>  drivers/perf/Kconfig                               |   6 +
>  drivers/perf/Makefile                              |   1 +
>  drivers/perf/stm32_ddr_pmu.c                       | 512 +++++++++++++++++++++
>  7 files changed, 590 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/perf/stm32-ddr-
> pmu.txt
>  create mode 100644 Documentation/perf/stm32-ddr-pmu.txt
>  create mode 100644 drivers/perf/stm32_ddr_pmu.c
> 
> --
> 2.7.4

^ permalink raw reply

* Re: [PATCH v3 0/2] ima/evm fixes for v5.2
From: Roberto Sassu @ 2019-06-06 11:43 UTC (permalink / raw)
  To: zohar, dmitry.kasatkin, mjg59
  Cc: linux-integrity, linux-security-module, linux-doc, stable,
	linux-kernel, silviu.vlasceanu
In-Reply-To: <20190606112620.26488-1-roberto.sassu@huawei.com>

On 6/6/2019 1:26 PM, Roberto Sassu wrote:
> Previous versions included the patch 'ima: don't ignore INTEGRITY_UNKNOWN
> EVM status'. However, I realized that this patch cannot be accepted alone
> because IMA-Appraisal would deny access to new files created during the
> boot. With the current behavior, those files are accessible because they
> have a valid security.ima (not protected by EVM) created after the first
> write.
> 
> A solution for this problem is to initialize EVM very early with a random
> key. Access to created files will be granted, even with the strict
> appraisal, because after the first write those files will have both
> security.ima and security.evm (HMAC calculated with the random key).
> 
> Strict appraisal will work only if it is done with signatures until the
> persistent HMAC key is loaded.

Changelog

v2:
- remove patch 1/3 (evm: check hash algorithm passed to init_desc());
   already accepted
- remove patch 3/3 (ima: show rules with IMA_INMASK correctly);
   already accepted
- add new patch (evm: add option to set a random HMAC key at early boot)
- patch 2/3: modify patch description

v1:
- remove patch 2/4 (evm: reset status in evm_inode_post_setattr()); file
   attributes cannot be set if the signature is portable and immutable
- patch 3/4: add __ro_after_init to ima_appraise_req_evm variable
   declaration
- patch 3/4: remove ima_appraise_req_evm kernel option and introduce
   'enforce-evm' and 'log-evm' as possible values for ima_appraise=
- remove patch 4/4 (ima: only audit failed appraisal verifications)
- add new patch (ima: show rules with IMA_INMASK correctly)


> Roberto Sassu (2):
>    evm: add option to set a random HMAC key at early boot
>    ima: add enforce-evm and log-evm modes to strictly check EVM status
> 
>   .../admin-guide/kernel-parameters.txt         | 11 ++--
>   security/integrity/evm/evm.h                  | 10 +++-
>   security/integrity/evm/evm_crypto.c           | 57 ++++++++++++++++---
>   security/integrity/evm/evm_main.c             | 41 ++++++++++---
>   security/integrity/ima/ima_appraise.c         |  8 +++
>   security/integrity/integrity.h                |  1 +
>   6 files changed, 106 insertions(+), 22 deletions(-)
> 

-- 
HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Bo PENG, Jian LI, Yanli SHI

^ permalink raw reply

* [PATCH v3 2/2] ima: add enforce-evm and log-evm modes to strictly check EVM status
From: Roberto Sassu @ 2019-06-06 11:26 UTC (permalink / raw)
  To: zohar, dmitry.kasatkin, mjg59
  Cc: linux-integrity, linux-security-module, linux-doc, stable,
	linux-kernel, silviu.vlasceanu, Roberto Sassu
In-Reply-To: <20190606112620.26488-1-roberto.sassu@huawei.com>

IMA and EVM have been designed as two independent subsystems: the first for
checking the integrity of file data; the second for checking file metadata.
Making them independent allows users to adopt them incrementally.

The point of intersection is in IMA-Appraisal, which calls
evm_verifyxattr() to ensure that security.ima wasn't modified during an
offline attack. The design choice, to ensure incremental adoption, was to
continue appraisal verification if evm_verifyxattr() returns
INTEGRITY_UNKNOWN. This value is returned when EVM is not enabled in the
kernel configuration, or if the HMAC key has not been loaded yet.

Although this choice appears legitimate, it might not be suitable for
hardened systems, where the administrator expects that access is denied if
there is any error. An attacker could intentionally delete the EVM keys
from the system and set the file digest in security.ima to the actual file
digest so that the final appraisal status is INTEGRITY_PASS.

This patch allows such hardened systems to strictly enforce an access
control policy based on the validity of signatures/HMACs, by introducing
two new values for the ima_appraise= kernel option: enforce-evm and
log-evm.

Fixes: 2fe5d6def1672 ("ima: integrity appraisal extension")
Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Cc: stable@vger.kernel.org
---
 Documentation/admin-guide/kernel-parameters.txt | 3 ++-
 security/integrity/ima/ima_appraise.c           | 8 ++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index fe5cde58c11b..0585194ca736 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1587,7 +1587,8 @@
 			Set number of hash buckets for inode cache.
 
 	ima_appraise=	[IMA] appraise integrity measurements
-			Format: { "off" | "enforce" | "fix" | "log" }
+			Format: { "off" | "enforce" | "fix" | "log" |
+				  "enforce-evm" | "log-evm" }
 			default: "enforce"
 
 	ima_appraise_tcb [IMA] Deprecated.  Use ima_policy= instead.
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 5fb7127bbe68..afef06e10fb9 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -18,6 +18,7 @@
 
 #include "ima.h"
 
+static bool ima_appraise_req_evm __ro_after_init;
 static int __init default_appraise_setup(char *str)
 {
 #ifdef CONFIG_IMA_APPRAISE_BOOTPARAM
@@ -28,6 +29,9 @@ static int __init default_appraise_setup(char *str)
 	else if (strncmp(str, "fix", 3) == 0)
 		ima_appraise = IMA_APPRAISE_FIX;
 #endif
+	if (strcmp(str, "enforce-evm") == 0 ||
+	    strcmp(str, "log-evm") == 0)
+		ima_appraise_req_evm = true;
 	return 1;
 }
 
@@ -245,7 +249,11 @@ int ima_appraise_measurement(enum ima_hooks func,
 	switch (status) {
 	case INTEGRITY_PASS:
 	case INTEGRITY_PASS_IMMUTABLE:
+		break;
 	case INTEGRITY_UNKNOWN:
+		if (ima_appraise_req_evm &&
+		    xattr_value->type != EVM_IMA_XATTR_DIGSIG)
+			goto out;
 		break;
 	case INTEGRITY_NOXATTRS:	/* No EVM protected xattrs. */
 	case INTEGRITY_NOLABEL:		/* No security.evm xattr. */
-- 
2.17.1


^ permalink raw reply related

* [PATCH v3 1/2] evm: add option to set a random HMAC key at early boot
From: Roberto Sassu @ 2019-06-06 11:26 UTC (permalink / raw)
  To: zohar, dmitry.kasatkin, mjg59
  Cc: linux-integrity, linux-security-module, linux-doc, stable,
	linux-kernel, silviu.vlasceanu, Roberto Sassu
In-Reply-To: <20190606112620.26488-1-roberto.sassu@huawei.com>

Mutable files can be created before the HMAC key is unsealed, for example
the dracut state and the systemd journal. Next accesses to those files will
be denied if the new appraisal mode enforce-evm is selected
(INTEGRITY_UNKNOWN returned by EVM is considered as an error).

This patch solves this problem by initializing EVM at early boot with a
randomly generated key. This key is used to calculate and verify the HMAC
for new files in a tmpfs filesystem, until the persistent key is loaded.

The new xattr type EVM_XATTR_HMAC_RND_KEY has been introduced to determine
which key should be used to verify the HMAC. This type is used for new
files and file updates (unless security.evm exists with a different type),
until the persistent key is loaded. Afterwards, existing HMACs calculated
with the random key are replaced with HMACs calculated with the persistent
key.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 .../admin-guide/kernel-parameters.txt         |  8 ++-
 security/integrity/evm/evm.h                  | 10 +++-
 security/integrity/evm/evm_crypto.c           | 57 ++++++++++++++++---
 security/integrity/evm/evm_main.c             | 41 ++++++++++---
 security/integrity/integrity.h                |  1 +
 5 files changed, 96 insertions(+), 21 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 138f6664b2e2..fe5cde58c11b 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1239,9 +1239,11 @@
 			has equivalent usage. See its documentation for details.
 
 	evm=		[EVM]
-			Format: { "fix" }
-			Permit 'security.evm' to be updated regardless of
-			current integrity status.
+			Format: { "fix" | "random" }
+			Specify "fix" to permit 'security.evm' to be updated
+			regardless of current integrity status. Specify "random"
+			to initialize EVM with a random key to be used for new
+			files until the persistent HMAC key is loaded.
 
 	failslab=
 	fail_page_alloc=
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index c3f437f5db10..0ca4490b7e40 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -24,9 +24,11 @@
 #define EVM_INIT_HMAC	0x0001
 #define EVM_INIT_X509	0x0002
 #define EVM_ALLOW_METADATA_WRITES	0x0004
+#define EVM_INIT_HMAC_RND_KEY	0x0008
 #define EVM_SETUP_COMPLETE 0x80000000 /* userland has signaled key load */
 
-#define EVM_KEY_MASK (EVM_INIT_HMAC | EVM_INIT_X509)
+#define EVM_PERSISTENT_KEY_MASK (EVM_INIT_HMAC | EVM_INIT_X509)
+#define EVM_KEY_MASK (EVM_INIT_HMAC | EVM_INIT_X509 | EVM_INIT_HMAC_RND_KEY)
 #define EVM_INIT_MASK (EVM_INIT_HMAC | EVM_INIT_X509 | EVM_SETUP_COMPLETE | \
 		       EVM_ALLOW_METADATA_WRITES)
 
@@ -53,19 +55,21 @@ struct evm_digest {
 } __packed;
 
 int evm_init_key(void);
+void evm_set_random_key(void);
 int evm_update_evmxattr(struct dentry *dentry,
 			const char *req_xattr_name,
 			const char *req_xattr_value,
 			size_t req_xattr_value_len);
 int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
 		  const char *req_xattr_value,
-		  size_t req_xattr_value_len, struct evm_digest *data);
+		  size_t req_xattr_value_len, char type,
+		  struct evm_digest *data);
 int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
 		  const char *req_xattr_value,
 		  size_t req_xattr_value_len, char type,
 		  struct evm_digest *data);
 int evm_init_hmac(struct inode *inode, const struct xattr *xattr,
-		  char *hmac_val);
+		  struct evm_ima_xattr_data *evm_xattr);
 int evm_init_secfs(void);
 
 #endif
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 82a38e801ee4..51a02200b057 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -19,6 +19,7 @@
 #include <linux/crypto.h>
 #include <linux/xattr.h>
 #include <linux/evm.h>
+#include <linux/random.h>
 #include <keys/encrypted-type.h>
 #include <crypto/hash.h>
 #include <crypto/hash_info.h>
@@ -30,6 +31,7 @@ static unsigned char evmkey[MAX_KEY_SIZE];
 static const int evmkey_len = MAX_KEY_SIZE;
 
 struct crypto_shash *hmac_tfm;
+struct crypto_shash *hmac_rnd_tfm;
 static struct crypto_shash *evm_tfm[HASH_ALGO__LAST];
 
 static DEFINE_MUTEX(mutex);
@@ -62,8 +64,10 @@ int evm_set_key(void *key, size_t keylen)
 	rc = -EINVAL;
 	if (keylen > MAX_KEY_SIZE)
 		goto inval;
+	memset(evmkey, 0, sizeof(evmkey));
 	memcpy(evmkey, key, keylen);
 	evm_initialized |= EVM_INIT_HMAC;
+	evm_initialized &= ~EVM_INIT_HMAC_RND_KEY;
 	pr_info("key initialized\n");
 	return 0;
 inval:
@@ -74,6 +78,12 @@ int evm_set_key(void *key, size_t keylen)
 }
 EXPORT_SYMBOL_GPL(evm_set_key);
 
+void evm_set_random_key(void)
+{
+	get_random_bytes(evmkey, sizeof(evmkey));
+	evm_initialized |= EVM_INIT_HMAC_RND_KEY;
+}
+
 static struct shash_desc *init_desc(char type, uint8_t hash_algo)
 {
 	long rc;
@@ -88,6 +98,9 @@ static struct shash_desc *init_desc(char type, uint8_t hash_algo)
 		}
 		tfm = &hmac_tfm;
 		algo = evm_hmac;
+	} else if (type == EVM_XATTR_HMAC_RND_KEY) {
+		tfm = &hmac_rnd_tfm;
+		algo = evm_hmac;
 	} else {
 		if (hash_algo >= HASH_ALGO__LAST)
 			return ERR_PTR(-EINVAL);
@@ -108,7 +121,7 @@ static struct shash_desc *init_desc(char type, uint8_t hash_algo)
 			mutex_unlock(&mutex);
 			return ERR_PTR(rc);
 		}
-		if (type == EVM_XATTR_HMAC) {
+		if (type == EVM_XATTR_HMAC || EVM_XATTR_HMAC_RND_KEY) {
 			rc = crypto_shash_setkey(*tfm, evmkey, evmkey_len);
 			if (rc) {
 				crypto_free_shash(*tfm);
@@ -255,10 +268,10 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
 
 int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
 		  const char *req_xattr_value, size_t req_xattr_value_len,
-		  struct evm_digest *data)
+		  char type, struct evm_digest *data)
 {
 	return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
-				    req_xattr_value_len, EVM_XATTR_HMAC, data);
+				    req_xattr_value_len, type, data);
 }
 
 int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
@@ -296,6 +309,29 @@ static int evm_is_immutable(struct dentry *dentry, struct inode *inode)
 	return rc;
 }
 
+static enum evm_ima_xattr_type evm_get_default_type(struct dentry *dentry)
+{
+	enum evm_ima_xattr_type evm_default_type = EVM_XATTR_HMAC;
+	struct evm_ima_xattr_data xattr_data;
+	int rc;
+
+	if (evm_initialized & EVM_INIT_HMAC_RND_KEY)
+		evm_default_type = EVM_XATTR_HMAC_RND_KEY;
+	else
+		goto out;
+
+	rc = vfs_getxattr(dentry, XATTR_NAME_EVM, (char *)&xattr_data,
+			  sizeof(xattr_data));
+
+	if (rc == sizeof(xattr_data))
+		evm_default_type = xattr_data.type;
+out:
+	if (evm_default_type != EVM_XATTR_HMAC_RND_KEY &&
+	    !(evm_initialized & EVM_INIT_HMAC))
+		return IMA_XATTR_LAST;
+
+	return evm_default_type;
+}
 
 /*
  * Calculate the hmac and update security.evm xattr
@@ -306,6 +342,7 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
 			const char *xattr_value, size_t xattr_value_len)
 {
 	struct inode *inode = d_backing_inode(dentry);
+	enum evm_ima_xattr_type evm_default_type;
 	struct evm_digest data;
 	int rc = 0;
 
@@ -319,11 +356,15 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
 	if (rc)
 		return -EPERM;
 
+	evm_default_type = evm_get_default_type(dentry);
+	if (evm_default_type == IMA_XATTR_LAST)
+		return -ENOKEY;
+
 	data.hdr.algo = HASH_ALGO_SHA1;
 	rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
-			   xattr_value_len, &data);
+			   xattr_value_len, evm_default_type, &data);
 	if (rc == 0) {
-		data.hdr.xattr.sha1.type = EVM_XATTR_HMAC;
+		data.hdr.xattr.sha1.type = evm_default_type;
 		rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
 					   &data.hdr.xattr.data[1],
 					   SHA1_DIGEST_SIZE + 1, 0);
@@ -334,18 +375,18 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
 }
 
 int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
-		  char *hmac_val)
+		  struct evm_ima_xattr_data *evm_xattr)
 {
 	struct shash_desc *desc;
 
-	desc = init_desc(EVM_XATTR_HMAC, HASH_ALGO_SHA1);
+	desc = init_desc(evm_xattr->type, HASH_ALGO_SHA1);
 	if (IS_ERR(desc)) {
 		pr_info("init_desc failed\n");
 		return PTR_ERR(desc);
 	}
 
 	crypto_shash_update(desc, lsm_xattr->value, lsm_xattr->value_len);
-	hmac_add_misc(desc, inode, EVM_XATTR_HMAC, hmac_val);
+	hmac_add_misc(desc, inode, evm_xattr->type, evm_xattr->digest);
 	kfree(desc);
 	return 0;
 }
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index b6d9f14bc234..faa4a02a3139 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -59,14 +59,16 @@ static struct xattr_list evm_config_default_xattrnames[] = {
 
 LIST_HEAD(evm_config_xattrnames);
 
-static int evm_fixmode;
-static int __init evm_set_fixmode(char *str)
+static int evm_fixmode, evm_random_key;
+static int __init evm_setup(char *str)
 {
 	if (strncmp(str, "fix", 3) == 0)
 		evm_fixmode = 1;
+	if (strncmp(str, "random", 6) == 0)
+		evm_random_key = 1;
 	return 0;
 }
-__setup("evm=", evm_set_fixmode);
+__setup("evm=", evm_setup);
 
 static void __init evm_init_config(void)
 {
@@ -92,6 +94,11 @@ static bool evm_key_loaded(void)
 	return (bool)(evm_initialized & EVM_KEY_MASK);
 }
 
+static bool evm_persistent_key_loaded(void)
+{
+	return (bool)(evm_initialized & EVM_PERSISTENT_KEY_MASK);
+}
+
 static int evm_find_protected_xattrs(struct dentry *dentry)
 {
 	struct inode *inode = d_backing_inode(dentry);
@@ -152,7 +159,9 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 				GFP_NOFS);
 	if (rc <= 0) {
 		evm_status = INTEGRITY_FAIL;
-		if (rc == -ENODATA) {
+		if (!evm_persistent_key_loaded()) {
+			evm_status = INTEGRITY_UNKNOWN;
+		} else if (rc == -ENODATA) {
 			rc = evm_find_protected_xattrs(dentry);
 			if (rc > 0)
 				evm_status = INTEGRITY_NOLABEL;
@@ -164,11 +173,18 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 		goto out;
 	}
 
+	if (xattr_data->type != EVM_XATTR_HMAC_RND_KEY &&
+	    !evm_persistent_key_loaded()) {
+		evm_status = INTEGRITY_UNKNOWN;
+		goto out;
+	}
+
 	xattr_len = rc;
 
 	/* check value type */
 	switch (xattr_data->type) {
 	case EVM_XATTR_HMAC:
+	case EVM_XATTR_HMAC_RND_KEY:
 		if (xattr_len != sizeof(struct evm_ima_xattr_data)) {
 			evm_status = INTEGRITY_FAIL;
 			goto out;
@@ -176,7 +192,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 
 		digest.hdr.algo = HASH_ALGO_SHA1;
 		rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
-				   xattr_value_len, &digest);
+				   xattr_value_len, xattr_data->type, &digest);
 		if (rc)
 			break;
 		rc = crypto_memneq(xattr_data->digest, digest.digest,
@@ -523,18 +539,26 @@ int evm_inode_init_security(struct inode *inode,
 				 const struct xattr *lsm_xattr,
 				 struct xattr *evm_xattr)
 {
+	enum evm_ima_xattr_type evm_default_type = EVM_XATTR_HMAC;
 	struct evm_ima_xattr_data *xattr_data;
 	int rc;
 
 	if (!evm_key_loaded() || !evm_protected_xattr(lsm_xattr->name))
 		return 0;
 
+	if (!evm_persistent_key_loaded()) {
+		if (inode->i_sb->s_magic != TMPFS_MAGIC)
+			return 0;
+
+		evm_default_type = EVM_XATTR_HMAC_RND_KEY;
+	}
+
 	xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
 	if (!xattr_data)
 		return -ENOMEM;
 
-	xattr_data->type = EVM_XATTR_HMAC;
-	rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest);
+	xattr_data->type = evm_default_type;
+	rc = evm_init_hmac(inode, lsm_xattr, xattr_data);
 	if (rc < 0)
 		goto out;
 
@@ -584,6 +608,9 @@ static int __init init_evm(void)
 		}
 	}
 
+	if (!error && evm_random_key)
+		evm_set_random_key();
+
 	return error;
 }
 
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 7de59f44cba3..a037d10db46f 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -74,6 +74,7 @@ enum evm_ima_xattr_type {
 	EVM_IMA_XATTR_DIGSIG,
 	IMA_XATTR_DIGEST_NG,
 	EVM_XATTR_PORTABLE_DIGSIG,
+	EVM_XATTR_HMAC_RND_KEY,
 	IMA_XATTR_LAST
 };
 
-- 
2.17.1


^ permalink raw reply related

* [PATCH v3 0/2] ima/evm fixes for v5.2
From: Roberto Sassu @ 2019-06-06 11:26 UTC (permalink / raw)
  To: zohar, dmitry.kasatkin, mjg59
  Cc: linux-integrity, linux-security-module, linux-doc, stable,
	linux-kernel, silviu.vlasceanu, Roberto Sassu

Previous versions included the patch 'ima: don't ignore INTEGRITY_UNKNOWN
EVM status'. However, I realized that this patch cannot be accepted alone
because IMA-Appraisal would deny access to new files created during the
boot. With the current behavior, those files are accessible because they
have a valid security.ima (not protected by EVM) created after the first
write.

A solution for this problem is to initialize EVM very early with a random
key. Access to created files will be granted, even with the strict
appraisal, because after the first write those files will have both
security.ima and security.evm (HMAC calculated with the random key).

Strict appraisal will work only if it is done with signatures until the
persistent HMAC key is loaded.


Roberto Sassu (2):
  evm: add option to set a random HMAC key at early boot
  ima: add enforce-evm and log-evm modes to strictly check EVM status

 .../admin-guide/kernel-parameters.txt         | 11 ++--
 security/integrity/evm/evm.h                  | 10 +++-
 security/integrity/evm/evm_crypto.c           | 57 ++++++++++++++++---
 security/integrity/evm/evm_main.c             | 41 ++++++++++---
 security/integrity/ima/ima_appraise.c         |  8 +++
 security/integrity/integrity.h                |  1 +
 6 files changed, 106 insertions(+), 22 deletions(-)

-- 
2.17.1


^ permalink raw reply

* Re: [PATCH v2] Add a document on rebasing and merging
From: Jani Nikula @ 2019-06-06  9:12 UTC (permalink / raw)
  To: Jonathan Corbet, linux-doc
  Cc: LKML, Linus Torvalds, Theodore Ts'o, Geert Uytterhoeven,
	David Rientjes
In-Reply-To: <20190604134835.16fc6bfa@lwn.net>

On Tue, 04 Jun 2019, Jonathan Corbet <corbet@lwn.net> wrote:
> Every merge window seems to involve at least one episode where subsystem
> maintainers don't manage their trees as Linus would like.  Document the
> expectations so that at least he has something to point people to.

Good stuff. Some notes inline.

BR,
Jani.

>
> Acked-by: David Rientjes <rientjes@google.com>
> Signed-off-by: Jonathan Corbet <corbet@lwn.net>
> ---
> Changes in v2:
>   - Try to clear up "reparenting" v. "history modification"
>   - Make the "don't rebase public branches" rule into more of a guideline
>   - Fix typos noted by Geert
>   - Rename the document to better reflect its contents
>
>  Documentation/maintainer/index.rst            |   1 +
>  .../maintainer/rebasing-and-merging.rst       | 216 ++++++++++++++++++
>  2 files changed, 217 insertions(+)
>  create mode 100644 Documentation/maintainer/rebasing-and-merging.rst
>
> diff --git a/Documentation/maintainer/index.rst
> b/Documentation/maintainer/index.rst index 2a14916930cb..56e2c09dfa39
> 100644 --- a/Documentation/maintainer/index.rst
> +++ b/Documentation/maintainer/index.rst
> @@ -10,5 +10,6 @@ additions to this manual.
>     :maxdepth: 2
>  
>     configure-git
> +   rebasing-and-merging
>     pull-requests
>  
> diff --git a/Documentation/maintainer/rebasing-and-merging.rst
> b/Documentation/maintainer/rebasing-and-merging.rst new file mode 100644
> index 000000000000..2987bd45dfb2
> --- /dev/null
> +++ b/Documentation/maintainer/rebasing-and-merging.rst
> @@ -0,0 +1,216 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +====================
> +Rebasing and merging
> +====================
> +
> +Maintaining a subsystem, as a general rule, requires a familiarity with
> the +Git source-code management system.  Git is a powerful tool with a lot
> of +features; as is often the case with such tools, there are right and
> wrong +ways to use those features.  This document looks in particular at
> the use +of rebasing and merging.  Maintainers often get in trouble when
> they use +those tools incorrectly, but avoiding problems is not actually
> all that +hard.
> +
> +One thing to be aware of in general is that, unlike many other projects,
> +the kernel community is not scared by seeing merge commits in its
> +development history.  Indeed, given the scale of the project, avoiding
> +merges would be nearly impossible.  Some problems encountered by
> +maintainers result from a desire to avoid merges, while others come from
> +merging a little too often.
> +
> +Rebasing
> +========
> +
> +"Rebasing" is the process of changing the history of a series of commits
> +within a repository.  There are two different types of operations that are
> +referred to as rebasing since both are done with the ``git rebase``
> +command, but there are significant differences between them:
> +
> + - Rebasing can change the parent (starting) commit upon which a series of
> +   patches is built.  For example, a rebase operation could take a patch
> +   set built on the previous kernel release and base it, instead, on the
> +   current release.  We'll call this operation "reparenting" in the
> +   discussion below.
> +
> + - Changing the history of a set of patches by fixing (or deleting) broken
> +   commits, adding patches, adding tags to commit changelogs, or changing
> +   the order in which commits are applied.  In the following text, this
> +   type of operation will be referred to as "history modification"
> +
> +The term "rebasing" will be used to refer to both of the above operations.
> +Used properly, rebasing can yield a cleaner and clearer development
> +history; used improperly, it can obscure that history and introduce bugs.
> +
> +There are a few rules of thumb that can help developers to avoid the worst
> +perils of rebasing:
> +
> + - History that has been exposed to the world beyond your private system
> +   should usually not be changed.  Others may have pulled a copy of your
> +   tree and built on it; modifying your tree will create pain for them.
> If
> +   work is in need of rebasing, that is usually a sign that it is not yet
> +   ready to be committed to a public repository.
> +
> +   That said, there are always exceptions.  Some trees (linux-next being
> +   a significant example) are frequently rebased by their nature, and
> +   developers know not to base work on them.  Developers will sometimes
> +   expose an unstable branch for others to test with or for automated
> +   testing services.  If you do expose a branch that may be unstable in
> +   this way, be sure that prospective users know not to base work on it.
> +
> + - Do not rebase a branch that contains history created by others.  If you
> +   have pulled changes from another developer's repository, you are now a
> +   custodian of their history.  You should not change it.  With few
> +   exceptions, for example, a broken commit in a tree like this should be
> +   explicitly reverted rather than disappeared via history modification.
> +
> + - Do not reparent a tree without a good reason to do so.  Just being on a
> +   newer base or avoiding a merge with an upstream repository is not
> +   generally a good reason.
> +
> + - If you must reparent a repository, do not pick some random kernel
> commit
> +   as the new base.  The kernel is often in a relatively unstable state
> +   between release points; basing development on one of those points
> +   increases the chances of running into surprising bugs.  When a patch
> +   series must move to a new base, pick a stable point (such as one of
> +   the -rc releases) to move to.
> +
> + - Realize that the rebasing a patch series changes the environment in
> +   which it was developed and, likely, invalidates much of the testing
> that
> +   was done.  A rebased patch series should, as a general rule, be treated
> +   like new code and retested from the beginning.
> +
> +A frequent cause of merge-window trouble is when Linus is presented with a
> +patch series that has clearly been reparented, often to a random commit,
> +shortly before the pull request was sent.  The chances of such a series
> +having been adequately tested are relatively low - as are the chances of
> +the pull request being acted upon.
> +
> +If, instead, rebasing is limited to private trees, commits are based on a
> +well-known starting point, and they are well tested, the potential for
> +trouble is low.
> +
> +Merging
> +=======
> +
> +Merging is a common operation in the kernel development process; the 5.1
> +development cycle included 1,126 merge commits - nearly 9% of the total.
> +Kernel work is accumulated in over 100 different subsystem trees, each of
> +which may contain multiple topic branches; each branch is usually
> developed +independently of the others.  So naturally, at least merge will
> be required +before any given branch finds its way into an upstream
> repository. +
> +Many projects require that branches in pull requests be based on the
> +current trunk so that no merge commits appear in the history.  The kernel
> +is not such a project; any rebasing of branches to avoid merges will, as
> +described above, lead to certain trouble.
> +
> +Subsystem maintainers find themselves having to do two types of merges:
> +from lower-level subsystem trees and from others, either sibling trees or
> +the mainline.  The best practices to follow differ in those two
> situations. +
> +Merging from lower-level trees
> +------------------------------
> +
> +Larger subsystems tend to have multiple levels of maintainers, with the
> +lower-level maintainers sending pull requests to the higher levels.
> Acting +on such a pull request will almost certainly generate a merge
> commit; that +is as it should be.  In fact, subsystem maintainers may want
> to use +the --no-ff flag to force the addition of a merge commit in the
> rare cases +where one would not normally be created so that the reasons
> for the merge +can be recorded.  The changelog for the merge should, for
> any kind of +merge, say *why* the merge is being done.  For a lower-level
> tree, "why" is +usually a summary of the changes that will come with that
> pull. +
> +Maintainers at all levels should be using signed tags on their pull
> +requests, and upstream maintainers should verify the tags when pulling
> +branches.  Failure to do so threatens the security of the development
> +process as a whole.
> +
> +As per the rules outlined above, once you have merged somebody else's
> +history into your tree, you cannot rebase that branch, even if you
> +otherwise would be able to.
> +
> +Merging from sibling or upstream trees
> +--------------------------------------
> +
> +While merges from downstream are common and unremarkable, merges from
> other +trees tend to be a red flag when it comes time to push a branch
> upstream. +Such merges need to be carefully thought about and well
> justified, or +there's a good chance that a subsequent pull request will
> be rejected. +
> +It is natural to want to merge the master branch into a repository; it can
> +help to make sure that there are no conflicts with parallel development
> and +generally gives a warm, fuzzy feeling of being up-to-date.  But this
> +temptation should be avoided almost all of the time.
> +
> +Why is that?  Merges with upstream will muddy the development history of
> +your own branch.  They will significantly increase your chances of
> +encountering bugs from elsewhere in the community and make it hard to
> +ensure that the work you are managing is stable and ready for upstream.
> +Frequent merges can also obscure problems with the development process in
> +your tree; they can hide interactions with other trees that should not be
> +happening (often) in a well-managed branch.
> +
> +One of the most frequent causes of merge-related trouble is when a
> +maintainer merges with the upstream in order to resolve merge conflicts
> +before sending a pull request.  Again, this temptation is easy enough to
> +understand, but it should absolutely be avoided.  This is especially true
> +for the final pull request: Linus is adamant that he would much rather see
> +merge conflicts than unnecessary back merges.  Seeing the conflicts lets

I think "backmerge" as a term deserves to be highlighted in the heading
or first paragraph of the section.

Occasionally backmerges are required. As a rule of thumb, it might be
worth mentioning you probably shouldn't do such merges across subsystem
hierarchies, i.e. ask the level above you to do a backmerge first, and
then backmerge from them. And that when backmerging from Linus' tree,
the merge point should be a tag.

> +him know where potential problem areas are.  He does a lot of merges (382
> +in the 5.1 development cycle) and has gotten quite good at conflict
> +resolution - often better than the developers involved.
> +
> +So what should a maintainer do when there is a conflict between their
> +subsystem branch and the mainline?  The most important step is to warn
> +Linus in the pull request that the conflict will happen; if nothing else,
> +that demonstrates an awareness of how your branch fits into the whole.
> For +especially difficult conflicts, create and push a *separate* branch
> to show +how you would resolve things.  Mention that branch in your pull
> request, +but the pull request itself should be for the unmerged branch.
> +
> +Even in the absence of known conflicts, doing a test merge before sending
> a +pull request is a good idea.  It may alert you to problems that you
> somehow +didn't see from linux-next and helps to understand exactly what
> you are +asking upstream to do.
> +
> +Another reason for doing merges of upstream or another subsystem tree is
> to +resolve dependencies.  These dependency issues do happen at times, and
> +sometimes a cross-merge with another tree is the best way to resolve them;
> +as always, in such situations, the merge commit should explain why the
> +merge has been done.  Take a moment to do it right; people will read those
> +changelogs.
> +
> +Often, though, dependency issues indicate that a change of approach is
> +needed.  Merging another subsystem tree to resolve a dependency risks
> +bringing in other bugs.  If that subsystem tree fails to be pulled
> +upstream, whatever problems it had will block the merging of your tree as
> +well.  Possible alternatives include agreeing with the maintainer to carry
> +both sets of changes in one of the trees or creating a special branch
> +dedicated to the dependent commits.  If the dependency is related to major
> +infrastructural changes, the right solution might be to hold the dependent
> +commits for one development cycle so that those changes have time to
> +stabilize in the mainline.

Is it not a common convention to call these special branches "topic
branches"?

FWIW, I don't think I've ever done a cross-merge or a direct merge from
a sibling tree. I've always solved the cases either by topic branches
merged to both trees or by having both trees merged to the first common
upstream tree, and then backmerging. From my POV feels like these
solutions should be presented more prominently than cross-merges.

> +
> +Finally
> +=======
> +
> +It is relatively common to merge with the mainline toward the beginning of
> +the development cycle in order to pick up changes and fixes done elsewhere
> +in the tree.  As always, such a merge should pick a well-known release
> +point rather than some random spot.  If your upstream-bound branch has
> +emptied entirely into the mainline during the merge window, you can pull
> it +forward with a command like::
> +
> +  git merge v5.2-rc1^0
> +
> +The "^0" will cause Git to do a fast-forward merge (which should be
> +possible in this situation), thus avoiding the addition of a spurious
> merge +commit.
> +
> +The guidelines laid out above are just that: guidelines.  There will
> always +be situations that call out for a different solution, and these
> guidelines +should not prevent developers from doing the right thing when
> the need +arises.  But one should always think about whether the need has
> truly +arisen and be prepared to explain why something abnormal needs to
> be done. -- 
> 2.21.0
>

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox