All of lore.kernel.org
 help / color / mirror / Atom feed
From: keescook@chromium.org (Kees Cook)
To: linux-arm-kernel@lists.infradead.org
Subject: [kernel-hardening] Re: [PATCH v3 0/7] arm64: Privileged Access Never using TTBR0_EL1 switching
Date: Thu, 27 Oct 2016 14:23:26 -0700	[thread overview]
Message-ID: <CAGXu5jL9=DKZSdOHh9gUqn5y478p7dwbVRFoQv5op5v8wLWBRw@mail.gmail.com> (raw)
In-Reply-To: <20161027145450.GB3762@e104818-lin.cambridge.arm.com>

On Thu, Oct 27, 2016 at 7:54 AM, Catalin Marinas
<catalin.marinas@arm.com> wrote:
> On Fri, Sep 30, 2016 at 11:42:02AM -0700, Kees Cook wrote:
>> On Thu, Sep 29, 2016 at 3:44 PM, Sami Tolvanen <samitolvanen@google.com> wrote:
>> > On Thu, Sep 15, 2016 at 05:20:45PM +0100, Mark Rutland wrote:
>> >> Likewise, how do we handle __flush_cache_user_range and
>> >> flush_icache_range? Some callers (e.g. __do_compat_cache_op) pass in
>> >> __user addresses.
>> >
>> > Also EXEC_USERSPACE in lkdtm passes a user space address to flush_icache_range
>> > and causes the process to hang when I tested these patches on HiKey.
>> >
>> > Adding uaccess_{enable,disable}_not_uao to __flush_cache_user_range appears to
>> > fix the problem.
>>
>> I had a thought just now on this: is lkdtm maybe doing the wrong thing
>> here? i.e. should lkdtm be the one do to the uaccess_en/disable
>> instead of flush_icache_range() itself, since it's the one abusing the
>> API?
>
> (preparing the v4 series)
>
> I think lkdtm is using the API incorrectly here. The documentation for
> flush_icache_range() (Documentation/cachetlb.txt) states that it is to
> be used on kernel addresses. Even with uaccess_enable/disable in lkdtm,
> faults on user space can still happen and the flush_icache_range()
> function must be able to handle them. It happens to work on arm64
> because of the fall through __flush_cache_user_range() but that's not
> guaranteed on other architectures.
>
> A potential solution is to use access_process_vm() and let the arch code
> handle the cache maintenance automatically:

Ah, perfect! I'll give this a spin, thanks!

-Kees

> ---------------------8<--------------------------------
> From fcbb7c9c30daf9bfc2a215ec10dba79c109ab835 Mon Sep 17 00:00:00 2001
> From: Catalin Marinas <catalin.marinas@arm.com>
> Date: Thu, 27 Oct 2016 15:47:20 +0100
> Subject: [PATCH] lkdtm: Do not use flush_icache_range() on user addresses
>
> The flush_icache_range() API is meant to be used on kernel addresses
> only as it may not have the infrastructure (exception entries) to handle
> user memory faults.
>
> The lkdtm execute_user_location() function tests the kernel execution of
> user space addresses by mmap'ing an anonymous page, copying some code
> together with cache maintenance and attempting to run it. However, the
> cache maintenance step may fail because of the incorrect API usage
> described above. The patch changes lkdtm to use access_process_vm() for
> copying the code into user space which would take care of the necessary
> cache maintenance.
>
> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> ---
>  drivers/misc/lkdtm_perms.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/misc/lkdtm_perms.c b/drivers/misc/lkdtm_perms.c
> index 45f1c0f96612..c7635a79341f 100644
> --- a/drivers/misc/lkdtm_perms.c
> +++ b/drivers/misc/lkdtm_perms.c
> @@ -60,15 +60,18 @@ static noinline void execute_location(void *dst, bool write)
>
>  static void execute_user_location(void *dst)
>  {
> +       int copied;
> +
>         /* Intentionally crossing kernel/user memory boundary. */
>         void (*func)(void) = dst;
>
>         pr_info("attempting ok execution at %p\n", do_nothing);
>         do_nothing();
>
> -       if (copy_to_user((void __user *)dst, do_nothing, EXEC_SIZE))
> +       copied = access_process_vm(current, (unsigned long)dst, do_nothing,
> +                                  EXEC_SIZE, FOLL_WRITE);
> +       if (copied < EXEC_SIZE)
>                 return;
> -       flush_icache_range((unsigned long)dst, (unsigned long)dst + EXEC_SIZE);
>         pr_info("attempting bad execution at %p\n", func);
>         func();
>  }



-- 
Kees Cook
Nexus Security

WARNING: multiple messages have this Message-ID (diff)
From: Kees Cook <keescook@chromium.org>
To: Catalin Marinas <catalin.marinas@arm.com>
Cc: Sami Tolvanen <samitolvanen@google.com>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	"kernel-hardening@lists.openwall.com"
	<kernel-hardening@lists.openwall.com>,
	Will Deacon <will.deacon@arm.com>,
	AKASHI Takahiro <takahiro.akashi@linaro.org>,
	James Morse <james.morse@arm.com>,
	andre.przywara@arm.com,
	"Suzuki K. Poulose" <suzuki.poulose@arm.com>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [kernel-hardening] Re: [PATCH v3 0/7] arm64: Privileged Access Never using TTBR0_EL1 switching
