All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] arm64: Validate tagged addresses in access_ok() called from kernel threads
@ 2019-12-05 18:12 Catalin Marinas
  2019-12-06 16:36 ` Evgenii Stepanov
  0 siblings, 1 reply; 2+ messages in thread
From: Catalin Marinas @ 2019-12-05 18:12 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Will Deacon, Evgenii Stepanov

__range_ok(), invoked from access_ok(), clears the tag of the user
address only if CONFIG_ARM64_TAGGED_ADDR_ABI is enabled and the thread
opted in to the relaxed ABI. The latter sets the TIF_TAGGED_ADDR thread
flag. In the case of asynchronous I/O (e.g. io_submit()), the
access_ok() may be called from a kernel thread. Since kernel threads
don't have TIF_TAGGED_ADDR set, access_ok() will fail for valid tagged
user addresses. Example from the ffs_user_copy_worker() thread:

	use_mm(io_data->mm);
	ret = ffs_copy_to_iter(io_data->buf, ret, &io_data->data);
	unuse_mm(io_data->mm);

Relax the __range_ok() check to always untag the user address if called
in the context of a kernel thread. The user pointers would have already
been checked via aio_setup_rw() -> import_{single_range,iovec}() at the
time of the asynchronous I/O request.

Fixes: 63f0c6037965 ("arm64: Introduce prctl() options to control the tagged user addresses ABI")
Cc: <stable@vger.kernel.org> # 5.4.x-
Cc: Will Deacon <will@kernel.org>
Reported-by: Evgenii Stepanov <eugenis@google.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/uaccess.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 097d6bfac0b7..cccb03e1ab1f 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -62,8 +62,13 @@ static inline unsigned long __range_ok(const void __user *addr, unsigned long si
 {
 	unsigned long ret, limit = current_thread_info()->addr_limit;
 
+	/*
+	 * Asynchronous I/O running in a kernel thread does not have the
+	 * TIF_TAGGED_ADDR flag of the process owning the mm, so always untag
+	 * the user address before checking.
+	 */
 	if (IS_ENABLED(CONFIG_ARM64_TAGGED_ADDR_ABI) &&
-	    test_thread_flag(TIF_TAGGED_ADDR))
+	    (current->flags & PF_KTHREAD || test_thread_flag(TIF_TAGGED_ADDR)))
 		addr = untagged_addr(addr);
 
 	__chk_user_ptr(addr);

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

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] arm64: Validate tagged addresses in access_ok() called from kernel threads
  2019-12-05 18:12 [PATCH] arm64: Validate tagged addresses in access_ok() called from kernel threads Catalin Marinas
@ 2019-12-06 16:36 ` Evgenii Stepanov
  0 siblings, 0 replies; 2+ messages in thread
From: Evgenii Stepanov @ 2019-12-06 16:36 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: Will Deacon, Linux ARM

I can confirm that this patch fixes the issue. Thank you!

Tested-by: Evgenii Stepanov <eugenis@google.com>


On Thu, Dec 5, 2019 at 10:13 AM Catalin Marinas <catalin.marinas@arm.com> wrote:
>
> __range_ok(), invoked from access_ok(), clears the tag of the user
> address only if CONFIG_ARM64_TAGGED_ADDR_ABI is enabled and the thread
> opted in to the relaxed ABI. The latter sets the TIF_TAGGED_ADDR thread
> flag. In the case of asynchronous I/O (e.g. io_submit()), the
> access_ok() may be called from a kernel thread. Since kernel threads
> don't have TIF_TAGGED_ADDR set, access_ok() will fail for valid tagged
> user addresses. Example from the ffs_user_copy_worker() thread:
>
>         use_mm(io_data->mm);
>         ret = ffs_copy_to_iter(io_data->buf, ret, &io_data->data);
>         unuse_mm(io_data->mm);
>
> Relax the __range_ok() check to always untag the user address if called
> in the context of a kernel thread. The user pointers would have already
> been checked via aio_setup_rw() -> import_{single_range,iovec}() at the
> time of the asynchronous I/O request.
>
> Fixes: 63f0c6037965 ("arm64: Introduce prctl() options to control the tagged user addresses ABI")
> Cc: <stable@vger.kernel.org> # 5.4.x-
> Cc: Will Deacon <will@kernel.org>
> Reported-by: Evgenii Stepanov <eugenis@google.com>
> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> ---
>  arch/arm64/include/asm/uaccess.h | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
> index 097d6bfac0b7..cccb03e1ab1f 100644
> --- a/arch/arm64/include/asm/uaccess.h
> +++ b/arch/arm64/include/asm/uaccess.h
> @@ -62,8 +62,13 @@ static inline unsigned long __range_ok(const void __user *addr, unsigned long si
>  {
>         unsigned long ret, limit = current_thread_info()->addr_limit;
>
> +       /*
> +        * Asynchronous I/O running in a kernel thread does not have the
> +        * TIF_TAGGED_ADDR flag of the process owning the mm, so always untag
> +        * the user address before checking.
> +        */
>         if (IS_ENABLED(CONFIG_ARM64_TAGGED_ADDR_ABI) &&
> -           test_thread_flag(TIF_TAGGED_ADDR))
> +           (current->flags & PF_KTHREAD || test_thread_flag(TIF_TAGGED_ADDR)))
>                 addr = untagged_addr(addr);
>
>         __chk_user_ptr(addr);

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

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-12-06 16:36 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-05 18:12 [PATCH] arm64: Validate tagged addresses in access_ok() called from kernel threads Catalin Marinas
2019-12-06 16:36 ` Evgenii Stepanov

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.