msm: kgsl: Signal fence only if last fence refcount was not put
Currently there is a chance that release for the fence was already called before we call dma_fence_get during kgsl_timeline_signal and kgsl_ioctl_timeline_destroy. This can cause use-after-free issue as we can access fence after release. Fix this by signalling fence only if the last refcount on the fence was not yet put. This makes sure that release for the fence will not be called until we are done signalling. Change-Id: I6bdcefa1f128febb7a0f7aef133757268a3b9ae3 Signed-off-by: Puranam V G Tejaswi <pvgtejas@codeaurora.org> Signed-off-by: Pranav Patel <quic_pranavp@quicinc.com>
This commit is contained in:
parent
e904060a40
commit
2959ed5eb8
1 changed files with 5 additions and 6 deletions
|
@ -270,12 +270,10 @@ void kgsl_timeline_signal(struct kgsl_timeline *timeline, u64 seqno)
|
|||
timeline->value = seqno;
|
||||
|
||||
spin_lock(&timeline->fence_lock);
|
||||
list_for_each_entry_safe(fence, tmp, &timeline->fences, node) {
|
||||
if (timeline_fence_signaled(&fence->base)) {
|
||||
dma_fence_get(&fence->base);
|
||||
list_for_each_entry_safe(fence, tmp, &timeline->fences, node)
|
||||
if (timeline_fence_signaled(&fence->base) &&
|
||||
kref_get_unless_zero(&fence->base.refcount))
|
||||
list_move(&fence->node, &temp);
|
||||
}
|
||||
}
|
||||
spin_unlock(&timeline->fence_lock);
|
||||
|
||||
list_for_each_entry_safe(fence, tmp, &temp, node) {
|
||||
|
@ -548,7 +546,8 @@ long kgsl_ioctl_timeline_destroy(struct kgsl_device_private *dev_priv,
|
|||
|
||||
spin_lock(&timeline->fence_lock);
|
||||
list_for_each_entry_safe(fence, tmp, &timeline->fences, node)
|
||||
dma_fence_get(&fence->base);
|
||||
if (!kref_get_unless_zero(&fence->base.refcount))
|
||||
list_del_init(&fence->node);
|
||||
list_replace_init(&timeline->fences, &temp);
|
||||
spin_unlock(&timeline->fence_lock);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue