All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Mickaël Salaün" <mic@digikod.net>
To: Mark Rutland <mark.rutland@arm.com>,
	"Madhavan T. Venkataraman" <madvenka@linux.microsoft.com>
Cc: kernel-hardening@lists.openwall.com, linux-api@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-fsdevel@vger.kernel.org, linux-integrity@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-security-module@vger.kernel.org, oleg@redhat.com,
	x86@kernel.org
Subject: Re: [PATCH v1 0/4] [RFC] Implement Trampoline File Descriptor
Date: Wed, 19 Aug 2020 20:53:42 +0200	[thread overview]
Message-ID: <41c4de64-68d0-6fcb-e5c3-63ebd459262e@digikod.net> (raw)
In-Reply-To: <20200812100650.GB28154@C02TD0UTHF1T.local>


On 12/08/2020 12:06, Mark Rutland wrote:
> On Thu, Aug 06, 2020 at 12:26:02PM -0500, Madhavan T. Venkataraman wrote:
>> Thanks for the lively discussion. I have tried to answer some of the
>> comments below.
>>
>> On 8/4/20 9:30 AM, Mark Rutland wrote:
>>>
>>>> So, the context is - if security settings in a system disallow a page to have
>>>> both write and execute permissions, how do you allow the execution of
>>>> genuine trampolines that are runtime generated and placed in a data
>>>> page or a stack page?
>>> There are options today, e.g.
>>>
>>> a) If the restriction is only per-alias, you can have distinct aliases
>>>    where one is writable and another is executable, and you can make it
>>>    hard to find the relationship between the two.
>>>
>>> b) If the restriction is only temporal, you can write instructions into
>>>    an RW- buffer, transition the buffer to R--, verify the buffer
>>>    contents, then transition it to --X.
>>>
>>> c) You can have two processes A and B where A generates instrucitons into
>>>    a buffer that (only) B can execute (where B may be restricted from
>>>    making syscalls like write, mprotect, etc).
>>
>> The general principle of the mitigation is W^X. I would argue that
>> the above options are violations of the W^X principle. If they are
>> allowed today, they must be fixed. And they will be. So, we cannot
>> rely on them.
> 
> Hold on.
> 
> Contemporary W^X means that a given virtual alias cannot be writeable
> and executeable simultaneously, permitting (a) and (b). If you read the
> references on the Wikipedia page for W^X you'll see the OpenBSD 3.3
> release notes and related presentation make this clear, and further they
> expect (b) to occur with JITS flipping W/X with mprotect().

W^X (with "permanent" mprotect restrictions [1]) goes back to 2000 with
PaX [2] (which predates partial OpenBSD implementation from 2003).

[1] https://pax.grsecurity.net/docs/mprotect.txt
[2] https://undeadly.org/cgi?action=article;sid=20030417082752

