Message ID | 20191205181258.27334-1-catalin.marinas@arm.com (mailing list archive) |
---|---|
State | Mainlined |
Commit | df325e05a682e9c624f471835c35bd3f870d5e8c |
Headers | show |
Series | arm64: Validate tagged addresses in access_ok() called from kernel threads | expand |
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);
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);
__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(-)