Re: [PATCH v3 0/5] Add support for RESOLVE_MAYEXEC

2020-05-05 Thread Mickaël Salaün


On 01/05/2020 13:47, Christian Heimes wrote:
> On 29/04/2020 00.01, Jann Horn wrote:
>> On Tue, Apr 28, 2020 at 11:21 PM Florian Weimer  wrote:
>>> * Jann Horn:
>>>
 Just as a comment: You'd probably also have to use RESOLVE_MAYEXEC in
 the dynamic linker.
>>>
>>> Absolutely.  In typical configurations, the kernel does not enforce
>>> that executable mappings must be backed by files which are executable.
>>> It's most obvious with using an explicit loader invocation to run
>>> executables on noexec mounts.  RESOLVE_MAYEXEC is much more useful
>>> than trying to reimplement the kernel permission checks (or what some
>>> believe they should be) in userspace.
>>
>> Oh, good point.
>>
>> That actually seems like something Mickaël could add to his series? If
>> someone turns on that knob for "When an interpreter wants to execute
>> something, enforce that we have execute access to it", they probably
>> also don't want it to be possible to just map files as executable? So
>> perhaps when that flag is on, the kernel should either refuse to map
>> anything as executable if it wasn't opened with RESOLVE_MAYEXEC or
>> (less strict) if RESOLVE_MAYEXEC wasn't used, print a warning, then
>> check whether the file is executable and bail out if not?
>>
>> A configuration where interpreters verify that scripts are executable,
>> but other things can just mmap executable pages, seems kinda
>> inconsistent...
> 
> +1
> 
> I worked with Steve Downer on Python PEP 578 [1] that added audit hooks
> and PyFile_OpenCode() to CPython. A PyFile_OpenCode() implementation
> with RESOLVE_MAYEXEC will hep to secure loading of Python code. But
> Python also includes a wrapper of libffi. ctypes or cffi can load native
> code from either shared libraries with dlopen() or execute native code
> from mmap() regions. For example SnakeEater [2] is a clever attack that
> abused memfd_create syscall and proc filesystem to execute code.
> 
> A consistent security policy must also ensure that mmap() PROT_EXEC
> enforces the same restrictions as RESOLVE_MAYEXEC. The restriction
> doesn't have be part of this patch, though.
> 
> Christian
> 
> [1] https://www.python.org/dev/peps/pep-0578/
> [2] https://github.com/nullbites/SnakeEater/blob/master/SnakeEater2.py

To be consistent, a "noexec" policy must indeed also restricts features
such as mprotect(2) and mmap(2) which may enable to set arbitrary memory
as executable. This can be restricted with SELinux (i.e. execmem,
execmod,execheap and execstack permissions), PaX MPROTECT [1] or SARA [2].

[1] https://pax.grsecurity.net/docs/mprotect.txt
[2]
https://lore.kernel.org/lkml/1562410493-8661-1-git-send-email-s.mesorac...@gmail.com/


Re: [PATCH v3 0/5] Add support for RESOLVE_MAYEXEC

2020-05-01 Thread Christian Heimes
On 29/04/2020 00.01, Jann Horn wrote:
> On Tue, Apr 28, 2020 at 11:21 PM Florian Weimer  wrote:
>> * Jann Horn:
>>
>>> Just as a comment: You'd probably also have to use RESOLVE_MAYEXEC in
>>> the dynamic linker.
>>
>> Absolutely.  In typical configurations, the kernel does not enforce
>> that executable mappings must be backed by files which are executable.
>> It's most obvious with using an explicit loader invocation to run
>> executables on noexec mounts.  RESOLVE_MAYEXEC is much more useful
>> than trying to reimplement the kernel permission checks (or what some
>> believe they should be) in userspace.
> 
> Oh, good point.
> 
> That actually seems like something Mickaël could add to his series? If
> someone turns on that knob for "When an interpreter wants to execute
> something, enforce that we have execute access to it", they probably
> also don't want it to be possible to just map files as executable? So
> perhaps when that flag is on, the kernel should either refuse to map
> anything as executable if it wasn't opened with RESOLVE_MAYEXEC or
> (less strict) if RESOLVE_MAYEXEC wasn't used, print a warning, then
> check whether the file is executable and bail out if not?
> 
> A configuration where interpreters verify that scripts are executable,
> but other things can just mmap executable pages, seems kinda
> inconsistent...

