Skip to content

Commit

Permalink
Fix NULL deref in balance_pgdat()
Browse files Browse the repository at this point in the history
Be careful not to unconditionally clear the PF_MEMALLOC bit in
the task structure.  It may have already been set when entering
kv_alloc() 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 <[email protected]>
Closes ZFS issue #287
  • Loading branch information
behlendorf committed Nov 3, 2011
1 parent 16952a6 commit b8b6e4c
Showing 1 changed file with 8 additions and 5 deletions.
13 changes: 8 additions & 5 deletions module/spl/spl-kmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -855,14 +855,17 @@ kv_alloc(spl_kmem_cache_t *skc, int size, int flags)
* been filed at kernel.org to track the issue.
*
* https://bugzilla.kernel.org/show_bug.cgi?id=30702
*
* NOTE: Only set PF_MEMALLOC if it's not already set, and
* then only clear it when we were the one who set it.
*/
if (!(flags & __GFP_FS))
if (!(flags & __GFP_FS) && !(current->flags & PF_MEMALLOC)) {
current->flags |= PF_MEMALLOC;

ptr = __vmalloc(size, flags | __GFP_HIGHMEM, PAGE_KERNEL);

if (!(flags & __GFP_FS))
ptr = __vmalloc(size, flags|__GFP_HIGHMEM, PAGE_KERNEL);
current->flags &= ~PF_MEMALLOC;
} else {
ptr = __vmalloc(size, flags|__GFP_HIGHMEM, PAGE_KERNEL);
}
}

/* Resulting allocated memory will be page aligned */
Expand Down

0 comments on commit b8b6e4c

Please sign in to comment.