aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2013-02-04 08:04:44 -0500
committerMiklos Szeredi <mszeredi@suse.cz>2013-02-04 09:22:23 -0500
commit6a4e922c3db06f7da27e072729e047185c2fba66 (patch)
tree26d92e82ab982b25b3f115e52a9bf9956003889b /fs/fuse
parent23c153e54197171f30b889d9654929d74b6599d5 (diff)
fuse: avoid out-of-scope stack access
The all pointers within fuse_req must point to valid memory once fuse_force_forget() returns. This bug appeared in "fuse: implement NFS-like readdirplus support" and was never in any official Linux release. I tested the fuse_force_forget() code path by injecting to fake -ENOMEM and verified the FORGET operation was called properly in userspace. Signed-off-by: Eric Wong <normalperson@yhbt.net> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/dev.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index cbae09e5a491..e9bdec0b16d9 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -440,9 +440,8 @@ __acquires(fc->lock)
440 } 440 }
441} 441}
442 442
443void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 443static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
444{ 444{
445 req->isreply = 1;
446 spin_lock(&fc->lock); 445 spin_lock(&fc->lock);
447 if (!fc->connected) 446 if (!fc->connected)
448 req->out.h.error = -ENOTCONN; 447 req->out.h.error = -ENOTCONN;
@@ -459,6 +458,12 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
459 } 458 }
460 spin_unlock(&fc->lock); 459 spin_unlock(&fc->lock);
461} 460}
461
462void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
463{
464 req->isreply = 1;
465 __fuse_request_send(fc, req);
466}
462EXPORT_SYMBOL_GPL(fuse_request_send); 467EXPORT_SYMBOL_GPL(fuse_request_send);
463 468
464static void fuse_request_send_nowait_locked(struct fuse_conn *fc, 469static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
@@ -541,7 +546,9 @@ void fuse_force_forget(struct file *file, u64 nodeid)
541 req->in.args[0].size = sizeof(inarg); 546 req->in.args[0].size = sizeof(inarg);
542 req->in.args[0].value = &inarg; 547 req->in.args[0].value = &inarg;
543 req->isreply = 0; 548 req->isreply = 0;
544 fuse_request_send_nowait(fc, req); 549 __fuse_request_send(fc, req);
550 /* ignore errors */
551 fuse_put_request(fc, req);
545} 552}
546 553
547/* 554/*