summaryrefslogtreecommitdiff
path: root/drivers/misc/habanalabs/common/command_buffer.c
diff options
context:
space:
mode:
authorTomer Tayar <ttayar@habana.ai>2022-11-23 16:09:43 +0300
committerOded Gabbay <ogabbay@kernel.org>2023-01-26 11:56:20 +0300
commit6003cb46e661e134e9e1f1449a6ea77d1e4ba6a9 (patch)
tree08f0d797060686dd52392527edf57f2462da4774 /drivers/misc/habanalabs/common/command_buffer.c
parent6710444cfeb533f8c7817c7ec1adfb52206a6d00 (diff)
downloadlinux-6003cb46e661e134e9e1f1449a6ea77d1e4ba6a9.tar.xz
habanalabs: don't allow user to destroy CB handle more than once
The refcount of a CB buffer is initialized when user allocates a CB, and is decreased when he destroys the CB handle. If this refcount is increased also from kernel and user sends more than one destroy requests for the handle, the buffer will be released/freed and later be accessed when the refcount is put from kernel side. To avoid it, prevent user from destroying the handle more than once. Signed-off-by: Tomer Tayar <ttayar@habana.ai> Reviewed-by: Oded Gabbay <ogabbay@kernel.org> Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
Diffstat (limited to 'drivers/misc/habanalabs/common/command_buffer.c')
-rw-r--r--drivers/misc/habanalabs/common/command_buffer.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/misc/habanalabs/common/command_buffer.c b/drivers/misc/habanalabs/common/command_buffer.c
index 2b332991ac6a..24100501f8ca 100644
--- a/drivers/misc/habanalabs/common/command_buffer.c
+++ b/drivers/misc/habanalabs/common/command_buffer.c
@@ -298,9 +298,31 @@ int hl_cb_create(struct hl_device *hdev, struct hl_mem_mgr *mmg,
int hl_cb_destroy(struct hl_mem_mgr *mmg, u64 cb_handle)
{
+ struct hl_cb *cb;
int rc;
+ /* Make sure that a CB handle isn't destroyed by user more than once */
+ if (!mmg->is_kernel_mem_mgr) {
+ cb = hl_cb_get(mmg, cb_handle);
+ if (!cb) {
+ dev_dbg(mmg->dev, "CB destroy failed, no CB was found for handle %#llx\n",
+ cb_handle);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ rc = atomic_cmpxchg(&cb->is_handle_destroyed, 0, 1);
+ hl_cb_put(cb);
+ if (rc) {
+ dev_dbg(mmg->dev, "CB destroy failed, handle %#llx was already destroyed\n",
+ cb_handle);
+ rc = -EINVAL;
+ goto out;
+ }
+ }
+
rc = hl_mmap_mem_buf_put_handle(mmg, cb_handle);
+out:
if (rc < 0)
return rc; /* Invalid handle */