commit dfd0743f1d upstream.
Since the tee subsystem does not keep a strong reference to its idle
shared memory buffers, it races with other threads that try to destroy a
shared memory through a close of its dma-buf fd or by unmapping the
memory.
In tee_shm_get_from_id() when a lookup in teedev->idr has been
successful, it is possible that the tee_shm is in the dma-buf teardown
path, but that path is blocked by the teedev mutex. Since we don't have
an API to tell if the tee_shm is in the dma-buf teardown path or not we
must find another way of detecting this condition.
Fix this by doing the reference counting directly on the tee_shm using a
new refcount_t refcount field. dma-buf is replaced by using
anon_inode_getfd() instead, this separates the life-cycle of the
underlying file from the tee_shm. tee_shm_put() is updated to hold the
mutex when decreasing the refcount to 0 and then remove the tee_shm from
teedev->idr before releasing the mutex. This means that the tee_shm can
never be found unless it has a refcount larger than 0.
Fixes: 967c9cca2c ("tee: generic TEE subsystem")
Cc: stable@vger.kernel.org
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Lars Persson <larper@axis.com>
Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Reported-by: Patrik Lantz <patrik.lantz@axis.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Currently TEE_SHM_DMA_BUF flag has been inappropriately used to not
register shared memory allocated for private usage by underlying TEE
driver: OP-TEE in this case. So rather add a new flag as TEE_SHM_PRIV
that can be utilized by underlying TEE drivers for private allocation
and usage of shared memory.
With this corrected, allow tee_shm_alloc_kernel_buf() to allocate a
shared memory region without the backing of dma-buf.
Cc: stable@vger.kernel.org
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Co-developed-by: Tyler Hicks <tyhicks@linux.microsoft.com>
Signed-off-by: Tyler Hicks <tyhicks@linux.microsoft.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Adds a new function tee_shm_alloc_kernel_buf() to allocate shared memory
from a kernel driver. This function can later be made more lightweight
by unnecessary dma-buf export.
Cc: stable@vger.kernel.org
Reviewed-by: Tyler Hicks <tyhicks@linux.microsoft.com>
Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
This code was using get_user_pages*(), in a "Case 2" scenario
(DMA/RDMA), using the categorization from [1]. That means that it's
time to convert the get_user_pages*() + put_page() calls to
pin_user_pages*() + unpin_user_pages() calls.
Factor out a new, small release_registered_pages() function, in
order to consolidate the logic for discerning between
TEE_SHM_USER_MAPPED and TEE_SHM_KERNEL_MAPPED pages. This also
absorbs the kfree() call that is also required there.
There is some helpful background in [2]: basically, this is a small
part of fixing a long-standing disconnect between pinning pages, and
file systems' use of those pages.
[1] Documentation/core-api/pin_user_pages.rst
[2] "Explicit pinning of user-space pages":
https://lwn.net/Articles/807108/
Cc: Jens Wiklander <jens.wiklander@linaro.org>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: tee-dev@lists.linaro.org
Cc: linux-media@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linaro-mm-sig@lists.linaro.org
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Enable support to register kernel memory reference with TEE. This change
will allow TEE bus drivers to register memory references.
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Smatch complains that "ctx" isn't checked consistently:
drivers/tee/tee_shm.c:164 tee_shm_alloc()
warn: variable dereferenced before check 'ctx' (see line 95)
I audited the callers and "ctx" can't be NULL so the check can be
removed.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
tee_shm_op_mmap() uses the TEE_SHM_USER_MAPPED flag instead of the
TEE_SHM_REGISTER flag to tell if a shared memory object is originating
from registered user space memory.
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
The ctx element in struct tee_shm is always valid. So remove the now
redundant teedev element.
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Private shared memory object must not be referenced from user space. To
guarantee that, don't assign an id to shared memory objects which are
driver private.
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
tee_shm_priv_alloc() isn't useful in the current state and it's also not
not used so remove it.
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
This patch is a part of a series that extends kernel ABI to allow to pass
tagged user pointers (with the top byte set to something else other than
0x00) as syscall arguments.
tee_shm_register()->optee_shm_unregister()->check_mem_type() uses provided
user pointers for vma lookups (via __check_mem_type()), which can only by
done with untagged pointers.
Untag user pointers in this function.
Link: http://lkml.kernel.org/r/4b993f33196b3566ac81285ff8453219e2079b45.1563904656.git.andreyknvl@google.com
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Felix Kuehling <Felix.Kuehling@amd.com>
Cc: Khalid Aziz <khalid.aziz@oracle.com>
Cc: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Cc: Mike Rapoport <rppt@linux.ibm.com>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Based on 1 normalized pattern(s):
this software is licensed under the terms of the gnu general public
license version 2 as published by the free software foundation and
may be copied distributed and modified under those terms this
program is distributed in the hope that it will be useful but
without any warranty without even the implied warranty of
merchantability or fitness for a particular purpose see the gnu
general public license for more details
extracted by the scancode license scanner the SPDX license identifier
GPL-2.0-only
has been chosen to replace the boilerplate/reference in 285 file(s).
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Alexios Zavras <alexios.zavras@intel.com>
Reviewed-by: Allison Randal <allison@lohutok.net>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190529141900.642774971@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To facilitate additional options to get_user_pages_fast() change the
singular write parameter to be gup_flags.
This patch does not change any functionality. New functionality will
follow in subsequent patches.
Some of the get_user_pages_fast() call sites were unchanged because they
already passed FOLL_WRITE or 0 for the write parameter.
NOTE: It was suggested to change the ordering of the get_user_pages_fast()
arguments to ensure that callers were converted. This breaks the current
GUP call site convention of having the returned pages be the final
parameter. So the suggestion was rejected.
Link: http://lkml.kernel.org/r/20190328084422.29911-4-ira.weiny@intel.com
Link: http://lkml.kernel.org/r/20190317183438.2057-4-ira.weiny@intel.com
Signed-off-by: Ira Weiny <ira.weiny@intel.com>
Reviewed-by: Mike Marshall <hubcap@omnibond.com>
Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Hogan <jhogan@kernel.org>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Rich Felker <dalias@libc.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Neither used nor correctly implemented anywhere. Just completely remove
the interface.
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Sumit Semwal <sumit.semwal@linaro.org>
Link: https://patchwork.freedesktop.org/patch/226645/
Bump the file's refcount before moving the reference into the fd table,
not afterwards. The old code could drop the file's refcount to zero for a
short moment before calling get_file() via get_dma_buf().
This code can only be triggered on ARM systems that use Linaro's OP-TEE.
Fixes: 967c9cca2c ("tee: generic TEE subsystem")
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
get_user_pages_fast() can return zero in certain error paths. We should
handle that or else it means we accidentally return ERR_PTR(0) which is
NULL instead of an error pointer. The callers are not expecting that
and will crash with a NULL dereference.
Fixes: 033ddf12bc ("tee: add register user memory")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
In the case that shm->pages fails to allocate, the current exit
error path will try to put_page on a null shm->pages and cause
a null pointer dereference when accessing shm->pages[n]. Fix this
by only performing the put_page and kfree on shm->pages if it
is not null.
Detected by CoverityScan, CID#1463283 ("Dereference after null check")
Fixes: 033ddf12bc ("tee: add register user memory")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
The function __tee_shm_alloc is local to the source and does
not need to be in global scope, so make it static.
Cleans up sparse warning:
symbol '__tee_shm_alloc' was not declared. Should it be static?
Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Adds a start argument to the shm_register callback to allow the callback
to check memory type of the passed pages.
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Now, when struct tee_shm is defined in public header,
we can inline small getter functions like this one.
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
We need to ensure that tee_context is present until last
shared buffer will be freed.
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Added new ioctl to allow users register own buffers as a shared memory.
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
[jw: moved tee_shm_is_registered() declaration]
[jw: added space after __tee_shm_alloc() implementation]
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Makes creation of shm pools more flexible by adding new more primitive
functions to allocate a shm pool. This makes it easier to add driver
specific shm pool management.
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
dma_buf_ops are not supposed to change at runtime. All functions
working with dma_buf_ops provided by <linux/dma-buf.h> work with
const dma_buf_ops. So mark the non-const structs as const.
File size before:
text data bss dec hex filename
2026 112 0 2138 85a drivers/tee/tee_shm.o
File size After adding 'const':
text data bss dec hex filename
2138 0 0 2138 85a drivers/tee/tee_shm.o
Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
This branch introduces a generic TEE framework in the kernel, to handle
trusted environemtns (security coprocessor or software implementations
such as OP-TEE/TrustZone). I'm sending it separately from the other
arm-soc driver changes to give it a little more visibility, once
the subsystem is merged, we will likely keep this in the arm₋soc
drivers branch or have the maintainers submit pull requests directly,
depending on the patch volume.
I have reviewed earlier versions in the past, and have reviewed
the latest version in person during Linaro Connect BUD17.
Here is my overall assessment of the subsystem:
* There is clearly demand for this, both for the generic
infrastructure and the specific OP-TEE implementation.
* The code has gone through a large number of reviews,
and the review comments have all been addressed, but
the reviews were not coming up with serious issues any more
and nobody volunteered to vouch for the quality.
* The user space ioctl interface is sufficient to work with the
OP-TEE driver, and it should in principle work with other
TEE implementations that follow the GlobalPlatform[1] standards,
but it might need to be extended in minor ways depending on
specific requirements of future TEE implementations
* The main downside of the API to me is how the user space
is tied to the TEE implementation in hardware or firmware,
but uses a generic way to communicate with it. This seems
to be an inherent problem with what it is trying to do,
and I could not come up with any better solution than what
is implemented here.
For a detailed history of the patch series, see
https://lkml.org/lkml/2017/3/10/1277
Conflicts: needs a fixup after the drm tree was merged, see
https://patchwork.kernel.org/patch/9691679/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIVAwUAWRIRzWCrR//JCVInAQLKUhAAiJaBqb4uv5wDWKw8MVV5BbFjq6po/eMK
r3lgwyBGoRnrYiXo0z2eYNqpHsmNIGrL21qYMzaBGhVeaOOVPZT4q3zH+Se9Oo+J
HHZZ4J6Q9kDIUy9WkM7ybHVj3C0kQIn7H+/6zi2L97tMQJMZHI0jCSgDa6XPqHzh
G/vqVx5jlaFj6SvkLR0L0yWTe0wXTHoyObSCWsM/nV8AiTNhMD3kcTEOm0XHcAJB
k8ei/Pw2INOFZu1B0xpoRkWoAo6YKMcxQp9kiMkcEhChPIkNK+8+npYJ3fiogsii
BVTXC9Km2jmUfQ21Pegd2XbqzNGU1rJSdHGTyK2Oax+0J+C8xElGMs8U9tqXPqun
fWkSp0dl7Sk0f9Yhc8JBD1Tsbuo0H+TsMtQ6RNvlxLiNHE/5/bZBCeylvtoUyI+m
NcvP0x5QeBmkitz7zhYpjaSv5HjZG3PPO3pfaz0Stmen5ZM8DWB1TaS1Nn9MigHt
RGXlafc6dKybQQBLWDwStv7IkqDRYte+7pwmx+QFCRWj8+uFtTCDPLyaDUTwlErL
n4ztUL1RWiq48S+yJDJURM4mLpEMnJFFF4tiiHH8eUe2JE+CXwGxkT6BG62W71Oy
RosiJ84LmdoHRyHx6xmqpoDcL1WG57IgWt05SRUkQatA/ealGX88gguGEAWsPL0h
cnKPYkiYfug=
=VzpB
-----END PGP SIGNATURE-----
Merge tag 'armsoc-tee' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull TEE driver infrastructure and OP-TEE drivers from Arnd Bergmann:
"This introduces a generic TEE framework in the kernel, to handle
trusted environemtns (security coprocessor or software implementations
such as OP-TEE/TrustZone). I'm sending it separately from the other
arm-soc driver changes to give it a little more visibility, once the
subsystem is merged, we will likely keep this in the arm₋soc drivers
branch or have the maintainers submit pull requests directly,
depending on the patch volume.
I have reviewed earlier versions in the past, and have reviewed the
latest version in person during Linaro Connect BUD17.
Here is my overall assessment of the subsystem:
- There is clearly demand for this, both for the generic
infrastructure and the specific OP-TEE implementation.
- The code has gone through a large number of reviews, and the review
comments have all been addressed, but the reviews were not coming
up with serious issues any more and nobody volunteered to vouch for
the quality.
- The user space ioctl interface is sufficient to work with the
OP-TEE driver, and it should in principle work with other TEE
implementations that follow the GlobalPlatform[1] standards, but it
might need to be extended in minor ways depending on specific
requirements of future TEE implementations
- The main downside of the API to me is how the user space is tied to
the TEE implementation in hardware or firmware, but uses a generic
way to communicate with it. This seems to be an inherent problem
with what it is trying to do, and I could not come up with any
better solution than what is implemented here.
For a detailed history of the patch series, see
https://lkml.org/lkml/2017/3/10/1277"
* tag 'armsoc-tee' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc:
arm64: dt: hikey: Add optee node
Documentation: tee subsystem and op-tee driver
tee: add OP-TEE driver
tee: generic TEE subsystem
dt/bindings: add bindings for optee
Initial patch for generic TEE subsystem.
This subsystem provides:
* Registration/un-registration of TEE drivers.
* Shared memory between normal world and secure world.
* Ioctl interface for interaction with user space.
* Sysfs implementation_id of TEE driver
A TEE (Trusted Execution Environment) driver is a driver that interfaces
with a trusted OS running in some secure environment, for example,
TrustZone on ARM cpus, or a separate secure co-processor etc.
The TEE subsystem can serve a TEE driver for a Global Platform compliant
TEE, but it's not limited to only Global Platform TEEs.
This patch builds on other similar implementations trying to solve
the same problem:
* "optee_linuxdriver" by among others
Jean-michel DELORME<jean-michel.delorme@st.com> and
Emmanuel MICHEL <emmanuel.michel@st.com>
* "Generic TrustZone Driver" by Javier González <javier@javigon.com>
Acked-by: Andreas Dannenberg <dannenberg@ti.com>
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (HiKey)
Tested-by: Volodymyr Babchuk <vlad.babchuk@gmail.com> (RCAR H3)
Tested-by: Scott Branden <scott.branden@broadcom.com>
Reviewed-by: Javier González <javier@javigon.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>