> 
> Please don't conflate your assumed stronger semantics with the general
> principle. It not matching you expectations does not necessarily mean
> that it is wrong.
> 
> If you want a stronger W^X semantics, please refer to this specifically
> with a distinct name.
> 
>> a) This requires a remap operation. Two mappings point to the same
>>      physical page. One mapping has W and the other one has X. This
>>      is a violation of W^X.
>>
>> b) This is again a violation. The kernel should refuse to give execute
>>      permission to a page that was writeable in the past and refuse to
>>      give write permission to a page that was executable in the past.
>>
>> c) This is just a variation of (a).
> 
> As above, this is not true.
> 
> If you have a rationale for why this is desirable or necessary, please
> justify that before using this as justification for additional features.
> 
>> In general, the problem with user-level methods to map and execute
>> dynamic code is that the kernel cannot tell if a genuine application is
>> using them or an attacker is using them or piggy-backing on them.
> 
> Yes, and as I pointed out the same is true for trampfd unless you can
> somehow authenticate the calls are legitimate (in both callsite and the
> set of arguments), and I don't see any reasonable way of doing that.
> 
> If you relax your threat model to an attacker not being able to make
> arbitrary syscalls, then your suggestion that userspace can perorm
> chceks between syscalls may be sufficient, but as I pointed out that's
> equally true for a sealed memfd or similar.
> 
>> Off the top of my head, I have tried to identify some examples
>> where we can have more trust on dynamic code and have the kernel
>> permit its execution.
>>
>> 1. If the kernel can do the job, then that is one safe way. Here, the kernel
>>     is the code. There is no code generation involved. This is what I
>>     have presented in the patch series as the first cut.
> 
> This is sleight-of-hand; it doesn't matter where the logic is performed
> if the power is identical. Practically speaking this is equivalent to
> some dynamic code generation.
> 
> I think that it's misleading to say that because the kernel emulates
> something it is safe when the provenance of the syscall arguments cannot
> be verified.
> 
> [...]
> 
>> Anyway, these are just examples. The principle is - if we can identify
>> dynamic code that has a certain measure of trust, can the kernel
>> permit their execution?
> 
> My point generally is that the kernel cannot identify this, and if
> usrspace code is trusted to dynamically generate trampfd arguments it
> can equally be trusted to dyncamilly generate code.
> 
> [...]
> 
>> As I have mentioned above, I intend to have the kernel generate code
>> only if the code generation is simple enough. For more complicated cases,
>> I plan to use a user-level code generator that is for exclusive kernel use.
>> I have yet to work out the details on how this would work. Need time.
> 
> This reads to me like trampfd is only dealing with a few special cases
> and we know that we need a more general solution.
> 
> I hope I am mistaken, but I get the strong impression that you're trying
> to justify your existing solution rather than trying to understand the
> problem space.
> 
> To be clear, my strong opinion is that we should not be trying to do
> this sort of emulation or code generation within the kernel. I do think
> it's worthwhile to look at mechanisms to make it harder to subvert
> dynamic userspace code generation, but I think the code generation
> itself needs to live in userspace (e.g. for ABI reasons I previously
> mentioned).
> 
> Mark.
> 

WARNING: multiple messages have this Message-ID (diff)
From: "Mickaël Salaün" <mic@digikod.net>
To: Mark Rutland <mark.rutland@arm.com>,
	"Madhavan T. Venkataraman" <madvenka@linux.microsoft.com>
Cc: kernel-hardening@lists.openwall.com, linux-api@vger.kernel.org,
	x86@kernel.org, linux-kernel@vger.kernel.org, oleg@redhat.com,
	linux-security-module@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, linux-integrity@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v1 0/4] [RFC] Implement Trampoline File Descriptor
Date: Wed, 19 Aug 2020 20:53:42 +0200	[thread overview]
Message-ID: <41c4de64-68d0-6fcb-e5c3-63ebd459262e@digikod.net> (raw)
In-Reply-To: <20200812100650.GB28154@C02TD0UTHF1T.local>


On 12/08/2020 12:06, Mark Rutland wrote:
> On Thu, Aug 06, 2020 at 12:26:02PM -0500, Madhavan T. Venkataraman wrote:
>> Thanks for the lively discussion. I have tried to answer some of the
>> comments below.
>>
>> On 8/4/20 9:30 AM, Mark Rutland wrote:
>>>
>>>> So, the context is - if security settings in a system disallow a page to have
>>>> both write and execute permissions, how do you allow the execution of
>>>> genuine trampolines that are runtime generated and placed in a data
>>>> page or a stack page?
>>> There are options today, e.g.
>>>
>>> a) If the restriction is only per-alias, you can have distinct aliases
>>>    where one is writable and another is executable, and you can make it
>>>    hard to find the relationship between the two.
>>>
>>> b) If the restriction is only temporal, you can write instructions into
>>>    an RW- buffer, transition the buffer to R--, verify the buffer
>>>    contents, then transition it to --X.
>>>
>>> c) You can have two processes A and B where A generates instrucitons into
>>>    a buffer that (only) B can execute (where B may be restricted from
>>>    making syscalls like write, mprotect, etc).
>>
>> The general principle of the mitigation is W^X. I would argue that
>> the above options are violations of the W^X principle. If they are
>> allowed today, they must be fixed. And they will be. So, we cannot
>> rely on them.
> 
> Hold on.
> 
> Contemporary W^X means that a given virtual alias cannot be writeable
> and executeable simultaneously, permitting (a) and (b). If you read the
> references on the Wikipedia page for W^X you'll see the OpenBSD 3.3
> release notes and related presentation make this clear, and further they
> expect (b) to occur with JITS flipping W/X with mprotect().