+1

I worked with Steve Downer on Python PEP 578 [1] that added audit hooks
and PyFile_OpenCode() to CPython. A PyFile_OpenCode() implementation
with RESOLVE_MAYEXEC will hep to secure loading of Python code. But
Python also includes a wrapper of libffi. ctypes or cffi can load native
code from either shared libraries with dlopen() or execute native code
from mmap() regions. For example SnakeEater [2] is a clever attack that
abused memfd_create syscall and proc filesystem to execute code.

A consistent security policy must also ensure that mmap() PROT_EXEC
enforces the same restrictions as RESOLVE_MAYEXEC. The restriction
doesn't have be part of this patch, though.

Christian

[1] https://www.python.org/dev/peps/pep-0578/
[2] https://github.com/nullbites/SnakeEater/blob/master/SnakeEater2.py


Re: [PATCH v3 0/5] Add support for RESOLVE_MAYEXEC

2020-04-30 Thread James Morris
On Tue, 28 Apr 2020, Mickaël Salaün wrote:

> Furthermore, the security policy can also be delegated to an LSM, either
> a MAC system or an integrity system.  For instance, the new kernel
> MAY_OPENEXEC flag closes a major IMA measurement/appraisal interpreter
> integrity gap by bringing the ability to check the use of scripts [1].
> Other uses are expected, such as for openat2(2) [2], SGX integration
> [3], bpffs [4] or IPE [5].

Confirming that this is a highly desirable feature for the proposed IPE 
LSM.

-- 
James Morris



Re: [PATCH v3 0/5] Add support for RESOLVE_MAYEXEC

2020-04-30 Thread Mickaël Salaün


On 30/04/2020 10:07, Christian Brauner wrote:
> On Thu, Apr 30, 2020 at 11:54:29AM +1000, Aleksa Sarai wrote:
>> On 2020-04-28, Mickaël Salaün  wrote:
>>> The goal of this patch series is to enable to control script execution
>>> with interpreters help.  A new RESOLVE_MAYEXEC flag, usable through
>>> openat2(2), is added to enable userspace script interpreter to delegate
>>> to the kernel (and thus the system security policy) the permission to
>>> interpret/execute scripts or other files containing what can be seen as
>>> commands.
>>>
>>> This third patch series mainly differ from the previous one by relying
>>> on the new openat2(2) system call to get rid of the undefined behavior
>>> of the open(2) flags.  Thus, the previous O_MAYEXEC flag is now replaced
>>> with the new RESOLVE_MAYEXEC flag and benefits from the openat2(2)
>>> strict check of this kind of flags.
>>
>> My only strong upfront objection is with this being a RESOLVE_ flag.
>>
>> RESOLVE_ flags have a specific meaning (they generally apply to all
>> components, and affect the rules of path resolution). RESOLVE_MAYEXEC
>> does neither of these things and so seems out of place among the other
>> RESOLVE_ flags.
>>
>> I would argue this should be an O_ flag, but not supported for the
> 
> I agree.

OK, I'll switch back to O_MAYEXEC.


Re: [PATCH v3 0/5] Add support for RESOLVE_MAYEXEC

