summaryrefslogtreecommitdiffstats
path: root/target/linux/generic/patches-4.4/051-0006-ovl-listxattr-use-strnlen.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/patches-4.4/051-0006-ovl-listxattr-use-strnlen.patch')
-rw-r--r--target/linux/generic/patches-4.4/051-0006-ovl-listxattr-use-strnlen.patch53
1 files changed, 53 insertions, 0 deletions
diff --git a/target/linux/generic/patches-4.4/051-0006-ovl-listxattr-use-strnlen.patch b/target/linux/generic/patches-4.4/051-0006-ovl-listxattr-use-strnlen.patch
new file mode 100644
index 0000000000..82ad20db4c
--- /dev/null
+++ b/target/linux/generic/patches-4.4/051-0006-ovl-listxattr-use-strnlen.patch
@@ -0,0 +1,53 @@
+From 7cb35119d067191ce9ebc380a599db0b03cbd9d9 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Thu, 1 Sep 2016 11:12:00 +0200
+Subject: [PATCH] ovl: listxattr: use strnlen()
+
+Be defensive about what underlying fs provides us in the returned xattr
+list buffer. If it's not properly null terminated, bail out with a warning
+insead of BUG.
+
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Cc: <stable@vger.kernel.org>
+---
+ fs/overlayfs/inode.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -277,7 +277,8 @@ ssize_t ovl_listxattr(struct dentry *den
+ struct path realpath;
+ enum ovl_path_type type = ovl_path_real(dentry, &realpath);
+ ssize_t res;
+- int off;
++ size_t len;
++ char *s;
+
+ res = vfs_listxattr(realpath.dentry, list, size);
+ if (res <= 0 || size == 0)
+@@ -287,17 +288,19 @@ ssize_t ovl_listxattr(struct dentry *den
+ return res;
+
+ /* filter out private xattrs */
+- for (off = 0; off < res;) {
+- char *s = list + off;
+- size_t slen = strlen(s) + 1;
++ for (s = list, len = res; len;) {
++ size_t slen = strnlen(s, len) + 1;
+
+- BUG_ON(off + slen > res);
++ /* underlying fs providing us with an broken xattr list? */
++ if (WARN_ON(slen > len))
++ return -EIO;
+
++ len -= slen;
+ if (ovl_is_private_xattr(s)) {
+ res -= slen;
+- memmove(s, s + slen, res - off);
++ memmove(s, s + slen, len);
+ } else {
+- off += slen;
++ s += slen;
+ }
+ }
+