[RHEL7,COMMIT] fuse kio: Check returned FUSE_SETATTR size

Submitted by Konstantin Khorenko on June 28, 2018, 3:03 p.m.

Details

Message ID 201806281503.w5SF3hD0020597@finist_ce7.work
State New
Series "fuse kio: Check returned FUSE_SETATTR size"
Headers show

Commit Message

Konstantin Khorenko June 28, 2018, 3:03 p.m.
The commit is pushed to "branch-rh7-3.10.0-862.3.2.vz7.61.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.3.2.vz7.61.6
------>
commit d7f18ea8beac582240e9bf341f7111f8f5265018
Author: Kirill Tkhai <ktkhai@virtuozzo.com>
Date:   Thu Jun 28 18:03:43 2018 +0300

    fuse kio: Check returned FUSE_SETATTR size
    
    This patch adds a check for a size returned from userspace.
    Userspace also can mistake, so we can't believe it returned
    exactly what we expect, while our further logic based on
    the fact it never fails.
    
    Also, this could be useful to catch size overflows issues.
    
    Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
    Acked-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
---
 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index 509526dc534b..258959ed5014 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -954,6 +954,7 @@  static void kpcs_setattr_end(struct fuse_conn *fc, struct fuse_req *req)
 {
 	struct pcs_fuse_req *r = pcs_req_from_fuse(req);
 	struct fuse_inode *fi = get_fuse_inode(req->io_inode);
+	struct fuse_setattr_in *inarg = (void*) req->in.args[0].value;
 	struct fuse_attr_out *outarg = (void*) req->out.args[0].value;
 	struct pcs_dentry_info *di = fi->private;
 
@@ -964,8 +965,14 @@  static void kpcs_setattr_end(struct fuse_conn *fc, struct fuse_req *req)
 	TRACE("update size: ino:%lu old_sz:%lld new:%lld\n",req->io_inode->i_ino,
 	      di->fileinfo.attr.size, outarg->attr.size);
 
-	if (!req->out.h.error)
+	if (!req->out.h.error) {
 		di->fileinfo.attr.size = outarg->attr.size;
+		if (outarg->attr.size != inarg->size) {
+			pr_err("kio: failed to set requested size: %llu %llu\n",
+				outarg->attr.size, inarg->size);
+			req->out.h.error = -EIO;
+		}
+	}
 	spin_unlock(&di->lock);
 	if(r->end)
 		r->end(fc, req);