[PATCH 3.16 084/306] fuse: listxattr: verify xattr list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



3.16.40-rc1 review patch.  If anyone has any objections, please let me know.

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

From: Miklos Szeredi <mszeredi@xxxxxxxxxx>

commit cb3ae6d25a5471be62bfe6ac1fccc0e91edeaba0 upstream.

Make sure userspace filesystem is returning a well formed list of xattr
names (zero or more nonzero length, null terminated strings).

[Michael Theall: only verify in the nonzero size case]

Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxxxxx>
[bwh: Backported to 3.16: adjust context, indentation]
Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx>
---
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1968,6 +1968,23 @@ static ssize_t fuse_getxattr(struct dent
 	return ret;
 }
 
+static int fuse_verify_xattr_list(char *list, size_t size)
+{
+	size_t origsize = size;
+
+	while (size) {
+		size_t thislen = strnlen(list, size);
+
+		if (!thislen || thislen == size)
+			return -EIO;
+
+		size -= thislen + 1;
+		list += thislen + 1;
+	}
+
+	return origsize;
+}
+
 static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
 {
 	struct inode *inode = entry->d_inode;
@@ -2006,9 +2023,11 @@ static ssize_t fuse_listxattr(struct den
 	}
 	fuse_request_send(fc, req);
 	ret = req->out.h.error;
-	if (!ret)
+	if (!ret) {
 		ret = size ? req->out.args[0].size : outarg.size;
-	else {
+		if (ret > 0 && size)
+			ret = fuse_verify_xattr_list(list, ret);
+	} else {
 		if (ret == -ENOSYS) {
 			fc->no_listxattr = 1;
 			ret = -EOPNOTSUPP;




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]