* [PATCH v4 17/23] modules: Use vmalloc special flag
From: Rick Edgecombe @ 2019-04-22 18:57 UTC (permalink / raw)
To: Borislav Petkov, Andy Lutomirski, Ingo Molnar
Cc: linux-kernel, x86, hpa, Thomas Gleixner, Nadav Amit, Dave Hansen,
Peter Zijlstra, linux_dti, linux-integrity, linux-security-module,
akpm, kernel-hardening, linux-mm, will.deacon, ard.biesheuvel,
kristen, deneen.t.dock, Rick Edgecombe, Jessica Yu,
Steven Rostedt
In-Reply-To: <20190422185805.1169-1-rick.p.edgecombe@intel.com>
Use new flag for handling freeing of special permissioned memory in vmalloc
and remove places where memory was set RW before freeing which is no longer
needed.
Since freeing of VM_FLUSH_RESET_PERMS memory is not supported in an
interrupt by vmalloc, the freeing of init sections is moved to a work
queue. Instead of call_rcu it now uses synchronize_rcu() in the work
queue.
Lastly, there is now a WARN_ON in module_memfree since it should not be
called in an interrupt with special memory as is required for
VM_FLUSH_RESET_PERMS.
Cc: Jessica Yu <jeyu@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
kernel/module.c | 77 +++++++++++++++++++++++++------------------------
1 file changed, 39 insertions(+), 38 deletions(-)
diff --git a/kernel/module.c b/kernel/module.c
index 2b2845ae983e..a9020bdd4cf6 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -98,6 +98,10 @@ DEFINE_MUTEX(module_mutex);
EXPORT_SYMBOL_GPL(module_mutex);
static LIST_HEAD(modules);
+/* Work queue for freeing init sections in success case */
+static struct work_struct init_free_wq;
+static struct llist_head init_free_list;
+
#ifdef CONFIG_MODULES_TREE_LOOKUP
/*
@@ -1949,6 +1953,8 @@ void module_enable_ro(const struct module *mod, bool after_init)
if (!rodata_enabled)
return;
+ set_vm_flush_reset_perms(mod->core_layout.base);
+ set_vm_flush_reset_perms(mod->init_layout.base);
frob_text(&mod->core_layout, set_memory_ro);
frob_text(&mod->core_layout, set_memory_x);
@@ -1972,15 +1978,6 @@ static void module_enable_nx(const struct module *mod)
frob_writable_data(&mod->init_layout, set_memory_nx);
}
-static void module_disable_nx(const struct module *mod)
-{
- frob_rodata(&mod->core_layout, set_memory_x);
- frob_ro_after_init(&mod->core_layout, set_memory_x);
- frob_writable_data(&mod->core_layout, set_memory_x);
- frob_rodata(&mod->init_layout, set_memory_x);
- frob_writable_data(&mod->init_layout, set_memory_x);
-}
-
/* Iterate through all modules and set each module's text as RW */
void set_all_modules_text_rw(void)
{
@@ -2024,23 +2021,8 @@ void set_all_modules_text_ro(void)
}
mutex_unlock(&module_mutex);
}
-
-static void disable_ro_nx(const struct module_layout *layout)
-{
- if (rodata_enabled) {
- frob_text(layout, set_memory_rw);
- frob_rodata(layout, set_memory_rw);
- frob_ro_after_init(layout, set_memory_rw);
- }
- frob_rodata(layout, set_memory_x);
- frob_ro_after_init(layout, set_memory_x);
- frob_writable_data(layout, set_memory_x);
-}
-
#else
-static void disable_ro_nx(const struct module_layout *layout) { }
static void module_enable_nx(const struct module *mod) { }
-static void module_disable_nx(const struct module *mod) { }
#endif
#ifdef CONFIG_LIVEPATCH
@@ -2120,6 +2102,11 @@ static void free_module_elf(struct module *mod)
void __weak module_memfree(void *module_region)
{
+ /*
+ * This memory may be RO, and freeing RO memory in an interrupt is not
+ * supported by vmalloc.
+ */
+ WARN_ON(in_interrupt());
vfree(module_region);
}
@@ -2171,7 +2158,6 @@ static void free_module(struct module *mod)
mutex_unlock(&module_mutex);
/* This may be empty, but that's OK */
- disable_ro_nx(&mod->init_layout);
module_arch_freeing_init(mod);
module_memfree(mod->init_layout.base);
kfree(mod->args);
@@ -2181,7 +2167,6 @@ static void free_module(struct module *mod)
lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size);
/* Finally, free the core (containing the module structure) */
- disable_ro_nx(&mod->core_layout);
module_memfree(mod->core_layout.base);
}
@@ -3420,17 +3405,34 @@ static void do_mod_ctors(struct module *mod)
/* For freeing module_init on success, in case kallsyms traversing */
struct mod_initfree {
- struct rcu_head rcu;
+ struct llist_node node;
void *module_init;
};
-static void do_free_init(struct rcu_head *head)
+static void do_free_init(struct work_struct *w)
{
- struct mod_initfree *m = container_of(head, struct mod_initfree, rcu);
- module_memfree(m->module_init);
- kfree(m);
+ struct llist_node *pos, *n, *list;
+ struct mod_initfree *initfree;
+
+ list = llist_del_all(&init_free_list);
+
+ synchronize_rcu();
+
+ llist_for_each_safe(pos, n, list) {
+ initfree = container_of(pos, struct mod_initfree, node);
+ module_memfree(initfree->module_init);
+ kfree(initfree);
+ }
}
+static int __init modules_wq_init(void)
+{
+ INIT_WORK(&init_free_wq, do_free_init);
+ init_llist_head(&init_free_list);
+ return 0;
+}
+module_init(modules_wq_init);
+
/*
* This is where the real work happens.
*
@@ -3507,7 +3509,6 @@ static noinline int do_init_module(struct module *mod)
#endif
module_enable_ro(mod, true);
mod_tree_remove_init(mod);
- disable_ro_nx(&mod->init_layout);
module_arch_freeing_init(mod);
mod->init_layout.base = NULL;
mod->init_layout.size = 0;
@@ -3518,14 +3519,18 @@ static noinline int do_init_module(struct module *mod)
* We want to free module_init, but be aware that kallsyms may be
* walking this with preempt disabled. In all the failure paths, we
* call synchronize_rcu(), but we don't want to slow down the success
- * path, so use actual RCU here.
+ * path. module_memfree() cannot be called in an interrupt, so do the
+ * work and call synchronize_rcu() in a work queue.
+ *
* Note that module_alloc() on most architectures creates W+X page
* mappings which won't be cleaned up until do_free_init() runs. Any
* code such as mark_rodata_ro() which depends on those mappings to
* be cleaned up needs to sync with the queued work - ie
* rcu_barrier()
*/
- call_rcu(&freeinit->rcu, do_free_init);
+ if (llist_add(&freeinit->node, &init_free_list))
+ schedule_work(&init_free_wq);
+
mutex_unlock(&module_mutex);
wake_up_all(&module_wq);
@@ -3822,10 +3827,6 @@ static int load_module(struct load_info *info, const char __user *uargs,
module_bug_cleanup(mod);
mutex_unlock(&module_mutex);
- /* we can't deallocate the module until we clear memory protection */
- module_disable_ro(mod);
- module_disable_nx(mod);
-
ddebug_cleanup:
ftrace_release_mod(mod);
dynamic_debug_remove(mod, info->debug);
--
2.17.1
^ permalink raw reply related
* [PATCH v4 15/23] mm: Make hibernate handle unmapped pages
From: Rick Edgecombe @ 2019-04-22 18:57 UTC (permalink / raw)
To: Borislav Petkov, Andy Lutomirski, Ingo Molnar
Cc: linux-kernel, x86, hpa, Thomas Gleixner, Nadav Amit, Dave Hansen,
Peter Zijlstra, linux_dti, linux-integrity, linux-security-module,
akpm, kernel-hardening, linux-mm, will.deacon, ard.biesheuvel,
kristen, deneen.t.dock, Rick Edgecombe, Rafael J. Wysocki,
Pavel Machek
In-Reply-To: <20190422185805.1169-1-rick.p.edgecombe@intel.com>
Make hibernate handle unmapped pages on the direct map when
CONFIG_ARCH_HAS_SET_ALIAS is set. These functions allow for setting pages
to invalid configurations, so now hibernate should check if the pages have
valid mappings and handle if they are unmapped when doing a hibernate
save operation.
Previously this checking was already done when CONFIG_DEBUG_PAGEALLOC
was configured. It does not appear to have a big hibernating performance
impact. The speed of the saving operation before this change was measured
as 819.02 MB/s, and after was measured at 813.32 MB/s.
Before:
[ 4.670938] PM: Wrote 171996 kbytes in 0.21 seconds (819.02 MB/s)
After:
[ 4.504714] PM: Wrote 178932 kbytes in 0.22 seconds (813.32 MB/s)
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Borislav Petkov <bp@alien8.de>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
arch/x86/mm/pageattr.c | 4 ----
include/linux/mm.h | 18 ++++++------------
kernel/power/snapshot.c | 5 +++--
mm/page_alloc.c | 7 +++++--
4 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 3574550192c6..daf4d645e537 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -2257,7 +2257,6 @@ int set_direct_map_default_noflush(struct page *page)
return __set_pages_p(page, 1);
}
-#ifdef CONFIG_DEBUG_PAGEALLOC
void __kernel_map_pages(struct page *page, int numpages, int enable)
{
if (PageHighMem(page))
@@ -2302,11 +2301,8 @@ bool kernel_page_present(struct page *page)
pte = lookup_address((unsigned long)page_address(page), &level);
return (pte_val(*pte) & _PAGE_PRESENT);
}
-
#endif /* CONFIG_HIBERNATION */
-#endif /* CONFIG_DEBUG_PAGEALLOC */
-
int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
unsigned numpages, unsigned long page_flags)
{
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 6b10c21630f5..083d7b4863ed 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2610,37 +2610,31 @@ static inline void kernel_poison_pages(struct page *page, int numpages,
int enable) { }
#endif
-#ifdef CONFIG_DEBUG_PAGEALLOC
extern bool _debug_pagealloc_enabled;
-extern void __kernel_map_pages(struct page *page, int numpages, int enable);
static inline bool debug_pagealloc_enabled(void)
{
- return _debug_pagealloc_enabled;
+ return IS_ENABLED(CONFIG_DEBUG_PAGEALLOC) && _debug_pagealloc_enabled;
}
+#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP)
+extern void __kernel_map_pages(struct page *page, int numpages, int enable);
+
static inline void
kernel_map_pages(struct page *page, int numpages, int enable)
{
- if (!debug_pagealloc_enabled())
- return;
-
__kernel_map_pages(page, numpages, enable);
}
#ifdef CONFIG_HIBERNATION
extern bool kernel_page_present(struct page *page);
#endif /* CONFIG_HIBERNATION */
-#else /* CONFIG_DEBUG_PAGEALLOC */
+#else /* CONFIG_DEBUG_PAGEALLOC || CONFIG_ARCH_HAS_SET_DIRECT_MAP */
static inline void
kernel_map_pages(struct page *page, int numpages, int enable) {}
#ifdef CONFIG_HIBERNATION
static inline bool kernel_page_present(struct page *page) { return true; }
#endif /* CONFIG_HIBERNATION */
-static inline bool debug_pagealloc_enabled(void)
-{
- return false;
-}
-#endif /* CONFIG_DEBUG_PAGEALLOC */
+#endif /* CONFIG_DEBUG_PAGEALLOC || CONFIG_ARCH_HAS_SET_DIRECT_MAP */
#ifdef __HAVE_ARCH_GATE_AREA
extern struct vm_area_struct *get_gate_vma(struct mm_struct *mm);
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index f08a1e4ee1d4..bc9558ab1e5b 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -1342,8 +1342,9 @@ static inline void do_copy_page(long *dst, long *src)
* safe_copy_page - Copy a page in a safe way.
*
* Check if the page we are going to copy is marked as present in the kernel
- * page tables (this always is the case if CONFIG_DEBUG_PAGEALLOC is not set
- * and in that case kernel_page_present() always returns 'true').
+ * page tables. This always is the case if CONFIG_DEBUG_PAGEALLOC or
+ * CONFIG_ARCH_HAS_SET_DIRECT_MAP is not set. In that case kernel_page_present()
+ * always returns 'true'.
*/
static void safe_copy_page(void *dst, struct page *s_page)
{
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d96ca5bc555b..34a70681a4af 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1131,7 +1131,9 @@ static __always_inline bool free_pages_prepare(struct page *page,
}
arch_free_page(page, order);
kernel_poison_pages(page, 1 << order, 0);
- kernel_map_pages(page, 1 << order, 0);
+ if (debug_pagealloc_enabled())
+ kernel_map_pages(page, 1 << order, 0);
+
kasan_free_nondeferred_pages(page, order);
return true;
@@ -2001,7 +2003,8 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
set_page_refcounted(page);
arch_alloc_page(page, order);
- kernel_map_pages(page, 1 << order, 1);
+ if (debug_pagealloc_enabled())
+ kernel_map_pages(page, 1 << order, 1);
kasan_alloc_pages(page, order);
kernel_poison_pages(page, 1 << order, 1);
set_page_owner(page, order, gfp_flags);
--
2.17.1
^ permalink raw reply related
* [PATCH v4 20/23] x86/kprobes: Use vmalloc special flag
From: Rick Edgecombe @ 2019-04-22 18:58 UTC (permalink / raw)
To: Borislav Petkov, Andy Lutomirski, Ingo Molnar
Cc: linux-kernel, x86, hpa, Thomas Gleixner, Nadav Amit, Dave Hansen,
Peter Zijlstra, linux_dti, linux-integrity, linux-security-module,
akpm, kernel-hardening, linux-mm, will.deacon, ard.biesheuvel,
kristen, deneen.t.dock, Rick Edgecombe, Masami Hiramatsu
In-Reply-To: <20190422185805.1169-1-rick.p.edgecombe@intel.com>
Use new flag VM_FLUSH_RESET_PERMS for handling freeing of special
permissioned memory in vmalloc and remove places where memory was set NX
and RW before freeing which is no longer needed.
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
arch/x86/kernel/kprobes/core.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index 1591852d3ac4..136695e4434a 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -434,6 +434,7 @@ void *alloc_insn_page(void)
if (!page)
return NULL;
+ set_vm_flush_reset_perms(page);
/*
* First make the page read-only, and only then make it executable to
* prevent it from being W+X in between.
@@ -452,12 +453,6 @@ void *alloc_insn_page(void)
/* Recover page to RW mode before releasing it */
void free_insn_page(void *page)
{
- /*
- * First make the page non-executable, and only then make it writable to
- * prevent it from being W+X in between.
- */
- set_memory_nx((unsigned long)page, 1);
- set_memory_rw((unsigned long)page, 1);
module_memfree(page);
}
--
2.17.1
^ permalink raw reply related
* [PATCH v4 21/23] x86/alternative: Comment about module removal races
From: Rick Edgecombe @ 2019-04-22 18:58 UTC (permalink / raw)
To: Borislav Petkov, Andy Lutomirski, Ingo Molnar
Cc: linux-kernel, x86, hpa, Thomas Gleixner, Nadav Amit, Dave Hansen,
Peter Zijlstra, linux_dti, linux-integrity, linux-security-module,
akpm, kernel-hardening, linux-mm, will.deacon, ard.biesheuvel,
kristen, deneen.t.dock, Nadav Amit, Masami Hiramatsu,
Rick Edgecombe
In-Reply-To: <20190422185805.1169-1-rick.p.edgecombe@intel.com>
From: Nadav Amit <namit@vmware.com>
Add a comment to clarify that users of text_poke() must ensure that
no races with module removal take place.
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Nadav Amit <namit@vmware.com>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
arch/x86/kernel/alternative.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 18f959975ea0..7b9b49dfc05a 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -810,6 +810,11 @@ static void *__text_poke(void *addr, const void *opcode, size_t len)
* It means the size must be writable atomically and the address must be aligned
* in a way that permits an atomic write. It also makes sure we fit on a single
* page.
+ *
+ * Note that the caller must ensure that if the modified code is part of a
+ * module, the module would not be removed during poking. This can be achieved
+ * by registering a module notifier, and ordering module removal and patching
+ * trough a mutex.
*/
void *text_poke(void *addr, const void *opcode, size_t len)
{
--
2.17.1
^ permalink raw reply related
* [PATCH v4 22/23] tlb: provide default nmi_uaccess_okay()
From: Rick Edgecombe @ 2019-04-22 18:58 UTC (permalink / raw)
To: Borislav Petkov, Andy Lutomirski, Ingo Molnar
Cc: linux-kernel, x86, hpa, Thomas Gleixner, Nadav Amit, Dave Hansen,
Peter Zijlstra, linux_dti, linux-integrity, linux-security-module,
akpm, kernel-hardening, linux-mm, will.deacon, ard.biesheuvel,
kristen, deneen.t.dock, Nadav Amit, Rick Edgecombe
In-Reply-To: <20190422185805.1169-1-rick.p.edgecombe@intel.com>
From: Nadav Amit <namit@vmware.com>
x86 has an nmi_uaccess_okay(), but other architectures do not.
Arch-independent code might need to know whether access to user
addresses is ok in an NMI context or in other code whose execution
context is unknown. Specifically, this function is needed for
bpf_probe_write_user().
Add a default implementation of nmi_uaccess_okay() for architectures
that do not have such a function.
Signed-off-by: Nadav Amit <namit@vmware.com>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
arch/x86/include/asm/tlbflush.h | 2 ++
include/asm-generic/tlb.h | 9 +++++++++
2 files changed, 11 insertions(+)
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 90926e8dd1f8..dee375831962 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -274,6 +274,8 @@ static inline bool nmi_uaccess_okay(void)
return true;
}
+#define nmi_uaccess_okay nmi_uaccess_okay
+
/* Initialize cr4 shadow for this CPU. */
static inline void cr4_init_shadow(void)
{
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index b9edc7608d90..480e5b2a5748 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -21,6 +21,15 @@
#include <asm/tlbflush.h>
#include <asm/cacheflush.h>
+/*
+ * Blindly accessing user memory from NMI context can be dangerous
+ * if we're in the middle of switching the current user task or switching
+ * the loaded mm.
+ */
+#ifndef nmi_uaccess_okay
+# define nmi_uaccess_okay() true
+#endif
+
#ifdef CONFIG_MMU
/*
--
2.17.1
^ permalink raw reply related
* [PATCH v4 23/23] bpf: Fail bpf_probe_write_user() while mm is switched
From: Rick Edgecombe @ 2019-04-22 18:58 UTC (permalink / raw)
To: Borislav Petkov, Andy Lutomirski, Ingo Molnar
Cc: linux-kernel, x86, hpa, Thomas Gleixner, Nadav Amit, Dave Hansen,
Peter Zijlstra, linux_dti, linux-integrity, linux-security-module,
akpm, kernel-hardening, linux-mm, will.deacon, ard.biesheuvel,
kristen, deneen.t.dock, Nadav Amit, Daniel Borkmann,
Alexei Starovoitov, Rick Edgecombe
In-Reply-To: <20190422185805.1169-1-rick.p.edgecombe@intel.com>
From: Nadav Amit <namit@vmware.com>
When using a temporary mm, bpf_probe_write_user() should not be able to
write to user memory, since user memory addresses may be used to map
kernel memory. Detect these cases and fail bpf_probe_write_user() in
such cases.
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
Reported-by: Jann Horn <jannh@google.com>
Suggested-by: Jann Horn <jannh@google.com>
Signed-off-by: Nadav Amit <namit@vmware.com>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
kernel/trace/bpf_trace.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index d64c00afceb5..94b0e37d90ef 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -14,6 +14,8 @@
#include <linux/syscalls.h>
#include <linux/error-injection.h>
+#include <asm/tlb.h>
+
#include "trace_probe.h"
#include "trace.h"
@@ -163,6 +165,10 @@ BPF_CALL_3(bpf_probe_write_user, void *, unsafe_ptr, const void *, src,
* access_ok() should prevent writing to non-user memory, but in
* some situations (nommu, temporary switch, etc) access_ok() does
* not provide enough validation, hence the check on KERNEL_DS.
+ *
+ * nmi_uaccess_okay() ensures the probe is not run in an interim
+ * state, when the task or mm are switched. This is specifically
+ * required to prevent the use of temporary mm.
*/
if (unlikely(in_interrupt() ||
@@ -170,6 +176,8 @@ BPF_CALL_3(bpf_probe_write_user, void *, unsafe_ptr, const void *, src,
return -EPERM;
if (unlikely(uaccess_kernel()))
return -EPERM;
+ if (unlikely(!nmi_uaccess_okay()))
+ return -EPERM;
if (!access_ok(unsafe_ptr, size))
return -EPERM;
--
2.17.1
^ permalink raw reply related
* [PATCH v4 14/23] x86/mm/cpa: Add set_direct_map_ functions
From: Rick Edgecombe @ 2019-04-22 18:57 UTC (permalink / raw)
To: Borislav Petkov, Andy Lutomirski, Ingo Molnar
Cc: linux-kernel, x86, hpa, Thomas Gleixner, Nadav Amit, Dave Hansen,
Peter Zijlstra, linux_dti, linux-integrity, linux-security-module,
akpm, kernel-hardening, linux-mm, will.deacon, ard.biesheuvel,
kristen, deneen.t.dock, Rick Edgecombe
In-Reply-To: <20190422185805.1169-1-rick.p.edgecombe@intel.com>
Add two new functions set_direct_map_default_noflush() and
set_direct_map_invalid_noflush() for setting the direct map alias for the
page to its default valid permissions and to an invalid state that cannot
be cached in a TLB, respectively. These functions do not flush the TLB.
Note, __kernel_map_pages() does something similar but flushes the TLB and
doesn't reset the permission bits to default on all architectures.
Also add an ARCH config ARCH_HAS_SET_DIRECT_MAP for specifying whether
these have an actual implementation or a default empty one.
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
arch/Kconfig | 4 ++++
arch/x86/Kconfig | 1 +
arch/x86/include/asm/set_memory.h | 3 +++
arch/x86/mm/pageattr.c | 14 +++++++++++---
include/linux/set_memory.h | 11 +++++++++++
5 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig
index 3ab446bd12ef..5e43fcbad4ca 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -249,6 +249,10 @@ config ARCH_HAS_FORTIFY_SOURCE
config ARCH_HAS_SET_MEMORY
bool
+# Select if arch has all set_direct_map_invalid/default() functions
+config ARCH_HAS_SET_DIRECT_MAP
+ bool
+
# Select if arch init_task must go in the __init_task_data section
config ARCH_TASK_STRUCT_ON_STACK
bool
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2ec5e850b807..45d788354376 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -66,6 +66,7 @@ config X86
select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64
select ARCH_HAS_UACCESS_MCSAFE if X86_64 && X86_MCE
select ARCH_HAS_SET_MEMORY
+ select ARCH_HAS_SET_DIRECT_MAP
select ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_HAS_STRICT_MODULE_RWX
select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
index 07a25753e85c..ae7b909dc242 100644
--- a/arch/x86/include/asm/set_memory.h
+++ b/arch/x86/include/asm/set_memory.h
@@ -85,6 +85,9 @@ int set_pages_nx(struct page *page, int numpages);
int set_pages_ro(struct page *page, int numpages);
int set_pages_rw(struct page *page, int numpages);
+int set_direct_map_invalid_noflush(struct page *page);
+int set_direct_map_default_noflush(struct page *page);
+
extern int kernel_set_to_readonly;
void set_kernel_text_rw(void);
void set_kernel_text_ro(void);
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 4c570612e24e..3574550192c6 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -2209,8 +2209,6 @@ int set_pages_rw(struct page *page, int numpages)
return set_memory_rw(addr, numpages);
}
-#ifdef CONFIG_DEBUG_PAGEALLOC
-
static int __set_pages_p(struct page *page, int numpages)
{
unsigned long tempaddr = (unsigned long) page_address(page);
@@ -2249,6 +2247,17 @@ static int __set_pages_np(struct page *page, int numpages)
return __change_page_attr_set_clr(&cpa, 0);
}
+int set_direct_map_invalid_noflush(struct page *page)
+{
+ return __set_pages_np(page, 1);
+}
+
+int set_direct_map_default_noflush(struct page *page)
+{
+ return __set_pages_p(page, 1);
+}
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
void __kernel_map_pages(struct page *page, int numpages, int enable)
{
if (PageHighMem(page))
@@ -2282,7 +2291,6 @@ void __kernel_map_pages(struct page *page, int numpages, int enable)
}
#ifdef CONFIG_HIBERNATION
-
bool kernel_page_present(struct page *page)
{
unsigned int level;
diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
index 2a986d282a97..b5071497b8cb 100644
--- a/include/linux/set_memory.h
+++ b/include/linux/set_memory.h
@@ -17,6 +17,17 @@ static inline int set_memory_x(unsigned long addr, int numpages) { return 0; }
static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; }
#endif
+#ifndef CONFIG_ARCH_HAS_SET_DIRECT_MAP
+static inline int set_direct_map_invalid_noflush(struct page *page)
+{
+ return 0;
+}
+static inline int set_direct_map_default_noflush(struct page *page)
+{
+ return 0;
+}
+#endif
+
#ifndef set_mce_nospec
static inline int set_mce_nospec(unsigned long pfn)
{
--
2.17.1
^ permalink raw reply related
* [PATCH v4 03/23] x86/mm: Introduce temporary mm structs
From: Rick Edgecombe @ 2019-04-22 18:57 UTC (permalink / raw)
To: Borislav Petkov, Andy Lutomirski, Ingo Molnar
Cc: linux-kernel, x86, hpa, Thomas Gleixner, Nadav Amit, Dave Hansen,
Peter Zijlstra, linux_dti, linux-integrity, linux-security-module,
akpm, kernel-hardening, linux-mm, will.deacon, ard.biesheuvel,
kristen, deneen.t.dock, Kees Cook, Dave Hansen, Nadav Amit,
Rick Edgecombe
In-Reply-To: <20190422185805.1169-1-rick.p.edgecombe@intel.com>
From: Andy Lutomirski <luto@kernel.org>
Using a dedicated page-table for temporary PTEs prevents other cores
from using - even speculatively - these PTEs, thereby providing two
benefits:
(1) Security hardening: an attacker that gains kernel memory writing
abilities cannot easily overwrite sensitive data.
(2) Avoiding TLB shootdowns: the PTEs do not need to be flushed in
remote page-tables.
To do so a temporary mm_struct can be used. Mappings which are private
for this mm can be set in the userspace part of the address-space.
During the whole time in which the temporary mm is loaded, interrupts
must be disabled.
The first use-case for temporary mm struct, which will follow, is for
poking the kernel text.
[ Commit message was written by Nadav Amit ]
Cc: Kees Cook <keescook@chromium.org>
Cc: Dave Hansen <dave.hansen@intel.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
Tested-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Nadav Amit <namit@vmware.com>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
arch/x86/include/asm/mmu_context.h | 33 ++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index 19d18fae6ec6..d684b954f3c0 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -356,4 +356,37 @@ static inline unsigned long __get_current_cr3_fast(void)
return cr3;
}
+typedef struct {
+ struct mm_struct *prev;
+} temp_mm_state_t;
+
+/*
+ * Using a temporary mm allows to set temporary mappings that are not accessible
+ * by other cores. Such mappings are needed to perform sensitive memory writes
+ * that override the kernel memory protections (e.g., W^X), without exposing the
+ * temporary page-table mappings that are required for these write operations to
+ * other cores. Using temporary mm also allows to avoid TLB shootdowns when the
+ * mapping is torn down.
+ *
+ * Context: The temporary mm needs to be used exclusively by a single core. To
+ * harden security IRQs must be disabled while the temporary mm is
+ * loaded, thereby preventing interrupt handler bugs from overriding
+ * the kernel memory protection.
+ */
+static inline temp_mm_state_t use_temporary_mm(struct mm_struct *mm)
+{
+ temp_mm_state_t state;
+
+ lockdep_assert_irqs_disabled();
+ state.prev = this_cpu_read(cpu_tlbstate.loaded_mm);
+ switch_mm_irqs_off(NULL, mm, current);
+ return state;
+}
+
+static inline void unuse_temporary_mm(temp_mm_state_t prev)
+{
+ lockdep_assert_irqs_disabled();
+ switch_mm_irqs_off(NULL, prev.prev, current);
+}
+
#endif /* _ASM_X86_MMU_CONTEXT_H */
--
2.17.1
^ permalink raw reply related
* [PATCH v4 00/23] Merge text_poke fixes and executable lockdowns
From: Rick Edgecombe @ 2019-04-22 18:57 UTC (permalink / raw)
To: Borislav Petkov, Andy Lutomirski, Ingo Molnar
Cc: linux-kernel, x86, hpa, Thomas Gleixner, Nadav Amit, Dave Hansen,
Peter Zijlstra, linux_dti, linux-integrity, linux-security-module,
akpm, kernel-hardening, linux-mm, will.deacon, ard.biesheuvel,
kristen, deneen.t.dock, Rick Edgecombe
Hi,
Picking this up again after seeing how things shook out around the issue
raised here: https://lkml.org/lkml/2019/2/22/702
This patchset improves several overlapping issues around stale TLB entries and
W^X violations. It is combined from "x86/alternative: text_poke() enhancements
v7" [1] and "Don’t leave executable TLB entries to freed pages v2" [2] patchsets
that were conflicting.
The related issues that this fixes:
1. Fixmap PTEs that are used for patching are available for access from
other cores and might be exploited. They are not even flushed from
the TLB in remote cores, so the risk is even higher. Address this
issue by introducing a temporary mm that is only used during
patching. Unfortunately, due to init ordering, fixmap is still used
during boot-time patching. Future patches can eliminate the need for
it.
2. Missing lockdep assertion to ensure text_mutex is taken. It is
actually not always taken, so fix the instances that were found not
to take the lock (although they should be safe even without taking
the lock).
3. Module_alloc returning memory that is RWX until a module is finished
loading.
4. Sometimes when memory is freed via the module subsystem, an
executable permissioned TLB entry can remain to a freed page. If the
page is re-used to back an address that will receive data from
userspace, it can result in user data being mapped as executable in
the kernel. The root of this behavior is vfree lazily flushing the
TLB, but not lazily freeing the underlying pages.
Changes v3 to v4:
- Remove the size parameter from tramp_free() [Steven]
- Remove caching of hw_breakpoint_active() [Sean]
- Prevent the use of bpf_probe_write_user() while using temporary mm [Jann]
- Fix build issues on other archs
Changes v2 to v3:
- Fix commit messages and comments [Boris]
- Rename VM_HAS_SPECIAL_PERMS [Boris]
- Remove unnecessary local variables [Boris]
- Rename set_alias_*() functions [Boris, Andy]
- Save/restore DR registers when using temporary mm
- Move line deletion from patch 10 to patch 17
Changes v1 to v2:
- Adding “Reviewed-by tag” [Masami]
- Comment instead of code to warn against module removal while
patching [Masami]
- Avoiding open-coded TLB flush [Andy]
- Remove "This patch" [Borislav Petkov]
- Not set global bit during text poking [Andy, hpa]
- Add Ack from [Pavel Machek]
- Split patch 16 "Plug in new special vfree flag" into 4 patches (16-19)
to make it easier to review. There were no code changes.
The changes from "Don’t leave executable TLB entries to freed pages
v2" to v1:
- Add support for case of hibernate trying to save an unmapped page
on the directmap. (Ard Biesheuvel)
- No week arch breakout for vfree-ing special memory (Andy Lutomirski)
- Avoid changing deferred free code by moving modules init free to work
queue (Andy Lutomirski)
- Plug in new flag for kprobes and ftrace
- More arch generic names for set_pages functions (Ard Biesheuvel)
- Fix for TLB not always flushing the directmap (Nadav Amit)
Changes from "x86/alternative: text_poke() enhancements v7" to v1
- Fix build failure on CONFIG_RANDOMIZE_BASE=n (Rick)
- Remove text_poke usage from ftrace (Nadav)
[1] https://lkml.org/lkml/2018/12/5/200
[2] https://lkml.org/lkml/2018/12/11/1571
Andy Lutomirski (1):
x86/mm: Introduce temporary mm structs
Nadav Amit (15):
Fix "x86/alternatives: Lockdep-enforce text_mutex in text_poke*()"
x86/jump_label: Use text_poke_early() during early init
x86/mm: Save DRs when loading a temporary mm
fork: Provide a function for copying init_mm
x86/alternative: Initialize temporary mm for patching
x86/alternative: Use temporary mm for text poking
x86/kgdb: Avoid redundant comparison of patched code
x86/ftrace: Set trampoline pages as executable
x86/kprobes: Set instruction page as executable
x86/module: Avoid breaking W^X while loading modules
x86/jump-label: Remove support for custom poker
x86/alternative: Remove the return value of text_poke_*()
x86/alternative: Comment about module removal races
tlb: provide default nmi_uaccess_okay()
bpf: Fail bpf_probe_write_user() while mm is switched
Rick Edgecombe (7):
x86/mm/cpa: Add set_direct_map_ functions
mm: Make hibernate handle unmapped pages
vmalloc: Add flag for free of special permsissions
modules: Use vmalloc special flag
bpf: Use vmalloc special flag
x86/ftrace: Use vmalloc special flag
x86/kprobes: Use vmalloc special flag
arch/Kconfig | 4 +
arch/x86/Kconfig | 1 +
arch/x86/include/asm/fixmap.h | 2 -
arch/x86/include/asm/mmu_context.h | 56 ++++++++
arch/x86/include/asm/pgtable.h | 3 +
arch/x86/include/asm/set_memory.h | 3 +
arch/x86/include/asm/text-patching.h | 7 +-
arch/x86/include/asm/tlbflush.h | 2 +
arch/x86/kernel/alternative.c | 201 ++++++++++++++++++++-------
arch/x86/kernel/ftrace.c | 22 +--
arch/x86/kernel/jump_label.c | 21 ++-
arch/x86/kernel/kgdb.c | 25 +---
arch/x86/kernel/kprobes/core.c | 19 ++-
arch/x86/kernel/module.c | 2 +-
arch/x86/mm/init_64.c | 36 +++++
arch/x86/mm/pageattr.c | 16 ++-
arch/x86/xen/mmu_pv.c | 2 -
include/asm-generic/tlb.h | 9 ++
include/linux/filter.h | 18 +--
include/linux/mm.h | 18 +--
include/linux/sched/task.h | 1 +
include/linux/set_memory.h | 11 ++
include/linux/vmalloc.h | 15 ++
init/main.c | 3 +
kernel/bpf/core.c | 1 -
kernel/fork.c | 24 +++-
kernel/module.c | 82 ++++++-----
kernel/power/snapshot.c | 5 +-
kernel/trace/bpf_trace.c | 8 ++
mm/page_alloc.c | 7 +-
mm/vmalloc.c | 113 ++++++++++++---
31 files changed, 542 insertions(+), 195 deletions(-)
--
2.17.1
^ permalink raw reply
* Re: [PATCH v2 23/79] docs: netlabel: convert docs to ReST and rename to *.rst
From: Paul Moore @ 2019-04-22 18:10 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: Linux Doc Mailing List, Mauro Carvalho Chehab, linux-kernel,
Jonathan Corbet, netdev, linux-security-module
In-Reply-To: <72133d276dd8cde2d1ee8528b4e87ab2a614cbd0.1555938376.git.mchehab+samsung@kernel.org>
On Mon, Apr 22, 2019 at 9:28 AM Mauro Carvalho Chehab
<mchehab+samsung@kernel.org> wrote:
>
> Convert netlabel documentation to ReST.
>
> This was trivial: just add proper title markups.
>
> At its new index.rst, let's add a :orphan: while this is not linked to
> the main index.rst file, in order to avoid build warnings.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
> ---
> .../{cipso_ipv4.txt => cipso_ipv4.rst} | 19 +++++++++++------
> Documentation/netlabel/draft_ietf.rst | 5 +++++
> Documentation/netlabel/index.rst | 21 +++++++++++++++++++
> .../{introduction.txt => introduction.rst} | 16 +++++++++-----
> .../{lsm_interface.txt => lsm_interface.rst} | 16 +++++++++-----
> 5 files changed, 61 insertions(+), 16 deletions(-)
> rename Documentation/netlabel/{cipso_ipv4.txt => cipso_ipv4.rst} (87%)
> create mode 100644 Documentation/netlabel/draft_ietf.rst
> create mode 100644 Documentation/netlabel/index.rst
> rename Documentation/netlabel/{introduction.txt => introduction.rst} (91%)
> rename Documentation/netlabel/{lsm_interface.txt => lsm_interface.rst} (88%)
Still looks fine to me. I should go through these docs again to make
sure they are current (the old email address definitely is a bad
sign).
Acked-by: Paul Moore <paul@paul-moore.com>
--
paul moore
www.paul-moore.com
^ permalink raw reply
* Re: [PATCH 00/90] LSM: Module stacking for all
From: Casey Schaufler @ 2019-04-22 16:10 UTC (permalink / raw)
To: Stephen Smalley, casey.schaufler, jmorris, linux-security-module,
selinux, Paul Moore
In-Reply-To: <fc27e666-5446-08b3-48c3-a4871d06bb68@tycho.nsa.gov>
On 4/22/2019 5:46 AM, Stephen Smalley wrote:
> On 4/21/19 1:31 PM, Casey Schaufler wrote:
>> On 4/19/2019 8:27 AM, Stephen Smalley wrote:
>>> On 4/18/19 8:44 PM, Casey Schaufler wrote:
>>>> This patchset provides the changes required for
>>>> the any security module to stack safely with any other.
>>>>
>>>> A new process attribute identifies which security module
>>>> information should be reported by SO_PEERSEC and the
>>>> /proc/.../attr/current interface. This is provided by
>>>> /proc/.../attr/display. Writing the name of the security
>>>> module desired to this interface will set which LSM hooks
>>>> will be called for this information. The first security
>>>> module providing the hooks will be used by default.
>>>>
>>>> The use of integer based security tokens (secids) is
>>>> generally (but not completely) replaced by a structure
>>>> lsm_export. The lsm_export structure can contain information
>>>> for each of the security modules that export information
>>>> outside the LSM layer.
>>>>
>>>> The LSM interfaces that provide "secctx" text strings
>>>> have been changed to use a structure "lsm_context"
>>>> instead of a pointer/length pair. In some cases the
>>>> interfaces used a "char *" pointer and in others a
>>>> "void *". This was necessary to ensure that the correct
>>>> release mechanism for the text is used. It also makes
>>>> many of the interfaces cleaner.
>>>>
>>>> Security modules that use Netlabel must agree on the
>>>> labels to be used on outgoing packets. If the modules
>>>> do not agree on the label option to be used the operation
>>>> will fail.
>>>>
>>>> Netfilter secmarks are restricted to a single security
>>>> module. The first module using the facility will "own"
>>>> the secmarks.
>>>
>>> Is it expected that enabling all security modules with this change
>>> will yield permission denials on packet send/receive (e.g. sendmsg()
>>> fails with permission denied), even without any configuration of
>>> NetLabel or SECMARK? That's what I see.
>>
>> Yes.
>>
>> Smack is much more aggressive about using labeled networking
>> than SELinux. Smack tells Netlabel to label networks, whereas
>> SELinux expects them to be unlabeled. Smack has the concept of
>> an "ambient" label, which is applied to unlabeled packets, and
>> for which packets are sent unlabeled. SELinux only uses netlabel
>> for the MLS component, whereas Smack uses it for the entire
>> label. In short, it's amazing if there's a case where they do
>> agree.
>>
>> You can make the default configuration work better by specifying
>> that the Smack "floor" label be treated more like the unconfined_t.
>>
>> # echo _ 0 0 0 > /sys/fs/smackfs/cipso2
>> # echo NotFloor > /sys/fs/smackfs/ambient
>>
>> Will result in a situation where the two MAC systems will agree
>> much more often.
>
> Not sure that should be required given that SELinux doesn't enable
> labeled networking at all by default,
SELinux doesn't. Smack does. Smack always enables labeled networking.
> so there is no real conflict until/unless someone configures labeled
> networking for SELinux.
Labeled networking is independent of the security modules.
Netlabel provides mechanism and leaves policy up to whoever
might look at the lsm_secattr. Once Smack sets the default
labeling everyone get the labels.
> I'll defer to Paul on that question.
>
> Given this restriction, to what extent have you tested Smack+SELinux
> together and what worked and didn't work? Everything except for
> networking-related tests?
Exporting security information, either by netlabel, netfilter
secmarks or security contexts has always been the challenge.
User space has never had to deal with the possibility that
there might be more than one security module to deal with.
A system that assumes a particular security module, as do
Fedora and Ubuntu, will have some opportunities for improvement
in the full stacking world.
I have been using Fedora 29 as a primary testbed. The
Fedora user space expects SELinux and so long as SELinux
appears before Smack in the LSM list, it's happy except
for the networking. If you put Smack ahead of SELinux the
user space fails when it tries to get or set SELinux
attributes. This is because the kernel uses the first
module providing the interfaces like SO_PEERSEC, and the
code only wants to see SELinux attributes.
I'm not 100% sure I can explain the behavior of overlayfs
in the combined environment, but then I'm not sure I really
understand how it's expected to work in any case.
^ permalink raw reply
* [PATCH v2 23/79] docs: netlabel: convert docs to ReST and rename to *.rst
From: Mauro Carvalho Chehab @ 2019-04-22 13:27 UTC (permalink / raw)
To: Linux Doc Mailing List
Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, linux-kernel,
Jonathan Corbet, Paul Moore, netdev, linux-security-module
In-Reply-To: <cover.1555938375.git.mchehab+samsung@kernel.org>
Convert netlabel documentation to ReST.
This was trivial: just add proper title markups.
At its new index.rst, let's add a :orphan: while this is not linked to
the main index.rst file, in order to avoid build warnings.
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
---
.../{cipso_ipv4.txt => cipso_ipv4.rst} | 19 +++++++++++------
Documentation/netlabel/draft_ietf.rst | 5 +++++
Documentation/netlabel/index.rst | 21 +++++++++++++++++++
.../{introduction.txt => introduction.rst} | 16 +++++++++-----
.../{lsm_interface.txt => lsm_interface.rst} | 16 +++++++++-----
5 files changed, 61 insertions(+), 16 deletions(-)
rename Documentation/netlabel/{cipso_ipv4.txt => cipso_ipv4.rst} (87%)
create mode 100644 Documentation/netlabel/draft_ietf.rst
create mode 100644 Documentation/netlabel/index.rst
rename Documentation/netlabel/{introduction.txt => introduction.rst} (91%)
rename Documentation/netlabel/{lsm_interface.txt => lsm_interface.rst} (88%)
diff --git a/Documentation/netlabel/cipso_ipv4.txt b/Documentation/netlabel/cipso_ipv4.rst
similarity index 87%
rename from Documentation/netlabel/cipso_ipv4.txt
rename to Documentation/netlabel/cipso_ipv4.rst
index a6075481fd60..cbd3f3231221 100644
--- a/Documentation/netlabel/cipso_ipv4.txt
+++ b/Documentation/netlabel/cipso_ipv4.rst
@@ -1,10 +1,13 @@
+===================================
NetLabel CIPSO/IPv4 Protocol Engine
-==============================================================================
+===================================
+
Paul Moore, paul.moore@hp.com
May 17, 2006
- * Overview
+Overview
+========
The NetLabel CIPSO/IPv4 protocol engine is based on the IETF Commercial
IP Security Option (CIPSO) draft from July 16, 1992. A copy of this
@@ -13,7 +16,8 @@ draft can be found in this directory
it to an RFC standard it has become a de-facto standard for labeled
networking and is used in many trusted operating systems.
- * Outbound Packet Processing
+Outbound Packet Processing
+==========================
The CIPSO/IPv4 protocol engine applies the CIPSO IP option to packets by
adding the CIPSO label to the socket. This causes all packets leaving the
@@ -24,7 +28,8 @@ label by using the NetLabel security module API; if the NetLabel "domain" is
configured to use CIPSO for packet labeling then a CIPSO IP option will be
generated and attached to the socket.
- * Inbound Packet Processing
+Inbound Packet Processing
+=========================
The CIPSO/IPv4 protocol engine validates every CIPSO IP option it finds at the
IP layer without any special handling required by the LSM. However, in order
@@ -33,7 +38,8 @@ NetLabel security module API to extract the security attributes of the packet.
This is typically done at the socket layer using the 'socket_sock_rcv_skb()'
LSM hook.
- * Label Translation
+Label Translation
+=================
The CIPSO/IPv4 protocol engine contains a mechanism to translate CIPSO security
attributes such as sensitivity level and category to values which are
@@ -42,7 +48,8 @@ Domain Of Interpretation (DOI) definition and are configured through the
NetLabel user space communication layer. Each DOI definition can have a
different security attribute mapping table.
- * Label Translation Cache
+Label Translation Cache
+=======================
The NetLabel system provides a framework for caching security attribute
mappings from the network labels to the corresponding LSM identifiers. The
diff --git a/Documentation/netlabel/draft_ietf.rst b/Documentation/netlabel/draft_ietf.rst
new file mode 100644
index 000000000000..5ed39ab8234b
--- /dev/null
+++ b/Documentation/netlabel/draft_ietf.rst
@@ -0,0 +1,5 @@
+Draft IETF CIPSO IP Security
+----------------------------
+
+ .. include:: draft-ietf-cipso-ipsecurity-01.txt
+ :literal:
diff --git a/Documentation/netlabel/index.rst b/Documentation/netlabel/index.rst
new file mode 100644
index 000000000000..47f1e0e5acd1
--- /dev/null
+++ b/Documentation/netlabel/index.rst
@@ -0,0 +1,21 @@
+:orphan:
+
+========
+NetLabel
+========
+
+.. toctree::
+ :maxdepth: 1
+
+ introduction
+ cipso_ipv4
+ lsm_interface
+
+ draft_ietf
+
+.. only:: subproject and html
+
+ Indices
+ =======
+
+ * :ref:`genindex`
diff --git a/Documentation/netlabel/introduction.txt b/Documentation/netlabel/introduction.rst
similarity index 91%
rename from Documentation/netlabel/introduction.txt
rename to Documentation/netlabel/introduction.rst
index 3caf77bcff0f..9333bbb0adc1 100644
--- a/Documentation/netlabel/introduction.txt
+++ b/Documentation/netlabel/introduction.rst
@@ -1,10 +1,13 @@
+=====================
NetLabel Introduction
-==============================================================================
+=====================
+
Paul Moore, paul.moore@hp.com
August 2, 2006
- * Overview
+Overview
+========
NetLabel is a mechanism which can be used by kernel security modules to attach
security attributes to outgoing network packets generated from user space
@@ -12,7 +15,8 @@ applications and read security attributes from incoming network packets. It
is composed of three main components, the protocol engines, the communication
layer, and the kernel security module API.
- * Protocol Engines
+Protocol Engines
+================
The protocol engines are responsible for both applying and retrieving the
network packet's security attributes. If any translation between the network
@@ -24,7 +28,8 @@ the NetLabel kernel security module API described below.
Detailed information about each NetLabel protocol engine can be found in this
directory.
- * Communication Layer
+Communication Layer
+===================
The communication layer exists to allow NetLabel configuration and monitoring
from user space. The NetLabel communication layer uses a message based
@@ -33,7 +38,8 @@ formatting of these NetLabel messages as well as the Generic NETLINK family
names can be found in the 'net/netlabel/' directory as comments in the
header files as well as in 'include/net/netlabel.h'.
- * Security Module API
+Security Module API
+===================
The purpose of the NetLabel security module API is to provide a protocol
independent interface to the underlying NetLabel protocol engines. In addition
diff --git a/Documentation/netlabel/lsm_interface.txt b/Documentation/netlabel/lsm_interface.rst
similarity index 88%
rename from Documentation/netlabel/lsm_interface.txt
rename to Documentation/netlabel/lsm_interface.rst
index 638c74f7de7f..026fc267f798 100644
--- a/Documentation/netlabel/lsm_interface.txt
+++ b/Documentation/netlabel/lsm_interface.rst
@@ -1,10 +1,13 @@
+========================================
NetLabel Linux Security Module Interface
-==============================================================================
+========================================
+
Paul Moore, paul.moore@hp.com
May 17, 2006
- * Overview
+Overview
+========
NetLabel is a mechanism which can set and retrieve security attributes from
network packets. It is intended to be used by LSM developers who want to make
@@ -12,7 +15,8 @@ use of a common code base for several different packet labeling protocols.
The NetLabel security module API is defined in 'include/net/netlabel.h' but a
brief overview is given below.
- * NetLabel Security Attributes
+NetLabel Security Attributes
+============================
Since NetLabel supports multiple different packet labeling protocols and LSMs
it uses the concept of security attributes to refer to the packet's security
@@ -24,7 +28,8 @@ configuration. It is up to the LSM developer to translate the NetLabel
security attributes into whatever security identifiers are in use for their
particular LSM.
- * NetLabel LSM Protocol Operations
+NetLabel LSM Protocol Operations
+================================
These are the functions which allow the LSM developer to manipulate the labels
on outgoing packets as well as read the labels on incoming packets. Functions
@@ -32,7 +37,8 @@ exist to operate both on sockets as well as the sk_buffs directly. These high
level functions are translated into low level protocol operations based on how
the administrator has configured the NetLabel subsystem.
- * NetLabel Label Mapping Cache Operations
+NetLabel Label Mapping Cache Operations
+=======================================
Depending on the exact configuration, translation between the network packet
label and the internal LSM security identifier can be time consuming. The
--
2.20.1
^ permalink raw reply related
* Re: [PATCH 69/90] LSM: Use full security context in security_inode_setsecctx
From: Tetsuo Handa @ 2019-04-22 13:13 UTC (permalink / raw)
To: Casey Schaufler; +Cc: casey.schaufler, jmorris, linux-security-module, selinux
In-Reply-To: <20190419004617.64627-70-casey@schaufler-ca.com>
On 2019/04/19 9:45, Casey Schaufler wrote:
> + hlist_for_each_entry(hp, &security_hook_heads.inode_setsecctx, list) {
> + if (strncmp(ctx, hp->lsm, strlen(hp->lsm))) {
> + WARN_ONCE(1, "security_inode_setsecctx form1 error\n");
> + rc = -EINVAL;
> + break;
> + }
Will you avoid using WARN*() ?
Since syzbot tests using panic_on_warn == 1, this WARN_ONCE() will act as panic().
^ permalink raw reply
* Re: [PATCH (resend)] tomoyo: Add a kernel config option for fuzzing testing.
From: Tetsuo Handa @ 2019-04-22 13:06 UTC (permalink / raw)
To: James Morris; +Cc: linux-security-module
In-Reply-To: <1555067094-9861-1-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp>
James, will you apply this patch and
"[PATCH 3/3] tomoyo: Check address length before reading address family" and
"[PATCH] tomoyo: Change pathname calculation for read-only filesystems." ?
On 2019/04/12 20:04, Tetsuo Handa wrote:
> syzbot is reporting kernel panic triggered by memory allocation fault
> injection before loading TOMOYO's policy [1]. To make the fuzzing tests
> useful, we need to assign a profile other than "disabled" (no-op) mode.
> Therefore, let's allow syzbot to load TOMOYO's built-in policy for
> "learning" mode using a kernel config option. This option must not be
> enabled for kernels built for production system, for this option also
> disables domain/program checks when modifying policy configuration via
> /sys/kernel/security/tomoyo/ interface.
>
> [1] https://syzkaller.appspot.com/bug?extid=29569ed06425fcf67a95
>
> Reported-by: syzbot <syzbot+e1b8084e532b6ee7afab@syzkaller.appspotmail.com>
> Reported-by: syzbot <syzbot+29569ed06425fcf67a95@syzkaller.appspotmail.com>
> Reported-by: syzbot <syzbot+2ee3f8974c2e7dc69feb@syzkaller.appspotmail.com>
> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> ---
> security/tomoyo/Kconfig | 10 ++++++++++
> security/tomoyo/common.c | 13 ++++++++++++-
> 2 files changed, 22 insertions(+), 1 deletion(-)
^ permalink raw reply
* Re: [PATCH 00/90] LSM: Module stacking for all
From: Stephen Smalley @ 2019-04-22 12:46 UTC (permalink / raw)
To: Casey Schaufler, casey.schaufler, jmorris, linux-security-module,
selinux, Paul Moore
In-Reply-To: <dbf99650-b53e-f197-aeb8-ed6fd9031837@schaufler-ca.com>
On 4/21/19 1:31 PM, Casey Schaufler wrote:
> On 4/19/2019 8:27 AM, Stephen Smalley wrote:
>> On 4/18/19 8:44 PM, Casey Schaufler wrote:
>>> This patchset provides the changes required for
>>> the any security module to stack safely with any other.
>>>
>>> A new process attribute identifies which security module
>>> information should be reported by SO_PEERSEC and the
>>> /proc/.../attr/current interface. This is provided by
>>> /proc/.../attr/display. Writing the name of the security
>>> module desired to this interface will set which LSM hooks
>>> will be called for this information. The first security
>>> module providing the hooks will be used by default.
>>>
>>> The use of integer based security tokens (secids) is
>>> generally (but not completely) replaced by a structure
>>> lsm_export. The lsm_export structure can contain information
>>> for each of the security modules that export information
>>> outside the LSM layer.
>>>
>>> The LSM interfaces that provide "secctx" text strings
>>> have been changed to use a structure "lsm_context"
>>> instead of a pointer/length pair. In some cases the
>>> interfaces used a "char *" pointer and in others a
>>> "void *". This was necessary to ensure that the correct
>>> release mechanism for the text is used. It also makes
>>> many of the interfaces cleaner.
>>>
>>> Security modules that use Netlabel must agree on the
>>> labels to be used on outgoing packets. If the modules
>>> do not agree on the label option to be used the operation
>>> will fail.
>>>
>>> Netfilter secmarks are restricted to a single security
>>> module. The first module using the facility will "own"
>>> the secmarks.
>>
>> Is it expected that enabling all security modules with this change
>> will yield permission denials on packet send/receive (e.g. sendmsg()
>> fails with permission denied), even without any configuration of
>> NetLabel or SECMARK? That's what I see.
>
> Yes.
>
> Smack is much more aggressive about using labeled networking
> than SELinux. Smack tells Netlabel to label networks, whereas
> SELinux expects them to be unlabeled. Smack has the concept of
> an "ambient" label, which is applied to unlabeled packets, and
> for which packets are sent unlabeled. SELinux only uses netlabel
> for the MLS component, whereas Smack uses it for the entire
> label. In short, it's amazing if there's a case where they do
> agree.
>
> You can make the default configuration work better by specifying
> that the Smack "floor" label be treated more like the unconfined_t.
>
> # echo _ 0 0 0 > /sys/fs/smackfs/cipso2
> # echo NotFloor > /sys/fs/smackfs/ambient
>
> Will result in a situation where the two MAC systems will agree
> much more often.
Not sure that should be required given that SELinux doesn't enable
labeled networking at all by default, so there is no real conflict
until/unless someone configures labeled networking for SELinux. I'll
defer to Paul on that question.
Given this restriction, to what extent have you tested Smack+SELinux
together and what worked and didn't work? Everything except for
networking-related tests?
>
>
>>
>>>
>>> git://github.com/cschaufler/lsm-stacking.git#stack-5.1-v2-full
>>>
>>> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
>>> ---
>>> drivers/android/binder.c | 25 +-
>>> fs/kernfs/dir.c | 6 +-
>>> fs/kernfs/inode.c | 31 +-
>>> fs/kernfs/kernfs-internal.h | 3 +-
>>> fs/nfs/inode.c | 13 +-
>>> fs/nfs/internal.h | 8 +-
>>> fs/nfs/nfs4proc.c | 17 +-
>>> fs/nfs/nfs4xdr.c | 16 +-
>>> fs/nfsd/nfs4proc.c | 8 +-
>>> fs/nfsd/nfs4xdr.c | 14 +-
>>> fs/nfsd/vfs.c | 7 +-
>>> fs/proc/base.c | 1 +
>>> include/linux/cred.h | 3 +-
>>> include/linux/lsm_hooks.h | 119 +++---
>>> include/linux/nfs4.h | 8 +-
>>> include/linux/security.h | 159 ++++++--
>>> include/net/af_unix.h | 2 +-
>>> include/net/netlabel.h | 18 +-
>>> include/net/scm.h | 14 +-
>>> kernel/audit.c | 43 +--
>>> kernel/audit.h | 9 +-
>>> kernel/auditfilter.c | 6 +-
>>> kernel/auditsc.c | 77 ++--
>>> kernel/cred.c | 15 +-
>>> net/ipv4/cipso_ipv4.c | 13 +-
>>> net/ipv4/ip_sockglue.c | 14 +-
>>> net/netfilter/nf_conntrack_netlink.c | 29 +-
>>> net/netfilter/nf_conntrack_standalone.c | 16 +-
>>> net/netfilter/nfnetlink_queue.c | 35 +-
>>> net/netfilter/nft_meta.c | 8 +-
>>> net/netfilter/xt_SECMARK.c | 9 +-
>>> net/netlabel/netlabel_kapi.c | 125 ++++--
>>> net/netlabel/netlabel_unlabeled.c | 101 +++--
>>> net/netlabel/netlabel_unlabeled.h | 2 +-
>>> net/netlabel/netlabel_user.c | 13 +-
>>> net/netlabel/netlabel_user.h | 2 +-
>>> net/unix/af_unix.c | 6 +-
>>> security/apparmor/audit.c | 4 +-
>>> security/apparmor/include/audit.h | 2 +-
>>> security/apparmor/include/net.h | 6 +-
>>> security/apparmor/include/secid.h | 9 +-
>>> security/apparmor/lsm.c | 64 ++--
>>> security/apparmor/secid.c | 42 +-
>>> security/integrity/ima/ima.h | 14 +-
>>> security/integrity/ima/ima_api.c | 9 +-
>>> security/integrity/ima/ima_appraise.c | 6 +-
>>> security/integrity/ima/ima_main.c | 34 +-
>>> security/integrity/ima/ima_policy.c | 19 +-
>>> security/security.c | 653
>>> +++++++++++++++++++++++++++-----
>>> security/selinux/hooks.c | 310 +++++++--------
>>> security/selinux/include/audit.h | 5 +-
>>> security/selinux/include/netlabel.h | 7 +
>>> security/selinux/include/objsec.h | 43 ++-
>>> security/selinux/netlabel.c | 69 ++--
>>> security/selinux/ss/services.c | 18 +-
>>> security/smack/smack.h | 34 ++
>>> security/smack/smack_access.c | 14 +-
>>> security/smack/smack_lsm.c | 388 ++++++++++---------
>>> security/smack/smack_netfilter.c | 48 ++-
>>> security/smack/smackfs.c | 23 +-
>>> 60 files changed, 1855 insertions(+), 961 deletions(-)
>>>
>>
^ permalink raw reply
* Re: [PATCH 00/90] LSM: Module stacking for all
From: Casey Schaufler @ 2019-04-21 17:31 UTC (permalink / raw)
To: Stephen Smalley, casey.schaufler, jmorris, linux-security-module,
selinux, casey
In-Reply-To: <6c9c3782-a168-c435-0caf-311c2d21d174@tycho.nsa.gov>
On 4/19/2019 8:27 AM, Stephen Smalley wrote:
> On 4/18/19 8:44 PM, Casey Schaufler wrote:
>> This patchset provides the changes required for
>> the any security module to stack safely with any other.
>>
>> A new process attribute identifies which security module
>> information should be reported by SO_PEERSEC and the
>> /proc/.../attr/current interface. This is provided by
>> /proc/.../attr/display. Writing the name of the security
>> module desired to this interface will set which LSM hooks
>> will be called for this information. The first security
>> module providing the hooks will be used by default.
>>
>> The use of integer based security tokens (secids) is
>> generally (but not completely) replaced by a structure
>> lsm_export. The lsm_export structure can contain information
>> for each of the security modules that export information
>> outside the LSM layer.
>>
>> The LSM interfaces that provide "secctx" text strings
>> have been changed to use a structure "lsm_context"
>> instead of a pointer/length pair. In some cases the
>> interfaces used a "char *" pointer and in others a
>> "void *". This was necessary to ensure that the correct
>> release mechanism for the text is used. It also makes
>> many of the interfaces cleaner.
>>
>> Security modules that use Netlabel must agree on the
>> labels to be used on outgoing packets. If the modules
>> do not agree on the label option to be used the operation
>> will fail.
>>
>> Netfilter secmarks are restricted to a single security
>> module. The first module using the facility will "own"
>> the secmarks.
>
> Is it expected that enabling all security modules with this change
> will yield permission denials on packet send/receive (e.g. sendmsg()
> fails with permission denied), even without any configuration of
> NetLabel or SECMARK? That's what I see.
Yes.
Smack is much more aggressive about using labeled networking
than SELinux. Smack tells Netlabel to label networks, whereas
SELinux expects them to be unlabeled. Smack has the concept of
an "ambient" label, which is applied to unlabeled packets, and
for which packets are sent unlabeled. SELinux only uses netlabel
for the MLS component, whereas Smack uses it for the entire
label. In short, it's amazing if there's a case where they do
agree.
You can make the default configuration work better by specifying
that the Smack "floor" label be treated more like the unconfined_t.
# echo _ 0 0 0 > /sys/fs/smackfs/cipso2
# echo NotFloor > /sys/fs/smackfs/ambient
Will result in a situation where the two MAC systems will agree
much more often.
>
>>
>> git://github.com/cschaufler/lsm-stacking.git#stack-5.1-v2-full
>>
>> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
>> ---
>> drivers/android/binder.c | 25 +-
>> fs/kernfs/dir.c | 6 +-
>> fs/kernfs/inode.c | 31 +-
>> fs/kernfs/kernfs-internal.h | 3 +-
>> fs/nfs/inode.c | 13 +-
>> fs/nfs/internal.h | 8 +-
>> fs/nfs/nfs4proc.c | 17 +-
>> fs/nfs/nfs4xdr.c | 16 +-
>> fs/nfsd/nfs4proc.c | 8 +-
>> fs/nfsd/nfs4xdr.c | 14 +-
>> fs/nfsd/vfs.c | 7 +-
>> fs/proc/base.c | 1 +
>> include/linux/cred.h | 3 +-
>> include/linux/lsm_hooks.h | 119 +++---
>> include/linux/nfs4.h | 8 +-
>> include/linux/security.h | 159 ++++++--
>> include/net/af_unix.h | 2 +-
>> include/net/netlabel.h | 18 +-
>> include/net/scm.h | 14 +-
>> kernel/audit.c | 43 +--
>> kernel/audit.h | 9 +-
>> kernel/auditfilter.c | 6 +-
>> kernel/auditsc.c | 77 ++--
>> kernel/cred.c | 15 +-
>> net/ipv4/cipso_ipv4.c | 13 +-
>> net/ipv4/ip_sockglue.c | 14 +-
>> net/netfilter/nf_conntrack_netlink.c | 29 +-
>> net/netfilter/nf_conntrack_standalone.c | 16 +-
>> net/netfilter/nfnetlink_queue.c | 35 +-
>> net/netfilter/nft_meta.c | 8 +-
>> net/netfilter/xt_SECMARK.c | 9 +-
>> net/netlabel/netlabel_kapi.c | 125 ++++--
>> net/netlabel/netlabel_unlabeled.c | 101 +++--
>> net/netlabel/netlabel_unlabeled.h | 2 +-
>> net/netlabel/netlabel_user.c | 13 +-
>> net/netlabel/netlabel_user.h | 2 +-
>> net/unix/af_unix.c | 6 +-
>> security/apparmor/audit.c | 4 +-
>> security/apparmor/include/audit.h | 2 +-
>> security/apparmor/include/net.h | 6 +-
>> security/apparmor/include/secid.h | 9 +-
>> security/apparmor/lsm.c | 64 ++--
>> security/apparmor/secid.c | 42 +-
>> security/integrity/ima/ima.h | 14 +-
>> security/integrity/ima/ima_api.c | 9 +-
>> security/integrity/ima/ima_appraise.c | 6 +-
>> security/integrity/ima/ima_main.c | 34 +-
>> security/integrity/ima/ima_policy.c | 19 +-
>> security/security.c | 653
>> +++++++++++++++++++++++++++-----
>> security/selinux/hooks.c | 310 +++++++--------
>> security/selinux/include/audit.h | 5 +-
>> security/selinux/include/netlabel.h | 7 +
>> security/selinux/include/objsec.h | 43 ++-
>> security/selinux/netlabel.c | 69 ++--
>> security/selinux/ss/services.c | 18 +-
>> security/smack/smack.h | 34 ++
>> security/smack/smack_access.c | 14 +-
>> security/smack/smack_lsm.c | 388 ++++++++++---------
>> security/smack/smack_netfilter.c | 48 ++-
>> security/smack/smackfs.c | 23 +-
>> 60 files changed, 1855 insertions(+), 961 deletions(-)
>>
>
^ permalink raw reply
* Re: [PATCH] proc: prevent changes to overridden credentials
From: Casey Schaufler @ 2019-04-21 17:14 UTC (permalink / raw)
To: Paul Moore, linux-security-module; +Cc: selinux, cj.chengjian, john.johansen
In-Reply-To: <155570011247.27135.12509150054846153288.stgit@chester>
On 4/19/2019 11:55 AM, Paul Moore wrote:
> Prevent userspace from changing the the /proc/PID/attr values if the
> task's credentials are currently overriden. This not only makes sense
> conceptually, it also prevents some really bizarre error cases caused
> when trying to commit credentials to a task with overridden
> credentials.
>
> Cc: <stable@vger.kernel.org>
> Reported-by: "chengjian (D)" <cj.chengjian@huawei.com>
> Signed-off-by: Paul Moore <paul@paul-moore.com>
Acked-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
> fs/proc/base.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index ddef482f1334..87ba007b86db 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -2539,6 +2539,11 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
> rcu_read_unlock();
> return -EACCES;
> }
> + /* Prevent changes to overridden credentials. */
> + if (current_cred() != current_real_cred()) {
> + rcu_read_unlock();
> + return -EBUSY;
> + }
> rcu_read_unlock();
>
> if (count > PAGE_SIZE)
>
^ permalink raw reply
* Re: kernel BUG at kernel/cred.c:434!
From: Yang Yingliang @ 2019-04-20 7:38 UTC (permalink / raw)
To: Paul Moore
Cc: Casey Schaufler, Oleg Nesterov, john.johansen, chengjian (D),
Kees Cook, NeilBrown, Anna Schumaker,
linux-kernel@vger.kernel.org, Al Viro, Xiexiuqi (Xie XiuQi),
Li Bin, Jason Yan, Peter Zijlstra, Ingo Molnar,
Linux Security Module list, SELinux
In-Reply-To: <CAHC9VhQqxL+LsK8YTD6PpTHaZsZ-PxAq3atdZKQcZLQZQH7t4g@mail.gmail.com>
On 2019/4/20 0:13, Paul Moore wrote:
> On Fri, Apr 19, 2019 at 10:34 AM Yang Yingliang
> <yangyingliang@huawei.com> wrote:
>> On 2019/4/19 21:24, Paul Moore wrote:
>>> On Thu, Apr 18, 2019 at 10:42 PM Yang Yingliang
>>> <yangyingliang@huawei.com> wrote:
>>>> On 2019/4/19 10:04, Paul Moore wrote:
>>>>> On Wed, Apr 17, 2019 at 10:50 PM Yang Yingliang
>>>>> <yangyingliang@huawei.com> wrote:
>>>>>> On 2019/4/18 8:24, Casey Schaufler wrote:
>>>>>>> On 4/17/2019 4:39 PM, Paul Moore wrote:
>>>>>>>> Since it looks like all three LSMs which implement the setprocattr
>>>>>>>> hook are vulnerable I'm open to the idea that proc_pid_attr_write() is
>>>>>>>> a better choice for the cred != read_cred check, but I would want to
>>>>>>>> make sure John and Casey are okay with that.
>>>>>>>>
>>>>>>>> John?
>>>>>>>>
>>>>>>>> Casey?
>>>>>>> I'm fine with the change going into proc_pid_attr_write().
>>>>>> The cred != real_cred checking is not enough.
>>>>>>
>>>>>> Consider this situation, when doing override, cred, real_cred and
>>>>>> new_cred are all same:
>>>>>>
>>>>>> after override_creds() cred == real_cred == new1_cred
>>>>> I'm sorry, you've lost me. After override_creds() returns
>>>>> current->cred and current->real_cred are not going to be the same,
>>>>> yes?
>>>> It's possible the new cred is equal to current->real_cred and
>>>> current->cred,
>>>> so after overrides_creds(), they have the same value.
>>> Both task_struct.cred and task_struct.real_cred are pointer values,
>>> assuming that one uses prepare_creds() to allocate/initialize a new
>>> cred struct for use with override_creds() then the newly created cred
>>> should never be equal to task_struct.real_cred. Am I missing
>>> something, or are you thinking of something else?
>> In do_acct_process(), file->f_cred may equal to current->real_cred, I
>> confirm
>> it by adding some debug message in do_acct_process() like this:
> I would expect that; real_cred is the task's objective DAC
> credentials, so using it for f_cred makes sense.
>
> What we are now talking about is the task's subjective credentials,
> which can be overridden via override_creds(), and are what the LSMs
> change via proc_pid_attr_write().
I'm not sure you got my point.
I was saying cred != real_cred check is not quite right, because the
cred can
be overridden by a same pointer as my print messages showing.
"cred != real_cred" means override_creds() is called, but "cred ==
real_cred"
doesn't mean override_creds() is not called.
When we use "cred != real_cred" check, we may lost the situation that cred
is overridden by a same pointer. In this case, we will do
override_creds() =>
commit_creds() => revert_creds(), this make cred != real_cred, when a new
commit_creds() is called, it also will trigger a BUG_ON().
>
>> --- a/kernel/acct.c
>> +++ b/kernel/acct.c
>> @@ -481,6 +481,7 @@ static void do_acct_process(struct bsd_acct_struct
>> *acct)
>> flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
>> current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
>> /* Perform file operations on behalf of whoever enabled
>> accounting */
>> + pr_info("task:%px new cred:%px real cred:%px cred:%px\n",
>> current, file->f_cred, current->real_cred, current->cred);
>> orig_cred = override_creds(file->f_cred);
^ permalink raw reply
* [PATCHv2] use event name instead of enum to make the call generic
From: Prakhar Srivastava @ 2019-04-20 0:00 UTC (permalink / raw)
To: linux-security-module, linux-kernel
Cc: zohar, Prakhar Srivastava, Prakhar Srivastava
In-Reply-To: <20190420000057.5222-1-prsriva02@gmail.com>
From: Prakhar Srivastava <prsriva02@gmail.com>
Signed-off-by: Prakhar Srivastava <prsriva@microsoft.com>
---
remove enaums to control type of buffers entries, instead pass the event name to be used.
include/linux/ima.h | 10 ++--------
kernel/kexec_file.c | 3 +++
security/integrity/ima/ima.h | 2 +-
security/integrity/ima/ima_main.c | 30 ++++++++++--------------------
4 files changed, 16 insertions(+), 29 deletions(-)
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 733d0cb9dedc..5e41507c57e5 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -14,12 +14,6 @@
#include <linux/kexec.h>
struct linux_binprm;
-enum __buffer_id {
- KERNEL_VERSION,
- KEXEC_CMDLINE,
- MAX_BUFFER_ID = KEXEC_CMDLINE
-} buffer_id;
-
#ifdef CONFIG_IMA
extern int ima_bprm_check(struct linux_binprm *bprm);
extern int ima_file_check(struct file *file, int mask, int opened);
@@ -29,7 +23,7 @@ extern int ima_read_file(struct file *file, enum kernel_read_file_id id);
extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
enum kernel_read_file_id id);
extern void ima_post_path_mknod(struct dentry *dentry);
-extern void ima_buffer_check(const void *buff, int size, enum buffer_id id);
+extern void ima_buffer_check(const void *buff, int size, char *eventname);
#ifdef CONFIG_IMA_KEXEC
extern void ima_add_kexec_buffer(struct kimage *image);
#endif
@@ -72,7 +66,7 @@ static inline void ima_post_path_mknod(struct dentry *dentry)
}
static inline void ima_buffer_check(const void *buff, int size,
- enum buffer_id id)
+ char *eventname)
{
return;
}
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index b118735fea9d..2a5234eb4b28 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -182,6 +182,9 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
ret = -EINVAL;
goto out;
}
+
+ ima_buffer_check(image->cmdline_buf, cmdline_len - 1,
+ "kexec_cmdline");
}
/* Call arch image load handlers */
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index b71f2f6f7421..fcade3c103ed 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -181,8 +181,8 @@ enum ima_hooks {
FIRMWARE_CHECK,
KEXEC_KERNEL_CHECK,
KEXEC_INITRAMFS_CHECK,
- BUFFER_CHECK,
POLICY_CHECK,
+ BUFFER_CHECK,
MAX_CHECK
};
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 6408cadaadbb..da82c705a5ed 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -160,8 +160,7 @@ void ima_file_free(struct file *file)
* (Instead of using the file hash the buffer hash is used).
* @buff - The buffer that needs to be added to the log
* @size - size of buffer(in bytes)
- * @id - buffer id, this is differentiator for the various buffers
- * that can be measured.
+ * @id - eventname, event name to be used for buffer measurement.
*
* The buffer passed is added to the ima logs.
* If the sig template is used, then the sig field contains the buffer.
@@ -170,7 +169,7 @@ void ima_file_free(struct file *file)
* On error cases surface errors from ima calls.
*/
static int process_buffer_measurement(const void *buff, int size,
- enum buffer_id id)
+ char *eventname)
{
int ret = -EINVAL;
struct ima_template_entry *entry = NULL;
@@ -185,23 +184,13 @@ static int process_buffer_measurement(const void *buff, int size,
int violation = 0;
int pcr = CONFIG_IMA_MEASURE_PCR_IDX;
- if (!buff || size == 0)
+ if (!buff || size == 0 || !eventname)
goto err_out;
if (ima_get_action(NULL, 0, BUFFER_CHECK, &pcr) != IMA_MEASURE)
goto err_out;
- switch (buffer_id) {
- case KERNEL_VERSION:
- name = "Kernel-version";
- break;
- case KEXEC_CMDLINE:
- name = "Kexec-cmdline";
- break;
- default:
- goto err_out;
- }
-
+ name = eventname;
memset(iint, 0, sizeof(*iint));
memset(&hash, 0, sizeof(hash));
@@ -452,15 +441,16 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
* ima_buffer_check - based on policy, collect & store buffer measurement
* @buf: pointer to buffer
* @size: size of buffer
- * @buffer_id: caller identifier
+ * @eventname: caller identifier
*
* Buffers can only be measured, not appraised. The buffer identifier
- * is used as the measurement list entry name (eg. boot_cmdline).
+ * is used as the measurement list entry name (eg. boot_cmdline,
+ * kernel_version).
*/
-void ima_buffer_check(const void *buf, int size, enum buffer_id id)
+void ima_buffer_check(const void *buf, int size, char *eventname)
{
- if (buf && size != 0)
- process_buffer_measurement(buf, size, id);
+ if (buf && size != 0 && eventname)
+ process_buffer_measurement(buf, size, eventname);
return;
}
--
2.17.1
^ permalink raw reply related
* [PATCHv2] since cmdline args can be same for multiple kexec, log entry hash will collide. Prepend the kernel file name to the cmdline args to distinguish between cmdline args passed to subsequent kexec calls
From: Prakhar Srivastava @ 2019-04-20 0:00 UTC (permalink / raw)
To: linux-security-module, linux-kernel
Cc: zohar, Prakhar Srivastava, Prakhar Srivastava
In-Reply-To: <20190420000057.5222-1-prsriva02@gmail.com>
From: Prakhar Srivastava <prsriva02@gmail.com>
Signed-off-by: Prakhar Srivastava <prsriva@microsoft.com>
---
since cmdline args can be same for multiple kexec, log entry
hash will collide. Prepend the kernel file name to the cmdline args to
distinguish between cmdline args passed to subsequent kexec calls
kernel/kexec_core.c | 57 +++++++++++++++++++++++++++++++++++++++++
kernel/kexec_file.c | 14 ++++++++--
kernel/kexec_internal.h | 3 +++
3 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index ae1a3ba24df5..97b77c780311 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -1151,3 +1151,60 @@ void __weak arch_kexec_protect_crashkres(void)
void __weak arch_kexec_unprotect_crashkres(void)
{}
+
+/**
+ * kexec_cmdline_prepend_img_name - prepare the buffer with cmdline
+ * that needs to be measured
+ * @outbuf - out buffer that contains the formated string
+ * @kernel_fd - the file identifier for the kerenel image
+ * @cmdline_ptr - ptr to the cmdline buffer
+ * @cmdline_len - len of the buffer.
+ *
+ * This generates a buffer in the format Kerenelfilename::cmdline
+ *
+ * On success return 0.
+ * On failure return -EINVAL.
+ */
+int kexec_cmdline_prepend_img_name(char **outbuf, int kernel_fd,
+ const char *cmdline_ptr,
+ unsigned long cmdline_len)
+{
+ int ret = -EINVAL;
+ struct fd f = {};
+ int size = 0;
+ char *buf = NULL;
+ char delimiter[] = "::";
+
+ if (!outbuf || !cmdline_ptr)
+ goto out;
+
+ f = fdget(kernel_fd);
+ if (!f.file)
+ goto out;
+
+ size = (f.file->f_path.dentry->d_name.len + cmdline_len - 1+
+ ARRAY_SIZE(delimiter)) - 1;
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (!buf)
+ goto out;
+
+ memcpy(buf, f.file->f_path.dentry->d_name.name,
+ f.file->f_path.dentry->d_name.len);
+ memcpy(buf + f.file->f_path.dentry->d_name.len,
+ delimiter, ARRAY_SIZE(delimiter) - 1);
+ memcpy(buf + f.file->f_path.dentry->d_name.len +
+ ARRAY_SIZE(delimiter) - 1,
+ cmdline_ptr, cmdline_len - 1);
+
+ *outbuf = buf;
+ ret = size;
+
+ pr_debug("kexec cmdline buff: %s\n", buf);
+
+out:
+ if (f.file)
+ fdput(f);
+
+ return ret;
+}
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 2a5234eb4b28..a487491d55b9 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -126,6 +126,8 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
int ret = 0;
void *ldata;
loff_t size;
+ char *buff_to_measure = NULL;
+ int buff_to_measure_size = 0;
ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
&size, INT_MAX, READING_KEXEC_IMAGE);
@@ -183,8 +185,13 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
goto out;
}
- ima_buffer_check(image->cmdline_buf, cmdline_len - 1,
- "kexec_cmdline");
+ /* IMA measures the cmdline args passed to the next kernel*/
+ buff_to_measure_size = kexec_cmdline_prepend_img_name(&buff_to_measure,
+ kernel_fd, image->cmdline_buf, image->cmdline_buf_len);
+
+ ima_buffer_check(buff_to_measure, buff_to_measure_size,
+ "kexec_cmdline");
+
}
/* Call arch image load handlers */
@@ -200,6 +207,9 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
/* In case of error, free up all allocated memory in this function */
if (ret)
kimage_file_post_load_cleanup(image);
+
+ kfree(buff_to_measure);
+
return ret;
}
diff --git a/kernel/kexec_internal.h b/kernel/kexec_internal.h
index 799a8a452187..4d34a8ef4637 100644
--- a/kernel/kexec_internal.h
+++ b/kernel/kexec_internal.h
@@ -11,6 +11,9 @@ int kimage_load_segment(struct kimage *image, struct kexec_segment *segment);
void kimage_terminate(struct kimage *image);
int kimage_is_destination_range(struct kimage *image,
unsigned long start, unsigned long end);
+int kexec_cmdline_prepend_img_name(char **outbuf, int kernel_fd,
+ const char *cmdline_ptr,
+ unsigned long cmdline_len);
extern struct mutex kexec_mutex;
--
2.17.1
^ permalink raw reply related
* [PATCHv2] added ima hook for buffer, being enabled as a policy
From: Prakhar Srivastava @ 2019-04-20 0:00 UTC (permalink / raw)
To: linux-security-module, linux-kernel
Cc: zohar, Prakhar Srivastava, Prakhar Srivastava
From: Prakhar Srivastava <prsriva02@gmail.com>
Signed-off-by: Prakhar Srivastava <prsriva@microsoft.com>
---
This adds a new ima hook ima_buffer_check and a policy entry BUFFER_CHECK.
This enables buffer has measurements into ima log
Documentation/ABI/testing/ima_policy | 1 +
include/linux/ima.h | 13 +++-
security/integrity/ima/ima.h | 1 +
security/integrity/ima/ima_main.c | 95 ++++++++++++++++++++++++++++
security/integrity/ima/ima_policy.c | 14 +++-
5 files changed, 122 insertions(+), 2 deletions(-)
diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index bb0f9a135e21..676088c7ab26 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -28,6 +28,7 @@ Description:
base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
[FIRMWARE_CHECK]
[KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
+ [BUFFER_CHECK]
mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
[[^]MAY_EXEC]
fsmagic:= hex value
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 7f6952f8d6aa..733d0cb9dedc 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -14,6 +14,12 @@
#include <linux/kexec.h>
struct linux_binprm;
+enum __buffer_id {
+ KERNEL_VERSION,
+ KEXEC_CMDLINE,
+ MAX_BUFFER_ID = KEXEC_CMDLINE
+} buffer_id;
+
#ifdef CONFIG_IMA
extern int ima_bprm_check(struct linux_binprm *bprm);
extern int ima_file_check(struct file *file, int mask, int opened);
@@ -23,7 +29,7 @@ extern int ima_read_file(struct file *file, enum kernel_read_file_id id);
extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
enum kernel_read_file_id id);
extern void ima_post_path_mknod(struct dentry *dentry);
-
+extern void ima_buffer_check(const void *buff, int size, enum buffer_id id);
#ifdef CONFIG_IMA_KEXEC
extern void ima_add_kexec_buffer(struct kimage *image);
#endif
@@ -65,6 +71,11 @@ static inline void ima_post_path_mknod(struct dentry *dentry)
return;
}
+static inline void ima_buffer_check(const void *buff, int size,
+ enum buffer_id id)
+{
+ return;
+}
#endif /* CONFIG_IMA */
#ifndef CONFIG_IMA_KEXEC
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index b563fbd4d122..b71f2f6f7421 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -181,6 +181,7 @@ enum ima_hooks {
FIRMWARE_CHECK,
KEXEC_KERNEL_CHECK,
KEXEC_INITRAMFS_CHECK,
+ BUFFER_CHECK,
POLICY_CHECK,
MAX_CHECK
};
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 2aebb7984437..6408cadaadbb 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -155,6 +155,84 @@ void ima_file_free(struct file *file)
ima_check_last_writer(iint, inode, file);
}
+/*
+ * process_buffer_measurement - Measure the buffer passed to ima log.
+ * (Instead of using the file hash the buffer hash is used).
+ * @buff - The buffer that needs to be added to the log
+ * @size - size of buffer(in bytes)
+ * @id - buffer id, this is differentiator for the various buffers
+ * that can be measured.
+ *
+ * The buffer passed is added to the ima logs.
+ * If the sig template is used, then the sig field contains the buffer.
+ *
+ * On success return 0.
+ * On error cases surface errors from ima calls.
+ */
+static int process_buffer_measurement(const void *buff, int size,
+ enum buffer_id id)
+{
+ int ret = -EINVAL;
+ struct ima_template_entry *entry = NULL;
+ struct integrity_iint_cache tmp_iint, *iint = &tmp_iint;
+ struct ima_event_data event_data = {iint, NULL, NULL,
+ NULL, 0, NULL};
+ struct {
+ struct ima_digest_data hdr;
+ char digest[IMA_MAX_DIGEST_SIZE];
+ } hash;
+ char *name = NULL;
+ int violation = 0;
+ int pcr = CONFIG_IMA_MEASURE_PCR_IDX;
+
+ if (!buff || size == 0)
+ goto err_out;
+
+ if (ima_get_action(NULL, 0, BUFFER_CHECK, &pcr) != IMA_MEASURE)
+ goto err_out;
+
+ switch (buffer_id) {
+ case KERNEL_VERSION:
+ name = "Kernel-version";
+ break;
+ case KEXEC_CMDLINE:
+ name = "Kexec-cmdline";
+ break;
+ default:
+ goto err_out;
+ }
+
+ memset(iint, 0, sizeof(*iint));
+ memset(&hash, 0, sizeof(hash));
+
+ event_data.filename = name;
+
+ iint->ima_hash = &hash.hdr;
+ iint->ima_hash->algo = ima_hash_algo;
+ iint->ima_hash->length = hash_digest_size[ima_hash_algo];
+
+ ret = ima_calc_buffer_hash(buff, size, iint->ima_hash);
+ if (ret < 0)
+ goto err_out;
+
+ ret = ima_alloc_init_template(&event_data, &entry);
+ if (ret < 0)
+ goto err_out;
+
+ ret = ima_store_template(entry, violation, NULL,
+ buff, pcr);
+ if (ret < 0) {
+ ima_free_template_entry(entry);
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ pr_err("Error in adding buffer measure: %d\n", ret);
+ return ret;
+}
+
static int process_measurement(struct file *file, char *buf, loff_t size,
int mask, enum ima_hooks func, int opened)
{
@@ -370,6 +448,23 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
return 0;
}
+/**
+ * ima_buffer_check - based on policy, collect & store buffer measurement
+ * @buf: pointer to buffer
+ * @size: size of buffer
+ * @buffer_id: caller identifier
+ *
+ * Buffers can only be measured, not appraised. The buffer identifier
+ * is used as the measurement list entry name (eg. boot_cmdline).
+ */
+void ima_buffer_check(const void *buf, int size, enum buffer_id id)
+{
+ if (buf && size != 0)
+ process_buffer_measurement(buf, size, id);
+
+ return;
+}
+
static int read_idmap[READING_MAX_ID] = {
[READING_FIRMWARE] = FIRMWARE_CHECK,
[READING_MODULE] = MODULE_CHECK,
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 3ab1067db624..cefe1a188f31 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -231,6 +231,12 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
const struct cred *cred = current_cred();
int i;
+ // Incase of BUFFER_CHECK, Inode is NULL
+ if (!inode) {
+ if ((rule->flags & IMA_FUNC) && (rule->func == func))
+ return true;
+ return false;
+ }
if ((rule->flags & IMA_FUNC) &&
(rule->func != func && func != POST_SETATTR))
return false;
@@ -665,6 +671,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
else if (strcmp(args[0].from, "KEXEC_INITRAMFS_CHECK")
== 0)
entry->func = KEXEC_INITRAMFS_CHECK;
+ else if (strcmp(args[0].from, "BUFFER_CHECK") == 0)
+ entry->func = BUFFER_CHECK;
else if (strcmp(args[0].from, "POLICY_CHECK") == 0)
entry->func = POLICY_CHECK;
else
@@ -944,7 +952,7 @@ enum {
func_file = 0, func_mmap, func_bprm,
func_module, func_firmware, func_post,
func_kexec_kernel, func_kexec_initramfs,
- func_policy
+ func_buffer, func_policy
};
static char *func_tokens[] = {
@@ -956,6 +964,7 @@ static char *func_tokens[] = {
"POST_SETATTR",
"KEXEC_KERNEL_CHECK",
"KEXEC_INITRAMFS_CHECK",
+ "BUFFER_CHECK",
"POLICY_CHECK"
};
@@ -1027,6 +1036,9 @@ static void policy_func_show(struct seq_file *m, enum ima_hooks func)
case KEXEC_INITRAMFS_CHECK:
seq_printf(m, pt(Opt_func), ft(func_kexec_initramfs));
break;
+ case BUFFER_CHECK:
+ seq_printf(m, pt(Opt_func), ft(func_buffer));
+ break;
case POLICY_CHECK:
seq_printf(m, pt(Opt_func), ft(func_policy));
break;
--
2.17.1
^ permalink raw reply related
* Re: [PATCH] proc: prevent changes to overridden credentials
From: John Johansen @ 2019-04-19 19:03 UTC (permalink / raw)
To: Paul Moore, linux-security-module; +Cc: selinux, cj.chengjian, casey
In-Reply-To: <155570011247.27135.12509150054846153288.stgit@chester>
On 4/19/19 11:55 AM, Paul Moore wrote:
> Prevent userspace from changing the the /proc/PID/attr values if the
> task's credentials are currently overriden. This not only makes sense
> conceptually, it also prevents some really bizarre error cases caused
> when trying to commit credentials to a task with overridden
> credentials.
>
> Cc: <stable@vger.kernel.org>
> Reported-by: "chengjian (D)" <cj.chengjian@huawei.com>
> Signed-off-by: Paul Moore <paul@paul-moore.com>
looks good
Acked-by: John Johansen <john.johansen@canonical.com>
> ---
> fs/proc/base.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index ddef482f1334..87ba007b86db 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -2539,6 +2539,11 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
> rcu_read_unlock();
> return -EACCES;
> }
> + /* Prevent changes to overridden credentials. */
> + if (current_cred() != current_real_cred()) {
> + rcu_read_unlock();
> + return -EBUSY;
> + }
> rcu_read_unlock();
>
> if (count > PAGE_SIZE)
>
^ permalink raw reply
* Re: Avoiding merge conflicts while adding new docs - Was: Re: [PATCH 00/57] Convert files to ReST
From: Jonathan Corbet @ 2019-04-19 22:10 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: Linux Doc Mailing List, Mauro Carvalho Chehab, linux-kernel,
linux-riscv, linux-fbdev, linux-s390, Greg Kroah-Hartman,
linux-watchdog, xdp-newbies, linux-samsung-soc, linux-acpi,
linux-stm32, bpf, linux-ide, linux-pm, dri-devel, linux-scsi,
linux-gpio, linuxppc-dev, x86, dm-devel, target-devel, netdev,
kexec, linux-fpga, linux-rdma, linux-kbuild, Thomas Gleixner,
linux-security-module, linux-usb, linux-arm-kernel
In-Reply-To: <20190418091526.00e074d1@coco.lan>
On Thu, 18 Apr 2019 09:42:23 -0300
Mauro Carvalho Chehab <mchehab+samsung@kernel.org> wrote:
> After thinking a little bit and doing some tests, I think a good solution
> would be to add ":orphan:" markup to the new .rst files that were not
> added yet into the main body (e. g. something like the enclosed example).
Interesting...I didn't know about that. Yes, I think it makes sense to
put that in...
jon
^ permalink raw reply
* Re: [PATCH] proc: prevent changes to overridden credentials
From: James Morris @ 2019-04-19 20:26 UTC (permalink / raw)
To: Paul Moore
Cc: linux-security-module, selinux, cj.chengjian, john.johansen,
casey
In-Reply-To: <CAHC9VhQKE3Rnbz8qxm0UKNB=GT6xPu-Le=ZZM0_XisOS+v3jKg@mail.gmail.com>
On Fri, 19 Apr 2019, Paul Moore wrote:
> On Fri, Apr 19, 2019 at 2:55 PM Paul Moore <paul@paul-moore.com> wrote:
> > Prevent userspace from changing the the /proc/PID/attr values if the
> > task's credentials are currently overriden. This not only makes sense
> > conceptually, it also prevents some really bizarre error cases caused
> > when trying to commit credentials to a task with overridden
> > credentials.
> >
> > Cc: <stable@vger.kernel.org>
> > Reported-by: "chengjian (D)" <cj.chengjian@huawei.com>
> > Signed-off-by: Paul Moore <paul@paul-moore.com>
> > ---
> > fs/proc/base.c | 5 +++++
> > 1 file changed, 5 insertions(+)
>
> I sent this to the LSM list as I figure it should probably go via
> James' linux-security tree since it is cross-LSM and doesn't really
> contain any LSM specific code. That said, if you don't want this
> James let me know and I'll send it via the SELinux tree assuming I can
> get ACKs from John and Casey (this should only affect SELinux,
> AppArmor, and Smack).
This is fine to go via your tree.
Acked-by: James Morris <james.morris@microsoft.com>
--
James Morris
<jmorris@namei.org>
^ permalink raw reply
* Re: [PATCH v2 1/3] security: Create "kernel hardening" config area
From: Alexander Popov @ 2019-04-19 19:15 UTC (permalink / raw)
To: Kees Cook, Masahiro Yamada
Cc: Alexander Potapenko, James Morris, Nick Desaulniers,
Kostya Serebryany, Dmitry Vyukov, Sandeep Patil, Laura Abbott,
Randy Dunlap, Michal Marek, Emese Revfy, Serge E. Hallyn,
Kernel Hardening, linux-security-module, linux-kbuild, LKML
In-Reply-To: <CAGXu5j+bVtkXHhs03t_yb1gp51WRhzZGqNpzV5VPb6dfnptw5w@mail.gmail.com>
On 16.04.2019 16:56, Kees Cook wrote:
> On Tue, Apr 16, 2019 at 8:55 AM Alexander Popov <alex.popov@linux.com> wrote:
>>
>> On 16.04.2019 7:02, Kees Cook wrote:
>>> On Mon, Apr 15, 2019 at 11:44 AM Alexander Popov <alex.popov@linux.com> wrote:
>>>>
>>>> What do you think about some separator between memory initialization options and
>>>> CONFIG_CRYPTO?
>>>
>>> This was true before too
>>
>> Hm, yes, it's a generic behavior - there is no any separator at 'endmenu' and
>> config options stick together.
>>
>> I've created a patch to fix that. What do you think about it?
>> I can send it to LKML separately.
>>
>>
>> From 50bf59d30fafcdebb3393fb742e1bd51e7d2f2da Mon Sep 17 00:00:00 2001
>> From: Alexander Popov <alex.popov@linux.com>
>> Date: Tue, 16 Apr 2019 16:09:40 +0300
>> Subject: [PATCH 1/1] kconfig: Terminate menu blocks with a newline in the
>> generated config
>>
>> Currently menu blocks start with a pretty header but end with nothing in
>> the generated config. So next config options stick together with the
>> options from the menu block.
>>
>> Let's terminate menu blocks with a newline in the generated config.
>>
>> Signed-off-by: Alexander Popov <alex.popov@linux.com>
>> ---
>> scripts/kconfig/confdata.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
>> index 08ba146..1459153 100644
>> --- a/scripts/kconfig/confdata.c
>> +++ b/scripts/kconfig/confdata.c
>> @@ -888,6 +888,8 @@ int conf_write(const char *name)
>> if (menu->next)
>> menu = menu->next;
>> else while ((menu = menu->parent)) {
>> + if (!menu->sym && menu_is_visible(menu))
>> + fprintf(out, "\n");
>> if (menu->next) {
>> menu = menu->next;
>> break;
>
> Seems fine to me. I defer to Masahiro, though. :)
Hi! I've sent this patch separately to LKML:
https://lore.kernel.org/lkml/1555669773-9766-1-git-send-email-alex.popov@linux.com/T/#u
Best regards,
Alexander
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox