1 From 5f00110f7273f9ff04ac69a5f85bb535a4fd0987 Mon Sep 17 00:00:00 2001
2 From: Greg Thelen <gthelen@google.com>
3 Date: Fri, 22 Feb 2013 16:36:01 -0800
4 Subject: tmpfs: fix use-after-free of mempolicy object
6 From: Greg Thelen <gthelen@google.com>
8 commit 5f00110f7273f9ff04ac69a5f85bb535a4fd0987 upstream.
10 The tmpfs remount logic preserves filesystem mempolicy if the mpol=M
11 option is not specified in the remount request. A new policy can be
12 specified if mpol=M is given.
14 Before this patch remounting an mpol bound tmpfs without specifying
15 mpol= mount option in the remount request would set the filesystem's
16 mempolicy object to a freed mempolicy object.
18 To reproduce the problem boot a DEBUG_PAGEALLOC kernel and run:
21 # mount -t tmpfs -o size=100M,mpol=interleave nodev /tmp/x
23 # grep /tmp/x /proc/mounts
24 nodev /tmp/x tmpfs rw,relatime,size=102400k,mpol=interleave:0-3 0 0
26 # mount -o remount,size=200M nodev /tmp/x
28 # grep /tmp/x /proc/mounts
29 nodev /tmp/x tmpfs rw,relatime,size=204800k,mpol=??? 0 0
30 # note ? garbage in mpol=... output above
32 # dd if=/dev/zero of=/tmp/x/f count=1
36 BUG: unable to handle kernel NULL pointer dereference at (null)
37 IP: [< (null)>] (null)
39 Oops: 0010 [#1] SMP DEBUG_PAGEALLOC
41 mpol_shared_policy_init+0xa5/0x160
42 shmem_get_inode+0x209/0x270
44 shmem_create+0x18/0x20
47 path_openat+0xb3/0x4d0
48 do_filp_open+0x42/0xa0
49 do_sys_open+0xfe/0x1e0
50 compat_sys_open+0x1b/0x20
51 cstar_dispatch+0x7/0x1f
53 Non-debug kernels will not crash immediately because referencing the
54 dangling mpol will not cause a fault. Instead the filesystem will
55 reference a freed mempolicy object, which will cause unpredictable
58 The problem boils down to a dropped mpol reference below if
59 shmem_parse_options() does not allocate a new mpol:
62 shmem_parse_options(data, &config, true)
63 mpol_put(sbinfo->mpol)
64 sbinfo->mpol = config.mpol /* BUG: saves unreferenced mpol */
66 This patch avoids the crash by not releasing the mempolicy if
67 shmem_parse_options() doesn't create a new mpol.
69 How far back does this issue go? I see it in both 2.6.36 and 3.3. I did
70 not look back further.
72 Signed-off-by: Greg Thelen <gthelen@google.com>
73 Acked-by: Hugh Dickins <hughd@google.com>
74 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
75 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
76 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
79 mm/shmem.c | 10 ++++++++--
80 1 file changed, 8 insertions(+), 2 deletions(-)
84 @@ -2397,6 +2397,7 @@ static int shmem_remount_fs(struct super
89 if (shmem_parse_options(data, &config, true))
92 @@ -2421,8 +2422,13 @@ static int shmem_remount_fs(struct super
93 sbinfo->max_inodes = config.max_inodes;
94 sbinfo->free_inodes = config.max_inodes - inodes;
96 - mpol_put(sbinfo->mpol);
97 - sbinfo->mpol = config.mpol; /* transfers initial ref */
99 + * Preserve previous mempolicy unless mpol remount option was specified.
102 + mpol_put(sbinfo->mpol);
103 + sbinfo->mpol = config.mpol; /* transfers initial ref */
106 spin_unlock(&sbinfo->stat_lock);