2020-04-30 Thread Christian Brauner
On Thu, Apr 30, 2020 at 11:54:29AM +1000, Aleksa Sarai wrote:
> On 2020-04-28, Mickaël Salaün  wrote:
> > The goal of this patch series is to enable to control script execution
> > with interpreters help.  A new RESOLVE_MAYEXEC flag, usable through
> > openat2(2), is added to enable userspace script interpreter to delegate
> > to the kernel (and thus the system security policy) the permission to
> > interpret/execute scripts or other files containing what can be seen as
> > commands.
> > 
> > This third patch series mainly differ from the previous one by relying
> > on the new openat2(2) system call to get rid of the undefined behavior
> > of the open(2) flags.  Thus, the previous O_MAYEXEC flag is now replaced
> > with the new RESOLVE_MAYEXEC flag and benefits from the openat2(2)
> > strict check of this kind of flags.
> 
> My only strong upfront objection is with this being a RESOLVE_ flag.
> 
> RESOLVE_ flags have a specific meaning (they generally apply to all
> components, and affect the rules of path resolution). RESOLVE_MAYEXEC
> does neither of these things and so seems out of place among the other
> RESOLVE_ flags.
> 
> I would argue this should be an O_ flag, but not supported for the

I agree.

Christian


Re: [PATCH v3 0/5] Add support for RESOLVE_MAYEXEC

2020-04-29 Thread Aleksa Sarai
On 2020-04-28, Mickaël Salaün  wrote:
> The goal of this patch series is to enable to control script execution
> with interpreters help.  A new RESOLVE_MAYEXEC flag, usable through
> openat2(2), is added to enable userspace script interpreter to delegate
> to the kernel (and thus the system security policy) the permission to
> interpret/execute scripts or other files containing what can be seen as
> commands.
> 
> This third patch series mainly differ from the previous one by relying
> on the new openat2(2) system call to get rid of the undefined behavior
> of the open(2) flags.  Thus, the previous O_MAYEXEC flag is now replaced
> with the new RESOLVE_MAYEXEC flag and benefits from the openat2(2)
> strict check of this kind of flags.

My only strong upfront objection is with this being a RESOLVE_ flag.

RESOLVE_ flags have a specific meaning (they generally apply to all
components, and affect the rules of path resolution). RESOLVE_MAYEXEC
does neither of these things and so seems out of place among the other
RESOLVE_ flags.

I would argue this should be an O_ flag, but not supported for the
old-style open(2). This is what the O_SPECIFIC_FD patchset does[1] and I
think it's a reasonable way of solving such problems.

-- 
Aleksa Sarai
Senior Software Engineer (Containers)
SUSE Linux GmbH



signature.asc
Description: PGP signature


Re: [PATCH v3 0/5] Add support for RESOLVE_MAYEXEC

2020-04-29 Thread Mickaël Salaün



On 29/04/2020 00:01, Jann Horn wrote:
> On Tue, Apr 28, 2020 at 11:21 PM Florian Weimer  wrote:
>> * Jann Horn:
>>
>>> Just as a comment: You'd probably also have to use RESOLVE_MAYEXEC in
>>> the dynamic linker.
>>
>> Absolutely.  In typical configurations, the kernel does not enforce
>> that executable mappings must be backed by files which are executable.
>> It's most obvious with using an explicit loader invocation to run
>> executables on noexec mounts.  RESOLVE_MAYEXEC is much more useful
>> than trying to reimplement the kernel permission checks (or what some
>> believe they should be) in userspace.

Indeed it makes sense to use RESOLVE_MAYEXEC for the dynamic linker too.
Only the noexec mount option is taken into account for mmap(2) with
PROT_EXEC, and if you can trick the dynamic linker with JOP as Jann
explained, it may enable to execute new code. However, a kernel which
forbids remapping memory with PROT_EXEC still enables to implement a W^X
policy. Any JOP/ROP still enables unexpected code execution though.

> 
> Oh, good point.
> 
> That actually seems like something Mickaël could add to his series? If
> someone turns on that knob for "When an interpreter wants to execute
> something, enforce that we have execute access to it", they probably
> also don't want it to be possible to just map files as executable? So
> perhaps when that flag is on, the kernel should either refuse to map
> anything as executable if it wasn't opened with RESOLVE_MAYEXEC or
> (less strict) if RESOLVE_MAYEXEC wasn't used, print a warning, then
> check whether the file is executable and bail out if not?
> 
> A configuration where interpreters verify that scripts are executable,
> but other things can just mmap executable pages, seems kinda
> inconsistent...