Date: Thu, 27 Oct 2016 14:23:26 -0700	[thread overview]
Message-ID: <CAGXu5jL9=DKZSdOHh9gUqn5y478p7dwbVRFoQv5op5v8wLWBRw@mail.gmail.com> (raw)
In-Reply-To: <20161027145450.GB3762@e104818-lin.cambridge.arm.com>

On Thu, Oct 27, 2016 at 7:54 AM, Catalin Marinas
<catalin.marinas@arm.com> wrote:
> On Fri, Sep 30, 2016 at 11:42:02AM -0700, Kees Cook wrote:
>> On Thu, Sep 29, 2016 at 3:44 PM, Sami Tolvanen <samitolvanen@google.com> wrote:
>> > On Thu, Sep 15, 2016 at 05:20:45PM +0100, Mark Rutland wrote:
>> >> Likewise, how do we handle __flush_cache_user_range and
>> >> flush_icache_range? Some callers (e.g. __do_compat_cache_op) pass in
>> >> __user addresses.
>> >
>> > Also EXEC_USERSPACE in lkdtm passes a user space address to flush_icache_range
>> > and causes the process to hang when I tested these patches on HiKey.
>> >
>> > Adding uaccess_{enable,disable}_not_uao to __flush_cache_user_range appears to
>> > fix the problem.
>>
>> I had a thought just now on this: is lkdtm maybe doing the wrong thing
>> here? i.e. should lkdtm be the one do to the uaccess_en/disable
>> instead of flush_icache_range() itself, since it's the one abusing the
>> API?
>
> (preparing the v4 series)
>
> I think lkdtm is using the API incorrectly here. The documentation for
> flush_icache_range() (Documentation/cachetlb.txt) states that it is to
> be used on kernel addresses. Even with uaccess_enable/disable in lkdtm,
> faults on user space can still happen and the flush_icache_range()
> function must be able to handle them. It happens to work on arm64
> because of the fall through __flush_cache_user_range() but that's not
> guaranteed on other architectures.
>
> A potential solution is to use access_process_vm() and let the arch code
> handle the cache maintenance automatically:

Ah, perfect! I'll give this a spin, thanks!

-Kees

> ---------------------8<--------------------------------
> From fcbb7c9c30daf9bfc2a215ec10dba79c109ab835 Mon Sep 17 00:00:00 2001
> From: Catalin Marinas <catalin.marinas@arm.com>
> Date: Thu, 27 Oct 2016 15:47:20 +0100
> Subject: [PATCH] lkdtm: Do not use flush_icache_range() on user addresses
>
> The flush_icache_range() API is meant to be used on kernel addresses
> only as it may not have the infrastructure (exception entries) to handle
> user memory faults.
>
> The lkdtm execute_user_location() function tests the kernel execution of
> user space addresses by mmap'ing an anonymous page, copying some code
> together with cache maintenance and attempting to run it. However, the
> cache maintenance step may fail because of the incorrect API usage
> described above. The patch changes lkdtm to use access_process_vm() for
> copying the code into user space which would take care of the necessary
> cache maintenance.
>
> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> ---
>  drivers/misc/lkdtm_perms.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/misc/lkdtm_perms.c b/drivers/misc/lkdtm_perms.c
> index 45f1c0f96612..c7635a79341f 100644
> --- a/drivers/misc/lkdtm_perms.c
> +++ b/drivers/misc/lkdtm_perms.c
> @@ -60,15 +60,18 @@ static noinline void execute_location(void *dst, bool write)
>
>  static void execute_user_location(void *dst)
>  {
> +       int copied;
> +
>         /* Intentionally crossing kernel/user memory boundary. */
>         void (*func)(void) = dst;
>
>         pr_info("attempting ok execution at %p\n", do_nothing);
>         do_nothing();
>
> -       if (copy_to_user((void __user *)dst, do_nothing, EXEC_SIZE))
> +       copied = access_process_vm(current, (unsigned long)dst, do_nothing,
> +                                  EXEC_SIZE, FOLL_WRITE);
> +       if (copied < EXEC_SIZE)
>                 return;
> -       flush_icache_range((unsigned long)dst, (unsigned long)dst + EXEC_SIZE);
>         pr_info("attempting bad execution at %p\n", func);
>         func();
>  }



