aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2015-09-04 18:44:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-04 19:54:41 -0400
commita068acf2ee77693e0bf39d6e07139ba704f461c3 (patch)
tree760636f774a9ad528168fa7ceaaf34529167b085 /fs/gfs2
parent46359295a352e01a5a017297c70b7ee0c5da6de6 (diff)
fs: create and use seq_show_option for escaping
Many file systems that implement the show_options hook fail to correctly escape their output which could lead to unescaped characters (e.g. new lines) leaking into /proc/mounts and /proc/[pid]/mountinfo files. This could lead to confusion, spoofed entries (resulting in things like systemd issuing false d-bus "mount" notifications), and who knows what else. This looks like it would only be the root user stepping on themselves, but it's possible weird things could happen in containers or in other situations with delegated mount privileges. Here's an example using overlay with setuid fusermount trusting the contents of /proc/mounts (via the /etc/mtab symlink). Imagine the use of "sudo" is something more sneaky: $ BASE="ovl" $ MNT="$BASE/mnt" $ LOW="$BASE/lower" $ UP="$BASE/upper" $ WORK="$BASE/work/ 0 0 none /proc fuse.pwn user_id=1000" $ mkdir -p "$LOW" "$UP" "$WORK" $ sudo mount -t overlay -o "lowerdir=$LOW,upperdir=$UP,workdir=$WORK" none /mnt $ cat /proc/mounts none /root/ovl/mnt overlay rw,relatime,lowerdir=ovl/lower,upperdir=ovl/upper,workdir=ovl/work/ 0 0 none /proc fuse.pwn user_id=1000 0 0 $ fusermount -u /proc $ cat /proc/mounts cat: /proc/mounts: No such file or directory This fixes the problem by adding new seq_show_option and seq_show_option_n helpers, and updating the vulnerable show_option handlers to use them as needed. Some, like SELinux, need to be open coded due to unusual existing escape mechanisms. [akpm@linux-foundation.org: add lost chunk, per Kees] [keescook@chromium.org: seq_show_option should be using const parameters] Signed-off-by: Kees Cook <keescook@chromium.org> Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Acked-by: Jan Kara <jack@suse.com> Acked-by: Paul Moore <paul@paul-moore.com> Cc: J. R. Okajima <hooanon05g@gmail.com> Signed-off-by: Kees Cook <keescook@chromium.org> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/super.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 2982445947e1..894fb01a91da 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1334,11 +1334,11 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
1334 if (is_ancestor(root, sdp->sd_master_dir)) 1334 if (is_ancestor(root, sdp->sd_master_dir))
1335 seq_puts(s, ",meta"); 1335 seq_puts(s, ",meta");
1336 if (args->ar_lockproto[0]) 1336 if (args->ar_lockproto[0])
1337 seq_printf(s, ",lockproto=%s", args->ar_lockproto); 1337 seq_show_option(s, "lockproto", args->ar_lockproto);
1338 if (args->ar_locktable[0]) 1338 if (args->ar_locktable[0])
1339 seq_printf(s, ",locktable=%s", args->ar_locktable); 1339 seq_show_option(s, "locktable", args->ar_locktable);
1340 if (args->ar_hostdata[0]) 1340 if (args->ar_hostdata[0])
1341 seq_printf(s, ",hostdata=%s", args->ar_hostdata); 1341 seq_show_option(s, "hostdata", args->ar_hostdata);
1342 if (args->ar_spectator) 1342 if (args->ar_spectator)
1343 seq_puts(s, ",spectator"); 1343 seq_puts(s, ",spectator");
1344 if (args->ar_localflocks) 1344 if (args->ar_localflocks)