2019-07-06 11:02:28

by Salvatore Mesoraca

[permalink] [raw]
Subject: [PATCH v5 00/12] S.A.R.A. a new stacked LSM

S.A.R.A. (S.A.R.A. is Another Recursive Acronym) is a stacked Linux
Security Module that aims to collect heterogeneous security measures,
providing a common interface to manage them.
It can be useful to allow minor security features to use advanced
management options, like user-space configuration files and tools, without
too much overhead.
Some submodules that use this framework are also introduced.
The code is quite long, I apologize for this. Thank you in advance to
anyone who will take the time to review this patchset.

S.A.R.A. is meant to be stacked but it needs cred blobs and the procattr
interface, so I temporarily implemented those parts in a way that won't
be acceptable for upstream, but it works for now. I know that there
is some ongoing work to make cred blobs and procattr stackable, as soon
as the new interfaces will be available I'll reimplement the involved
parts.
At the moment I've been able to test it only on x86.

The only submodule introduced in this patchset is WX Protection.

The kernel-space part is complemented by its user-space counterpart:
saractl [1].
A test suite for WX Protection, called sara-test [2], is also available.

WX Protection aims to improve user-space programs security by applying:
- W^X enforcement: program can't have a page of memory that is marked, at
the same time, writable and executable.
- W!->X restriction: any page that could have been marked as writable in
the past won't ever be allowed to be marked as
executable.
- Executable MMAP prevention: prevents the creation of new executable mmaps
after the dynamic libraries have been loaded.
All of the above features can be enabled or disabled both system wide
or on a per executable basis through the use of configuration files managed
by "saractl".
It is important to note that some programs may have issues working with
WX Protection. In particular:
- W^X enforcement will cause problems to any programs that needs
memory pages mapped both as writable and executable at the same time e.g.
programs with executable stack markings in the PT_GNU_STACK segment.
- W!->X restriction will cause problems to any program that
needs to generate executable code at run time or to modify executable
pages e.g. programs with a JIT compiler built-in or linked against a
non-PIC library.
- Executable MMAP prevention can work only with programs that have at least
partial RELRO support. It's disabled automatically for programs that
lack this feature. It will cause problems to any program that uses dlopen
or tries to do an executable mmap. Unfortunately this feature is the one
that could create most problems and should be enabled only after careful
evaluation.
To extend the scope of the above features, despite the issues that they may
cause, they are complemented by:
- procattr interface: can be used by a program to discover which WX
Protection features are enabled and/or to tighten
them.
- Trampoline emulation: emulates the execution of well-known "trampolines"
even when they are placed in non-executable memory.
Parts of WX Protection are inspired by some of the features available in
PaX.

Thanks to the addition of extended attributes support, it's now possible to
use S.A.R.A. without being forced to rely on any special userspace tool.

More information can be found in the documentation introduced in the first
patch and in the "commit message" of the following emails.

Changes in v2:
- Removed USB filtering submodule and relative hook
- s/saralib/libsara/ typo
- STR macro renamed to avoid conflicts
- check_vmflags hook now returns an error code instead of just 1
or 0. (suggested by Casey Schaufler)
- pr_wxp macro rewritten as function for readability
- Fixed i386 compilation warnings
- Documentation now states clearly that changes done via procattr
interface only apply to current thread. (suggested by Jann Horn)

Changes in v3:
- Documentation has been moved to match the new directory structure.
- Kernel cmdline arguments are now accessed via module_param interface
(suggested by Kees Cook).
- Created "sara_warn_or_return" macro to make WX Protection code more
readable (suggested by Kees Cook).
- Added more comments, in the most important places, to clarify my
intentions (suggested by Kees Cook).
- The "pagefault_handler" hook has been rewritten in a more "arch
agnostic" way. Though it only support x86 at the moment
(suggested by Kees Cook).

Changes in v4:
- Documentation improved and some mistakes have been fixed.
- Reduced dmesg verbosity.
- check_vmflags is now also used to decide whether to ignore
GNU executable stack markings or not.
- Added the check_vmflags hook in setup_arg_pages too.
- Added support for extended attributes.
- Moved trampoline emulation to arch/x86/ (suggested by Kees Cook).
- SARA_WXP_MMAP now depends on SARA_WXP_OTHER.
- MAC_ADMIN capability is now required also for config read.
- Some other minor fixes not worth mentionig here.

Changes in v5:
- Updated the code to use the new stacking interface.
- Path matching is now done using a DFA