W^X (with "permanent" mprotect restrictions [1]) goes back to 2000 with
PaX [2] (which predates partial OpenBSD implementation from 2003).

[1] https://pax.grsecurity.net/docs/mprotect.txt
[2] https://undeadly.org/cgi?action=article;sid=20030417082752

> 
> Please don't conflate your assumed stronger semantics with the general
> principle. It not matching you expectations does not necessarily mean
> that it is wrong.
> 
> If you want a stronger W^X semantics, please refer to this specifically
> with a distinct name.
> 
>> a) This requires a remap operation. Two mappings point to the same
>>      physical page. One mapping has W and the other one has X. This
>>      is a violation of W^X.
>>
>> b) This is again a violation. The kernel should refuse to give execute
>>      permission to a page that was writeable in the past and refuse to
>>      give write permission to a page that was executable in the past.
>>
>> c) This is just a variation of (a).
> 
> As above, this is not true.
> 
> If you have a rationale for why this is desirable or necessary, please
> justify that before using this as justification for additional features.
> 
>> In general, the problem with user-level methods to map and execute
>> dynamic code is that the kernel cannot tell if a genuine application is
>> using them or an attacker is using them or piggy-backing on them.
> 
> Yes, and as I pointed out the same is true for trampfd unless you can
> somehow authenticate the calls are legitimate (in both callsite and the
> set of arguments), and I don't see any reasonable way of doing that.
> 
> If you relax your threat model to an attacker not being able to make
> arbitrary syscalls, then your suggestion that userspace can perorm
> chceks between syscalls may be sufficient, but as I pointed out that's
> equally true for a sealed memfd or similar.
> 
>> Off the top of my head, I have tried to identify some examples
>> where we can have more trust on dynamic code and have the kernel
>> permit its execution.
>>
>> 1. If the kernel can do the job, then that is one safe way. Here, the kernel
>>     is the code. There is no code generation involved. This is what I
>>     have presented in the patch series as the first cut.
> 
> This is sleight-of-hand; it doesn't matter where the logic is performed
> if the power is identical. Practically speaking this is equivalent to
> some dynamic code generation.
> 
> I think that it's misleading to say that because the kernel emulates
> something it is safe when the provenance of the syscall arguments cannot
> be verified.
> 
> [...]
> 
>> Anyway, these are just examples. The principle is - if we can identify
>> dynamic code that has a certain measure of trust, can the kernel
>> permit their execution?
> 
> My point generally is that the kernel cannot identify this, and if
> usrspace code is trusted to dynamically generate trampfd arguments it
> can equally be trusted to dyncamilly generate code.
> 
> [...]
> 
>> As I have mentioned above, I intend to have the kernel generate code
>> only if the code generation is simple enough. For more complicated cases,
>> I plan to use a user-level code generator that is for exclusive kernel use.
>> I have yet to work out the details on how this would work. Need time.
> 
> This reads to me like trampfd is only dealing with a few special cases
> and we know that we need a more general solution.
> 
> I hope I am mistaken, but I get the strong impression that you're trying
> to justify your existing solution rather than trying to understand the
> problem space.
> 
> To be clear, my strong opinion is that we should not be trying to do
> this sort of emulation or code generation within the kernel. I do think
> it's worthwhile to look at mechanisms to make it harder to subvert
> dynamic userspace code generation, but I think the code generation
> itself needs to live in userspace (e.g. for ABI reasons I previously
> mentioned).
> 
> Mark.
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2020-08-19 18:54 UTC|newest]

