]> git.proxmox.com Git - mirror_zfs-debian.git/commitdiff
Fix NULL deref in balance_pgdat()
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 1 Nov 2011 20:07:41 +0000 (13:07 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 3 Nov 2011 17:15:39 +0000 (10:15 -0700)
Be careful not to unconditionally clear the PF_MEMALLOC bit in
the task structure.  It may have already been set when entering
zpl_putpage() in which case it must remain set on exit.  In
particular the kswapd thread will have PF_MEMALLOC set in
order to prevent it from entering direct reclaim.  By clearing
it we allow the following NULL deref to potentially occur.

  BUG: unable to handle kernel NULL pointer dereference at (null)
  IP: [<ffffffff8109c7ab>] balance_pgdat+0x25b/0x4ff

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #287

module/zfs/zpl_file.c

index af46afddfbbcf0ffcc255d4b40c2ad4fa2b89424..298c0b62df751dcc7ad13c380ef43b2b28a9d70d 100644 (file)
@@ -324,9 +324,13 @@ zpl_putpage(struct page *pp, struct writeback_control *wbc, void *data)
         * the VM might try to write out additional pages by calling
         * zpl_putpage() again resulting in a deadlock.
         */
-       current->flags |= PF_MEMALLOC;
-       (void) zfs_putpage(mapping->host, pp, wbc);
-       current->flags &= ~PF_MEMALLOC;
+       if (current->flags & PF_MEMALLOC) {
+               (void) zfs_putpage(mapping->host, pp, wbc);
+       } else {
+               current->flags |= PF_MEMALLOC;
+               (void) zfs_putpage(mapping->host, pp, wbc);
+               current->flags &= ~PF_MEMALLOC;
+       }
 
        return (0);
 }