From 6a95d0b74c2951f0dc82361ea279f64a7349f060 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 1 Nov 2011 13:07:41 -0700 Subject: [PATCH] Fix NULL deref in balance_pgdat() 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: [] balance_pgdat+0x25b/0x4ff Signed-off-by: Brian Behlendorf Issue #287 --- module/zfs/zpl_file.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c index af46afddf..298c0b62d 100644 --- a/module/zfs/zpl_file.c +++ b/module/zfs/zpl_file.c @@ -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); }