Thread overview: 146+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <aefc85852ea518982e74b233e11e16d2e707bc32>
2020-07-28 13:10 ` [PATCH v1 0/4] [RFC] Implement Trampoline File Descriptor madvenka
2020-07-28 13:10   ` madvenka
2020-07-28 13:10   ` [PATCH v1 1/4] [RFC] fs/trampfd: Implement the trampoline file descriptor API madvenka
2020-07-28 13:10     ` madvenka
2020-07-28 14:50     ` Oleg Nesterov
2020-07-28 14:50       ` Oleg Nesterov
2020-07-28 14:58       ` Madhavan T. Venkataraman
2020-07-28 14:58         ` Madhavan T. Venkataraman
2020-07-28 16:06         ` Oleg Nesterov
2020-07-28 16:06           ` Oleg Nesterov
2020-07-28 19:48     ` kernel test robot
2020-07-29  2:33     ` kernel test robot
2020-07-28 13:10   ` [PATCH v1 2/4] [RFC] x86/trampfd: Provide support for the trampoline file descriptor madvenka
2020-07-28 13:10     ` madvenka
2020-07-28 18:38     ` kernel test robot
2020-07-30  9:06     ` Greg KH
2020-07-30  9:06       ` Greg KH
2020-07-30 14:25       ` Madhavan T. Venkataraman
2020-07-30 14:25         ` Madhavan T. Venkataraman
2020-07-28 13:10   ` [PATCH v1 3/4] [RFC] arm64/trampfd: " madvenka
2020-07-28 13:10     ` madvenka
2020-07-28 13:10   ` [PATCH v1 4/4] [RFC] arm/trampfd: " madvenka
2020-07-28 13:10     ` madvenka
2020-07-28 15:13   ` [PATCH v1 0/4] [RFC] Implement Trampoline File Descriptor David Laight
2020-07-28 15:13     ` David Laight
2020-07-28 15:13     ` David Laight
2020-07-28 16:32     ` Madhavan T. Venkataraman
2020-07-28 16:32       ` Madhavan T. Venkataraman
2020-07-28 16:32       ` Madhavan T. Venkataraman
2020-07-28 17:16       ` Andy Lutomirski
2020-07-28 17:16         ` Andy Lutomirski
2020-07-28 17:16         ` Andy Lutomirski
2020-07-28 17:39         ` Madhavan T. Venkataraman
2020-07-29  5:16           ` Andy Lutomirski
2020-07-29  5:16             ` Andy Lutomirski
2020-07-29  5:16             ` Andy Lutomirski
2020-07-28 18:52         ` Madhavan T. Venkataraman
2020-07-28 18:52           ` Madhavan T. Venkataraman
2020-07-28 18:52           ` Madhavan T. Venkataraman
2020-07-29  8:36           ` David Laight
2020-07-29  8:36             ` David Laight
2020-07-29  8:36             ` David Laight
2020-07-29 17:55             ` Madhavan T. Venkataraman
2020-07-29 17:55               ` Madhavan T. Venkataraman
2020-07-29 17:55               ` Madhavan T. Venkataraman
2020-07-28 16:05   ` Casey Schaufler
2020-07-28 16:05     ` Casey Schaufler
2020-07-28 16:49     ` Madhavan T. Venkataraman
2020-07-28 16:49       ` Madhavan T. Venkataraman
2020-07-28 17:05     ` James Morris
2020-07-28 17:05       ` James Morris
2020-07-28 17:08       ` Madhavan T. Venkataraman
2020-07-28 17:08         ` Madhavan T. Venkataraman
2020-07-28 17:31   ` Andy Lutomirski
2020-07-28 17:31     ` Andy Lutomirski
2020-07-28 17:31     ` Andy Lutomirski
2020-07-28 19:01     ` Madhavan T. Venkataraman
2020-07-28 19:01       ` Madhavan T. Venkataraman
2020-07-29 13:29     ` Florian Weimer
2020-07-29 13:29       ` Florian Weimer
2020-07-29 13:29       ` Florian Weimer
2020-07-30 13:09     ` David Laight
2020-07-30 13:09       ` David Laight
2020-08-02 11:56       ` Pavel Machek
2020-08-02 11:56         ` Pavel Machek
2020-08-03  8:08         ` David Laight
2020-08-03  8:08           ` David Laight
2020-08-03 15:57           ` Madhavan T. Venkataraman
2020-08-03 15:57             ` Madhavan T. Venkataraman
2020-07-30 14:24     ` Madhavan T. Venkataraman
2020-07-30 20:54       ` Andy Lutomirski
2020-07-30 20:54         ` Andy Lutomirski
2020-07-30 20:54         ` Andy Lutomirski
2020-07-31 17:13         ` Madhavan T. Venkataraman
2020-07-31 17:13           ` Madhavan T. Venkataraman
2020-07-31 18:31           ` Mark Rutland
2020-07-31 18:31             ` Mark Rutland
2020-08-03  8:27             ` David Laight
2020-08-03  8:27               ` David Laight
2020-08-03 16:03               ` Madhavan T. Venkataraman
2020-08-03 16:03                 ` Madhavan T. Venkataraman
2020-08-03 16:57                 ` David Laight
2020-08-03 16:57                   ` David Laight
2020-08-03 17:00                   ` Madhavan T. Venkataraman
2020-08-03 17:00                     ` Madhavan T. Venkataraman
2020-08-03 17:58             ` Madhavan T. Venkataraman
2020-08-03 17:58               ` Madhavan T. Venkataraman
2020-08-04 13:55               ` Mark Rutland
2020-08-04 13:55                 ` Mark Rutland
2020-08-04 14:33                 ` David Laight
2020-08-04 14:33                   ` David Laight
2020-08-04 14:44                   ` David Laight
2020-08-04 14:44                     ` David Laight
2020-08-04 14:48                   ` Madhavan T. Venkataraman
2020-08-04 14:48                     ` Madhavan T. Venkataraman
2020-08-04 15:46                 ` Madhavan T. Venkataraman
2020-08-04 15:46                   ` Madhavan T. Venkataraman
2020-08-02 13:57           ` Florian Weimer
2020-08-02 13:57             ` Florian Weimer
2020-08-02 13:57             ` Florian Weimer
2020-07-30 14:42     ` Madhavan T. Venkataraman
2020-07-30 14:42       ` Madhavan T. Venkataraman
2020-08-02 18:54     ` Madhavan T. Venkataraman
2020-08-02 18:54       ` Madhavan T. Venkataraman
2020-08-02 20:00       ` Andy Lutomirski
2020-08-02 20:00         ` Andy Lutomirski
2020-08-02 20:00         ` Andy Lutomirski
2020-08-02 22:58         ` Madhavan T. Venkataraman
2020-08-02 22:58           ` Madhavan T. Venkataraman
2020-08-03 18:36         ` Madhavan T. Venkataraman
2020-08-03 18:36           ` Madhavan T. Venkataraman
2020-08-10 17:20         ` Madhavan T. Venkataraman
2020-08-10 17:34         ` Madhavan T. Venkataraman
2020-08-10 17:34           ` Madhavan T. Venkataraman
2020-08-11 21:12           ` Madhavan T. Venkataraman
2020-08-11 21:12             ` Madhavan T. Venkataraman
2020-08-03  8:23       ` David Laight
2020-08-03  8:23         ` David Laight
2020-08-03 15:59         ` Madhavan T. Venkataraman
2020-08-03 15:59           ` Madhavan T. Venkataraman
2020-07-31 18:09   ` Mark Rutland
2020-07-31 18:09     ` Mark Rutland
2020-07-31 20:08     ` Madhavan T. Venkataraman
2020-07-31 20:08       ` Madhavan T. Venkataraman
2020-08-03 16:57     ` Madhavan T. Venkataraman
2020-08-03 16:57       ` Madhavan T. Venkataraman
2020-08-04 14:30       ` Mark Rutland
2020-08-04 14:30         ` Mark Rutland
2020-08-06 17:26         ` Madhavan T. Venkataraman
2020-08-06 17:26           ` Madhavan T. Venkataraman
2020-08-08 22:17           ` Pavel Machek
2020-08-08 22:17             ` Pavel Machek
2020-08-11 12:41             ` Madhavan T. Venkataraman
2020-08-11 12:41               ` Madhavan T. Venkataraman
2020-08-11 13:08               ` Pavel Machek
2020-08-11 13:08                 ` Pavel Machek
2020-08-11 15:54                 ` Madhavan T. Venkataraman
2020-08-11 15:54                   ` Madhavan T. Venkataraman
2020-08-12 10:06           ` Mark Rutland
2020-08-12 10:06             ` Mark Rutland
2020-08-12 18:47             ` Madhavan T. Venkataraman
2020-08-12 18:47               ` Madhavan T. Venkataraman
2020-08-19 18:53             ` Mickaël Salaün [this message]
2020-08-19 18:53               ` Mickaël Salaün
2020-09-01 15:42               ` Mark Rutland
2020-09-01 15:42                 ` Mark Rutland

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=41c4de64-68d0-6fcb-e5c3-63ebd459262e@digikod.net \
    --to=mic@digikod.net \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=madvenka@linux.microsoft.com \
    --cc=mark.rutland@arm.com \
    --cc=oleg@redhat.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.