4.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Miklos Szeredi <[email protected]>

commit 7cb35119d067191ce9ebc380a599db0b03cbd9d9 upstream.

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 <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 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;
                }
        }
 


Reply via email to