Salvatore Mesoraca (12):
S.A.R.A.: add documentation
S.A.R.A.: create framework
S.A.R.A.: cred blob management
S.A.R.A.: generic DFA for string matching
LSM: creation of "check_vmflags" LSM hook
S.A.R.A.: WX protection
LSM: creation of "pagefault_handler" LSM hook
S.A.R.A.: trampoline emulation
S.A.R.A.: WX protection procattr interface
S.A.R.A.: XATTRs support
S.A.R.A.: /proc/*/mem write limitation
MAINTAINERS: take maintainership for S.A.R.A.

Documentation/admin-guide/LSM/SARA.rst | 197 +++++
Documentation/admin-guide/LSM/index.rst | 1 +
Documentation/admin-guide/kernel-parameters.txt | 40 +
MAINTAINERS | 9 +
arch/Kconfig | 6 +
arch/x86/Kbuild | 2 +
arch/x86/Kconfig | 1 +
arch/x86/mm/fault.c | 6 +
arch/x86/security/Makefile | 2 +
arch/x86/security/sara/Makefile | 1 +
arch/x86/security/sara/emutramp.c | 57 ++
arch/x86/security/sara/trampolines32.h | 137 ++++
arch/x86/security/sara/trampolines64.h | 164 ++++
fs/binfmt_elf.c | 3 +-
fs/binfmt_elf_fdpic.c | 3 +-
fs/exec.c | 4 +
fs/proc/base.c | 11 +
include/linux/lsm_hooks.h | 19 +
include/linux/security.h | 17 +
include/uapi/linux/xattr.h | 4 +
mm/mmap.c | 13 +
security/Kconfig | 11 +-
security/Makefile | 2 +
security/sara/Kconfig | 176 +++++
security/sara/Makefile | 5 +
security/sara/dfa.c | 335 ++++++++
security/sara/dfa_test.c | 135 ++++
security/sara/include/dfa.h | 52 ++
security/sara/include/dfa_test.h | 29 +
security/sara/include/emutramp.h | 35 +
security/sara/include/sara.h | 29 +
security/sara/include/sara_data.h | 100 +++
security/sara/include/securityfs.h | 61 ++
security/sara/include/utils.h | 80 ++
security/sara/include/wxprot.h | 29 +
security/sara/main.c | 134 ++++
security/sara/sara_data.c | 77 ++
security/sara/securityfs.c | 565 ++++++++++++++
security/sara/utils.c | 92 +++
security/sara/wxprot.c | 998 ++++++++++++++++++++++++
security/security.c | 16 +
41 files changed, 3651 insertions(+), 7 deletions(-)
create mode 100644 Documentation/admin-guide/LSM/SARA.rst
create mode 100644 arch/x86/security/Makefile
create mode 100644 arch/x86/security/sara/Makefile
create mode 100644 arch/x86/security/sara/emutramp.c
create mode 100644 arch/x86/security/sara/trampolines32.h
create mode 100644 arch/x86/security/sara/trampolines64.h
create mode 100644 security/sara/Kconfig
create mode 100644 security/sara/Makefile
create mode 100644 security/sara/dfa.c
create mode 100644 security/sara/dfa_test.c
create mode 100644 security/sara/include/dfa.h
create mode 100644 security/sara/include/dfa_test.h
create mode 100644 security/sara/include/emutramp.h
create mode 100644 security/sara/include/sara.h
create mode 100644 security/sara/include/sara_data.h
create mode 100644 security/sara/include/securityfs.h
create mode 100644 security/sara/include/utils.h
create mode 100644 security/sara/include/wxprot.h
create mode 100644 security/sara/main.c
create mode 100644 security/sara/sara_data.c
create mode 100644 security/sara/securityfs.c
create mode 100644 security/sara/utils.c
create mode 100644 security/sara/wxprot.c

--
1.9.1


2019-07-06 11:02:36

by Salvatore Mesoraca

[permalink] [raw]
Subject: [PATCH v5 12/12] MAINTAINERS: take maintainership for S.A.R.A.

Signed-off-by: Salvatore Mesoraca <[email protected]>
---
MAINTAINERS | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f16e5d0..de6dab1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13925,6 +13925,15 @@ F: drivers/phy/samsung/phy-s5pv210-usb2.c
F: drivers/phy/samsung/phy-samsung-usb2.c
F: drivers/phy/samsung/phy-samsung-usb2.h

+SARA SECURITY MODULE
+M: Salvatore Mesoraca <[email protected]>
+T: git git://github.com/smeso/sara.git lsm/sara/master
+W: https://sara.smeso.it
+S: Maintained
+F: security/sara/
+F: arch/x86/security/sara/
+F: Documentation/admin-guide/LSM/SARA.rst
+
SC1200 WDT DRIVER
M: Zwane Mwaikambo <[email protected]>
S: Maintained
--
1.9.1

2019-07-06 11:02:52

by Salvatore Mesoraca

[permalink] [raw]
Subject: [PATCH v5 07/12] LSM: creation of "pagefault_handler" LSM hook

Creation of a new hook to let LSM modules handle user-space pagefaults on
x86.
It can be used to avoid segfaulting the originating process.
If it's the case it can modify process registers before returning.
This is not a security feature by itself, it's a way to soften some
unwanted side-effects of restrictive security features.
In particular this is used by S.A.R.A. to implement what PaX call
"trampoline emulation" that, in practice, allows for some specific
code sequences to be executed even if they are in non executable memory.
This may look like a bad thing at first, but you have to consider
that:
- This allows for strict memory restrictions (e.g. W^X) to stay on even
when they should be turned off. And, even if this emulation
makes those features less effective, it's still better than having
them turned off completely.
- The only code sequences emulated are trampolines used to make
function calls. In many cases, when you have the chance to
make arbitrary memory writes, you can already manipulate the
control flow of the program by overwriting function pointers or
return values. So, in many cases, "trampoline emulation"
doesn't introduce new exploit vectors.
- It's a feature that can be turned on only if needed, on a per
executable file basis.

Signed-off-by: Salvatore Mesoraca <[email protected]>
---
arch/Kconfig | 6 ++++++
arch/x86/Kconfig | 1 +
arch/x86/mm/fault.c | 6 ++++++
include/linux/lsm_hooks.h | 12 ++++++++++++
include/linux/security.h | 11 +++++++++++
security/security.c | 11 +++++++++++
6 files changed, 47 insertions(+)

diff --git a/arch/Kconfig b/arch/Kconfig
index c47b328..16997c3 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -252,6 +252,12 @@ config ARCH_HAS_FORTIFY_SOURCE
config ARCH_HAS_KEEPINITRD
bool

+config ARCH_HAS_LSM_PAGEFAULT
+ bool
+ help
+ An architecture should select this if it supports
+ "pagefault_handler" LSM hook.
+
# Select if arch has all set_memory_ro/rw/x/nx() functions in asm/cacheflush.h
config ARCH_HAS_SET_MEMORY
bool
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2bbbd4d..a3c7660 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -67,6 +67,7 @@ config X86
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_KCOV if X86_64
+ select ARCH_HAS_LSM_PAGEFAULT
select ARCH_HAS_MEMBARRIER_SYNC_CORE
select ARCH_HAS_PMEM_API if X86_64
select ARCH_HAS_PTE_SPECIAL
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 46df4c6..7fe36f1 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -18,6 +18,7 @@
#include <linux/uaccess.h> /* faulthandler_disabled() */
#include <linux/efi.h> /* efi_recover_from_page_fault()*/
#include <linux/mm_types.h>
+#include <linux/security.h> /* security_pagefault_handler */