-- 
Kees Cook
Nexus Security

  reply	other threads:[~2016-10-27 21:23 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-13 17:46 [PATCH v3 0/7] arm64: Privileged Access Never using TTBR0_EL1 switching Catalin Marinas
2016-09-13 17:46 ` [kernel-hardening] " Catalin Marinas
2016-09-13 17:46 ` [PATCH v3 1/7] arm64: Factor out PAN enabling/disabling into separate uaccess_* macros Catalin Marinas
2016-09-13 17:46   ` [kernel-hardening] " Catalin Marinas
2016-09-15 15:10   ` Mark Rutland
2016-09-15 15:10     ` [kernel-hardening] " Mark Rutland
2016-09-13 17:46 ` [PATCH v3 2/7] arm64: Factor out TTBR0_EL1 post-update workaround into a specific asm macro Catalin Marinas
2016-09-13 17:46   ` [kernel-hardening] " Catalin Marinas
2016-09-15 15:19   ` Mark Rutland
2016-09-15 15:19     ` [kernel-hardening] " Mark Rutland
2016-09-13 17:46 ` [PATCH v3 3/7] arm64: Introduce uaccess_{disable, enable} functionality based on TTBR0_EL1 Catalin Marinas
2016-09-13 17:46   ` [kernel-hardening] [PATCH v3 3/7] arm64: Introduce uaccess_{disable,enable} " Catalin Marinas
2016-09-13 20:45   ` Kees Cook
2016-09-13 20:45     ` [kernel-hardening] " Kees Cook
2016-09-14  8:52     ` Mark Rutland
2016-09-14  8:52       ` [kernel-hardening] " Mark Rutland
2016-09-14 16:27       ` Kees Cook
2016-09-14 16:27         ` Kees Cook
2016-09-13 17:46 ` [PATCH v3 4/7] arm64: Disable TTBR0_EL1 during normal kernel execution Catalin Marinas
2016-09-13 17:46   ` [kernel-hardening] " Catalin Marinas
2016-09-14 16:45   ` Will Deacon
2016-09-14 16:45     ` [kernel-hardening] " Will Deacon
2016-09-13 17:46 ` [PATCH v3 5/7] arm64: Handle faults caused by inadvertent user access with PAN enabled Catalin Marinas
2016-09-13 17:46   ` [kernel-hardening] " Catalin Marinas
2016-09-16 11:33   ` Mark Rutland
2016-09-16 11:33     ` [kernel-hardening] " Mark Rutland
2016-09-16 15:55     ` Catalin Marinas
2016-09-16 15:55       ` [kernel-hardening] " Catalin Marinas
2016-09-13 17:46 ` [PATCH v3 6/7] arm64: xen: Enable user access before a privcmd hvc call Catalin Marinas
2016-09-13 17:46   ` [kernel-hardening] " Catalin Marinas
2016-09-13 17:46 ` [PATCH v3 7/7] arm64: Enable CONFIG_ARM64_SW_TTBR0_PAN Catalin Marinas
2016-09-13 17:46   ` [kernel-hardening] " Catalin Marinas
2016-09-14 10:13 ` [PATCH v3 0/7] arm64: Privileged Access Never using TTBR0_EL1 switching Ard Biesheuvel
2016-09-14 10:13   ` [kernel-hardening] " Ard Biesheuvel
2016-09-14 10:27   ` Mark Rutland
2016-09-14 10:27     ` [kernel-hardening] " Mark Rutland
2016-09-14 10:30     ` Ard Biesheuvel
2016-09-14 10:30       ` [kernel-hardening] " Ard Biesheuvel
2016-09-14 10:36       ` Mark Rutland
2016-09-14 10:36         ` [kernel-hardening] " Mark Rutland
2016-09-14 10:48         ` Mark Rutland
2016-09-14 10:48           ` [kernel-hardening] " Mark Rutland
2016-09-14 20:54 ` [kernel-hardening] " David Brown
2016-09-14 20:54   ` David Brown
2016-09-15  9:52   ` Catalin Marinas
2016-09-15  9:52     ` Catalin Marinas
2016-09-15 16:20 ` Mark Rutland
2016-09-15 16:20   ` [kernel-hardening] " Mark Rutland
2016-09-15 16:41   ` Mark Rutland
2016-09-15 16:41     ` [kernel-hardening] " Mark Rutland
2016-09-29 22:44   ` Sami Tolvanen
2016-09-29 22:44     ` Sami Tolvanen
2016-09-30 18:42     ` Kees Cook
2016-09-30 18:42       ` Kees Cook
2016-10-27 14:54       ` Catalin Marinas
2016-10-27 14:54         ` Catalin Marinas
2016-10-27 21:23         ` Kees Cook [this message]
2016-10-27 21:23           ` Kees Cook
2016-10-14 21:44 ` Kees Cook
2016-10-14 21:44   ` [kernel-hardening] " Kees Cook
2016-10-15 14:35   ` Catalin Marinas
2016-10-15 14:35     ` [kernel-hardening] " Catalin Marinas
2016-10-16  2:04     ` Kees Cook
2016-10-16  2:04       ` [kernel-hardening] " Kees Cook

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='CAGXu5jL9=DKZSdOHh9gUqn5y478p7dwbVRFoQv5op5v8wLWBRw@mail.gmail.com' \
    --to=keescook@chromium.org \
    --cc=linux-arm-kernel@lists.infradead.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.