[RHEL7,COMMIT] fs/fuse kio: NULL pointer dereference in case of dead map

Submitted by Vasily Averin on Aug. 6, 2020, 6:50 a.m.

Details

Message ID 202008060650.0766oBpX005070@vz7build.vvs.sw.ru
State New
Series "fs/fuse kio: NULL pointer dereference in case of dead map"
Headers show

Commit Message

Vasily Averin Aug. 6, 2020, 6:50 a.m.
The commit is pushed to "branch-rh7-3.10.0-1127.8.2.vz7.158.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.8.2.vz7.158.4
------>
commit 143512ec074bd724c80bfe655930dec01e0bdc5b
Author: Ildar Ismagilov <Ildar.Ismagilov@acronis.com>
Date:   Thu Aug 6 09:50:11 2020 +0300

    fs/fuse kio: NULL pointer dereference in case of dead map
    
    Inside fuse_map_resolve() there is dereference m->mapping,
    which can be NULL in case of map dead.
    
    https://pmc.acronis.com/browse/VSTOR-34510
    
    Signed-off-by: Ildar Ismagilov <Ildar.Ismagilov@acronis.com>
    Acked-by: Andrey Zaitsev <azaitsev@virtuozzo.com>
---
 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

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 06016a2..438c3c1 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -515,8 +515,8 @@  static void fuse_complete_map_work(struct work_struct *w)
 
 int fuse_map_resolve(struct pcs_map_entry *m, int direction)
 {
-	struct pcs_dentry_info *di = pcs_dentry_from_mapping(m->mapping);
-	struct fuse_conn *fc = pcs_cluster_from_cc(di->cluster)->fc;
+	struct pcs_dentry_info *di;
+	struct fuse_conn *fc;
 	struct fuse_req *req;
 	struct fuse_ioctl_in *inarg;
 	struct fuse_ioctl_out *outarg;
@@ -524,10 +524,22 @@  int fuse_map_resolve(struct pcs_map_entry *m, int direction)
 	struct pcs_fuse_work *reply_work;
 	size_t map_sz;
 
+	spin_lock(&m->lock);
+
+	if (m->state & PCS_MAP_DEAD) {
+		spin_unlock(&m->lock);
+		pcs_map_put(m);
+		return 0;
+	}
+	di = pcs_dentry_from_mapping(m->mapping);
+	fc = pcs_cluster_from_cc(di->cluster)->fc;
+
 	DTRACE("enter m: " MAP_FMT ", dir:%d \n", MAP_ARGS(m),	direction);
 
 	BUG_ON(!(m->state & PCS_MAP_RESOLVING));
 
+	spin_unlock(&m->lock);
+
 	map_sz = sizeof(*map_ioc) + MAX_CS_CNT * sizeof(struct pcs_cs_info);
 	map_ioc = kzalloc(map_sz, GFP_NOIO);
 	if (!map_ioc)