mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
UPSTREAM: arm64: Validate tagged addresses in access_ok() called from kernel threads
(Upstream commitdf325e05a6). __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:63f0c60379("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> Tested-by: Evgenii Stepanov <eugenis@google.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Andrey Konovalov <andreyknvl@google.com> Change-Id: Icfb58d6e03a85409b98a97bb570c8608cac4a3b1 Bug: 135692346
This commit is contained in:
committed by
Todd Kjos
parent
b3ddf584b0
commit
436ded39cc
@@ -76,8 +76,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);
|
||||
|
||||
Reference in New Issue
Block a user