History

tee: handle lookup of shm with reference count 0

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.

Jens Wiklander committed 4 years ago

Commit dfd07431 parent d58071a2 files · +68 −110Browse files

Showing the changes to include/linux (1 of 2 files). Show all

Unified · Split

include/linux/tee_drv.h+2−2
@@ -195,7 +195,7 @@ int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method, · 194 unmodified lines
195 * @offset: offset of buffer in user space195 * @offset: offset of buffer in user space
196 * @pages: locked pages from userspace196 * @pages: locked pages from userspace
197 * @num_pages: number of locked pages197 * @num_pages: number of locked pages
198 * @dmabuf: dmabuf used to for exporting to user space198 * @refcount: reference counter
199 * @flags: defined by TEE_SHM_* in tee_drv.h199 * @flags: defined by TEE_SHM_* in tee_drv.h
200 * @id: unique id of a shared memory object on this device, shared200 * @id: unique id of a shared memory object on this device, shared
201 * with user space201 * with user space
@@ -214,7 +214,7 @@ struct tee_shm { · 12 unmodified lines
214 unsigned int offset;214 unsigned int offset;
215 struct page **pages;215 struct page **pages;
216 size_t num_pages;216 size_t num_pages;
217 struct dma_buf *dmabuf;217 refcount_t refcount;
218 u32 flags;218 u32 flags;
219 int id;219 int id;
220 u64 sec_world_id;220 u64 sec_world_id;