From 1926ee85a903d189c5702eed6531be321e33eb47 Mon Sep 17 00:00:00 2001 From: Jack Steiner <steiner@sgi.com> Date: Wed, 17 Jun 2009 16:28:33 -0700 Subject: gru: fix potential use-after-free when purging GRU tlbs Fix potential SGI GRU bug that could cause a use-after-free. If one thread in a task is flushing the GRU and another thread destroys the GRU context, there is the potential to access a table after it has been freed. Copy the gms pointer to a local variable before unlocking the gts table. Note that no refcnt is needed for the gms - the reference is held indirectly by the task's mm_struct. Signed-off-by: Jack Steiner <steiner@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> --- drivers/misc/sgi-gru/grufault.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c index 1ad360cd3183..679e01778286 100644 --- a/drivers/misc/sgi-gru/grufault.c +++ b/drivers/misc/sgi-gru/grufault.c @@ -702,6 +702,7 @@ int gru_user_flush_tlb(unsigned long arg) { struct gru_thread_state *gts; struct gru_flush_tlb_req req; + struct gru_mm_struct *gms; STAT(user_flush_tlb); if (copy_from_user(&req, (void __user *)arg, sizeof(req))) @@ -714,8 +715,9 @@ int gru_user_flush_tlb(unsigned long arg) if (!gts) return -EINVAL; - gru_flush_tlb_range(gts->ts_gms, req.vaddr, req.len); + gms = gts->ts_gms; gru_unlock_gts(gts); + gru_flush_tlb_range(gms, req.vaddr, req.len); return 0; } -- cgit v1.2.3