As it is written in the documentation patch, this RESOLVE_MAYEXEC
feature is an important missing piece, but to implement a consistent
security policy we need to enable other restrictions starting with a
noexec mount point policy. The purpose of this patch series is not to
bring a full-feature LSM with process states handling, but it brings
what is needed for LSMs such as SELinux, IMA or IPE to extend their
capabilities to reach what you would expect.


Re: [PATCH v3 0/5] Add support for RESOLVE_MAYEXEC

2020-04-28 Thread Jann Horn
On Tue, Apr 28, 2020 at 11:21 PM Florian Weimer  wrote:
> * Jann Horn:
>
> > Just as a comment: You'd probably also have to use RESOLVE_MAYEXEC in
> > the dynamic linker.
>
> Absolutely.  In typical configurations, the kernel does not enforce
> that executable mappings must be backed by files which are executable.
> It's most obvious with using an explicit loader invocation to run
> executables on noexec mounts.  RESOLVE_MAYEXEC is much more useful
> than trying to reimplement the kernel permission checks (or what some
> believe they should be) in userspace.

Oh, good point.

That actually seems like something Mickaël could add to his series? If
someone turns on that knob for "When an interpreter wants to execute
something, enforce that we have execute access to it", they probably
also don't want it to be possible to just map files as executable? So
perhaps when that flag is on, the kernel should either refuse to map
anything as executable if it wasn't opened with RESOLVE_MAYEXEC or
(less strict) if RESOLVE_MAYEXEC wasn't used, print a warning, then
check whether the file is executable and bail out if not?

A configuration where interpreters verify that scripts are executable,
but other things can just mmap executable pages, seems kinda
inconsistent...


Re: [PATCH v3 0/5] Add support for RESOLVE_MAYEXEC

2020-04-28 Thread Florian Weimer
* Jann Horn:

> Just as a comment: You'd probably also have to use RESOLVE_MAYEXEC in
> the dynamic linker.

Absolutely.  In typical configurations, the kernel does not enforce
that executable mappings must be backed by files which are executable.
It's most obvious with using an explicit loader invocation to run
executables on noexec mounts.  RESOLVE_MAYEXEC is much more useful
than trying to reimplement the kernel permission checks (or what some
believe they should be) in userspace.


Re: [PATCH v3 0/5] Add support for RESOLVE_MAYEXEC

2020-04-28 Thread Jann Horn
On Tue, Apr 28, 2020 at 7:51 PM Mickaël Salaün  wrote:
> The goal of this patch series is to enable to control script execution
> with interpreters help.  A new RESOLVE_MAYEXEC flag, usable through
> openat2(2), is added to enable userspace script interpreter to delegate
> to the kernel (and thus the system security policy) the permission to
> interpret/execute scripts or other files containing what can be seen as
> commands.
>
> This third patch series mainly differ from the previous one by relying
> on the new openat2(2) system call to get rid of the undefined behavior
> of the open(2) flags.  Thus, the previous O_MAYEXEC flag is now replaced
> with the new RESOLVE_MAYEXEC flag and benefits from the openat2(2)
> strict check of this kind of flags.
>
> A simple system-wide security policy can be enforced by the system
> administrator through a sysctl configuration consistent with the mount
> points or the file access rights.  The documentation patch explains the
> prerequisites.
>
> Furthermore, the security policy can also be delegated to an LSM, either
> a MAC system or an integrity system.  For instance, the new kernel
> MAY_OPENEXEC flag closes a major IMA measurement/appraisal interpreter
> integrity gap by bringing the ability to check the use of scripts [1].
> Other uses are expected, such as for openat2(2) [2], SGX integration
> [3], bpffs [4] or IPE [5].
>
> Userspace needs to adapt to take advantage of this new feature.  For
> example, the PEP 578 [6] (Runtime Audit Hooks) enables Python 3.8 to be
> extended with policy enforcement points related to code interpretation,
> which can be used to align with the PowerShell audit features.
> Additional Python security improvements (e.g. a limited interpreter
> withou -c, stdin piping of code) are on their way.
>
> The initial idea come from CLIP OS 4 and the original implementation has
> been used for more than 11 years:
> https://github.com/clipos-archive/clipos4_doc
>
> An introduction to O_MAYEXEC (original name of RESOLVE_MAYEXEC) was
> given at the Linux Security Summit Europe 2018 - Linux Kernel Security
> Contributions by ANSSI:
> https://www.youtube.com/watch?v=chNjCRtPKQY=17m15s
> The "write xor execute" principle was explained at Kernel Recipes 2018 -
> CLIP OS: a defense-in-depth OS:
> https://www.youtube.com/watch?v=PjRE0uBtkHU=11m14s
>
> This patch series can be applied on top of v5.7-rc3.  This can be tested
> with CONFIG_SYSCTL.  I would really appreciate constructive comments on
> this patch series.

