History

dma-buf/sw_sync: Synchronize signal vs syncpt free

During release of the syncpt, we remove it from the list of syncpt and the tree, but only if it is not already been removed. However, during signaling, we first remove the syncpt from the list. So, if we concurrently free and signal the syncpt, the free may decide that it is not part of the tree and immediately free itself -- meanwhile the signaler goes on to use the now freed datastructure. In particular, we get struck by commit 0e2f733addbf ("dma-buf: make dma_fence structure a bit smaller v2") as the cb_list is immediately clobbered by the kfree_rcu. v2: Avoid calling into timeline_fence_release() from under the spinlock

Chris Wilson committed 7 years ago

Commit d3c6dd11 parent 1c2b9391 file · +7 −9Browse files

Unified · Split

drivers/dma-buf/sw_sync.c+7−9
@@ -132,17 +132,14 @@ static void timeline_fence_release(struct dma_fence *fence) · 131 unmodified lines
132132 {
133133 struct sync_pt *pt = dma_fence_to_sync_pt(fence);
134134 struct sync_timeline *parent = dma_fence_parent(fence);
135+ unsigned long flags;
135136
137+ spin_lock_irqsave(fence->lock, flags);
136138 if (!list_empty(&pt->link)) {
137− unsigned long flags;
138−
139− spin_lock_irqsave(fence->lock, flags);
140− if (!list_empty(&pt->link)) {
141− list_del(&pt->link);
142− rb_erase(&pt->node, &parent->pt_tree);
143− }
144− spin_unlock_irqrestore(fence->lock, flags);
139+ list_del(&pt->link);
140+ rb_erase(&pt->node, &parent->pt_tree);
145141 }
142+ spin_unlock_irqrestore(fence->lock, flags);
146143
147144 sync_timeline_put(parent);
148145 dma_fence_free(fence);
@@ -265,7 +262,8 @@ static struct sync_pt *sync_pt_create(struct sync_timeline *obj, · 116 unmodified lines
265262 p = &parent->rb_left;
266263 } else {
267264 if (dma_fence_get_rcu(&other->base)) {
268− dma_fence_put(&pt->base);
265+ sync_timeline_put(obj);
266+ kfree(pt);
269267 pt = other;
270268 goto unlock;
271269 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t