#include <asm/cpufeature.h> /* boot_cpu_has, ... */
#include <asm/traps.h> /* dotraplinkage, ... */
@@ -1360,6 +1361,11 @@ void do_user_addr_fault(struct pt_regs *regs,
local_irq_enable();
}

+ if (unlikely(security_pagefault_handler(regs,
+ hw_error_code,
+ address)))
+ return;
+
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);

if (hw_error_code & X86_PF_WRITE)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 12ce609..478a187 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -518,6 +518,14 @@
* @vmflags contains the requested vmflags.
* Return 0 if the operation is allowed to continue otherwise return
* the appropriate error code.
+ * @pagefault_handler:
+ * Handle pagefaults on supported architectures, that is any architecture
+ * which defines CONFIG_ARCH_HAS_LSM_PAGEFAULT.
+ * @regs contains process' registers.
+ * @error_code contains error code for the pagefault.
+ * @address contains the address that caused the pagefault.
+ * Return 0 to let the kernel handle the pagefault as usually, any other
+ * value to let the process continue its execution.
* @file_lock:
* Check permission before performing file locking operations.
* Note the hook mediates both flock and fcntl style locks.
@@ -1603,6 +1611,9 @@
int (*file_mprotect)(struct vm_area_struct *vma, unsigned long reqprot,
unsigned long prot);
int (*check_vmflags)(vm_flags_t vmflags);
+ int (*pagefault_handler)(struct pt_regs *regs,
+ unsigned long error_code,
+ unsigned long address);
int (*file_lock)(struct file *file, unsigned int cmd);
int (*file_fcntl)(struct file *file, unsigned int cmd,
unsigned long arg);
@@ -1904,6 +1915,7 @@ struct security_hook_heads {
struct hlist_head mmap_file;
struct hlist_head file_mprotect;
struct hlist_head check_vmflags;
+ struct hlist_head pagefault_handler;
struct hlist_head file_lock;
struct hlist_head file_fcntl;
struct hlist_head file_set_fowner;
diff --git a/include/linux/security.h b/include/linux/security.h
index aed78eb..c287eb2 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -313,6 +313,9 @@ int security_mmap_file(struct file *file, unsigned long prot,
int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
unsigned long prot);
int security_check_vmflags(vm_flags_t vmflags);
+int __maybe_unused security_pagefault_handler(struct pt_regs *regs,
+ unsigned long error_code,
+ unsigned long address);
int security_file_lock(struct file *file, unsigned int cmd);
int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg);
void security_file_set_fowner(struct file *file);
@@ -865,6 +868,14 @@ static inline int security_check_vmflags(vm_flags_t vmflags)
return 0;
}