Just as a comment: You'd probably also have to use RESOLVE_MAYEXEC in
the dynamic linker. A while back, I wrote a proof-of-concept ELF
library that can execute arbitrary code without triggering IMA because
it has no executable segments - instead it uses init_array to directly
trigger code execution at a JOP gadget in libc that then uses
mprotect() to make the code executable. I tested this on Debian
Stretch back in 2018.

=
user@debian:~/ima_stuff$ cat make_segments_rw.c
#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc, char **argv) {
int fd = open(argv[1], O_RDWR);
if (fd == -1) err(1, "open");
struct stat st;
if (fstat(fd, )) err(1, "stat");
unsigned char *mapping = mmap(NULL, st.st_size,
PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (mapping == MAP_FAILED) err(1, "mmap");
Elf64_Ehdr *ehdr = (void*)mapping;
Elf64_Phdr *phdrs = (void*)(mapping + ehdr->e_phoff);

for (int i=0; ie_phnum; i++) {
phdrs[i].p_flags &= ~PF_X;
phdrs[i].p_flags |= PF_W;
}

return 0;
}
user@debian:~/ima_stuff$ cat test.s
.text
.section.text.startup,"aw",@progbits
.globl  foobar
.align 4096
foobar:
/* alignment for xmm stuff in libc */
sub $8, %rsp
callgetpid
mov %rax, %rsi
leaqmessage(%rip), %rdi
callprintf
movqstdout_indir(%rip), %rdi
movq(%rdi), %rdi
call fflush
xor %edi, %edi
call_exit

.section.init_array,"aw"
.align 8
.quad   rmdir+0x774

.section.fini_array,"aw"
.quad   0xdeadbeef
.quad   0xdeadbeef
.quad   0xdeadbeef
.quad   ucontext_data /* goes into rdi */
.quad   0xdeadbeef
.quad   0xdeadbeef
.quad   0xdeadbeef
.quad   0xdeadbeef
.quad   setcontext+0x35 /* call target */

.data
ucontext_data:
/* 0x00 */
.quad 0xdeadbeefdeadbeef, 0xdeadbeefdeadbeef
.quad 0xdeadbeefdeadbeef, 0xdeadbeefdeadbeef
.quad 0xdeadbeefdeadbeef, 0xdeadbeefdeadbeef
.quad 0xdeadbeefdeadbeef, 0xdeadbeefdeadbeef
/* 0x40 */
.quad 0xdeadbeefdeadbeef, 0xdeadbeefdeadbeef
.quad 0xdeadbeefdeadbeef, 0xdeadbeefdeadbeef
.quad 0xdeadbeefdeadbeef, foobar

[PATCH v3 0/5] Add support for RESOLVE_MAYEXEC

2020-04-28 Thread Mickaël Salaün
Hi,

The goal of this patch series is to enable to control script execution
with interpreters help.  A new RESOLVE_MAYEXEC flag, usable through
openat2(2), is added to enable userspace script interpreter to delegate
to the kernel (and thus the system security policy) the permission to
interpret/execute scripts or other files containing what can be seen as
commands.

