gru: fix potential use-after-free when purging GRU tlbs
authorJack Steiner <steiner@sgi.com>
Wed, 17 Jun 2009 23:28:33 +0000 (16:28 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 18 Jun 2009 20:04:04 +0000 (13:04 -0700)
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

index 1ad360cd3183286923732a3bef20ce8614871398..679e01778286029bf21299db49e6284ee001475f 100644 (file)
@@ -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;
 }