+static inline int __maybe_unused security_pagefault_handler(
+ struct pt_regs *regs,
+ unsigned long error_code,
+ unsigned long address)
+{
+ return 0;
+}
+
static inline int security_file_lock(struct file *file, unsigned int cmd)
{
return 0;
diff --git a/security/security.c b/security/security.c
index 3308e89..a8bdcf3 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1426,6 +1426,17 @@ int security_check_vmflags(vm_flags_t vmflags)
return call_int_hook(check_vmflags, 0, vmflags);
}

+int __maybe_unused security_pagefault_handler(struct pt_regs *regs,
+ unsigned long error_code,
+ unsigned long address)
+{
+ return call_int_hook(pagefault_handler,
+ 0,
+ regs,
+ error_code,
+ address);
+}
+
int security_file_lock(struct file *file, unsigned int cmd)
{
return call_int_hook(file_lock, 0, file, cmd);
--
1.9.1

2019-07-06 14:34:06

by Jordan Glover

[permalink] [raw]
Subject: Re: [PATCH v5 00/12] S.A.R.A. a new stacked LSM

On Saturday, July 6, 2019 10:54 AM, Salvatore Mesoraca <[email protected]> wrote:

> S.A.R.A. is meant to be stacked but it needs cred blobs and the procattr
> interface, so I temporarily implemented those parts in a way that won't
> be acceptable for upstream, but it works for now. I know that there
> is some ongoing work to make cred blobs and procattr stackable, as soon
> as the new interfaces will be available I'll reimplement the involved
> parts.

I thought all stacking pieces for minor LSM were merged in Linux 5.1.
Is there still something missing or is this comment out-fo-date?

Jordan

2019-07-06 15:03:35

by Salvatore Mesoraca

[permalink] [raw]
Subject: Re: [PATCH v5 00/12] S.A.R.A. a new stacked LSM

You are right. I just forgot to remove that paragraph from the cover letter.
My bad.
Thank you for noticing that :)

Il giorno sab 6 lug 2019 alle ore 16:33 Jordan Glover
<[email protected]> ha scritto:
>
> On Saturday, July 6, 2019 10:54 AM, Salvatore Mesoraca <[email protected]> wrote:
>
> > S.A.R.A. is meant to be stacked but it needs cred blobs and the procattr
> > interface, so I temporarily implemented those parts in a way that won't
> > be acceptable for upstream, but it works for now. I know that there
> > is some ongoing work to make cred blobs and procattr stackable, as soon
> > as the new interfaces will be available I'll reimplement the involved
> > parts.
>
> I thought all stacking pieces for minor LSM were merged in Linux 5.1.
> Is there still something missing or is this comment out-fo-date?
>
> Jordan

2019-07-07 01:20:37

by James Morris

[permalink] [raw]
Subject: Re: [PATCH v5 00/12] S.A.R.A. a new stacked LSM

On Sat, 6 Jul 2019, Salvatore Mesoraca wrote:

> S.A.R.A. (S.A.R.A. is Another Recursive Acronym) is a stacked Linux

Please make this just SARA. Nobody wants to read or type S.A.R.A.



--
James Morris
<[email protected]>

2019-07-07 16:46:31

by Salvatore Mesoraca

[permalink] [raw]
Subject: Re: [PATCH v5 00/12] S.A.R.A. a new stacked LSM

James Morris <[email protected]> wrote:
>
> On Sat, 6 Jul 2019, Salvatore Mesoraca wrote:
>
> > S.A.R.A. (S.A.R.A. is Another Recursive Acronym) is a stacked Linux
>
> Please make this just SARA. Nobody wants to read or type S.A.R.A.

Agreed.
Thank you for your suggestion.