This third patch series mainly differ from the previous one by relying
on the new openat2(2) system call to get rid of the undefined behavior
of the open(2) flags.  Thus, the previous O_MAYEXEC flag is now replaced
with the new RESOLVE_MAYEXEC flag and benefits from the openat2(2)
strict check of this kind of flags.

A simple system-wide security policy can be enforced by the system
administrator through a sysctl configuration consistent with the mount
points or the file access rights.  The documentation patch explains the
prerequisites.

Furthermore, the security policy can also be delegated to an LSM, either
a MAC system or an integrity system.  For instance, the new kernel
MAY_OPENEXEC flag closes a major IMA measurement/appraisal interpreter
integrity gap by bringing the ability to check the use of scripts [1].
Other uses are expected, such as for openat2(2) [2], SGX integration
[3], bpffs [4] or IPE [5].

Userspace needs to adapt to take advantage of this new feature.  For
example, the PEP 578 [6] (Runtime Audit Hooks) enables Python 3.8 to be
extended with policy enforcement points related to code interpretation,
which can be used to align with the PowerShell audit features.
Additional Python security improvements (e.g. a limited interpreter
withou -c, stdin piping of code) are on their way.

The initial idea come from CLIP OS 4 and the original implementation has
been used for more than 11 years:
https://github.com/clipos-archive/clipos4_doc

An introduction to O_MAYEXEC (original name of RESOLVE_MAYEXEC) was
given at the Linux Security Summit Europe 2018 - Linux Kernel Security
Contributions by ANSSI:
https://www.youtube.com/watch?v=chNjCRtPKQY=17m15s
The "write xor execute" principle was explained at Kernel Recipes 2018 -
CLIP OS: a defense-in-depth OS:
https://www.youtube.com/watch?v=PjRE0uBtkHU=11m14s

This patch series can be applied on top of v5.7-rc3.  This can be tested
with CONFIG_SYSCTL.  I would really appreciate constructive comments on
this patch series.

Previous version:
https://lore.kernel.org/lkml/20190906152455.22757-1-...@digikod.net/


[1] https://lore.kernel.org/lkml/1544647356.4028.105.ca...@linux.ibm.com/
[2] https://lore.kernel.org/lkml/20190904201933.10736-6-cyp...@cyphar.com/
[3] 
https://lore.kernel.org/lkml/CALCETrVovr8XNZSroey7pHF46O=kj_c5D9K8h=z2t_cnrpv...@mail.gmail.com/
[4] 
https://lore.kernel.org/lkml/calcetrvez0euffxwfhtag_j+advbzewe0m3wjxmwveo7pj+...@mail.gmail.com/
[5] 
https://lore.kernel.org/lkml/20200406221439.1469862-12-deven.de...@linux.microsoft.com/
[6] https://www.python.org/dev/peps/pep-0578/

Regards,

Mickaël Salaün (5):
  fs: Add support for a RESOLVE_MAYEXEC flag on openat2(2)
  fs: Add a MAY_EXECMOUNT flag to infer the noexec mount property
  fs: Enable to enforce noexec mounts or file exec through
RESOLVE_MAYEXEC
  selftest/openat2: Add tests for RESOLVE_MAYEXEC enforcing
  doc: Add documentation for the fs.open_mayexec_enforce sysctl

 Documentation/admin-guide/sysctl/fs.rst   |  43 +++
 fs/namei.c|  74 +++-
 fs/open.c |   6 +
 include/linux/fcntl.h |   2 +-
 include/linux/fs.h|   7 +
 include/uapi/linux/openat2.h  |   6 +
 kernel/sysctl.c   |   7 +
 tools/testing/selftests/kselftest_harness.h   |   3 +
 tools/testing/selftests/openat2/Makefile  |   3 +-
 tools/testing/selftests/openat2/config|   1 +
 tools/testing/selftests/openat2/helpers.h |   3 +
 .../testing/selftests/openat2/omayexec_test.c | 315 ++
 12 files changed, 467 insertions(+), 3 deletions(-)
 create mode 100644 tools/testing/selftests/openat2/config
 create mode 100644 tools/testing/selftests/openat2/omayexec_test.c

-- 
2.26.2