ceph: avoid panic in create_session_open_msg() if utsname() returns NULL
authorYan, Zheng <zyan@redhat.com>
Mon, 11 Sep 2017 04:10:08 +0000 (12:10 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Tue, 19 Sep 2017 19:04:52 +0000 (21:04 +0200)
utsname() can return NULL while process is exiting. Kernel releases
file locks during process exits. We send request to mds when releasing
file lock. So it's possible that we open mds session while process is
exiting. utsname() is called in create_session_open_msg().

Link: http://tracker.ceph.com/issues/21275
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
[idryomov@gmail.com: drop utsname.h include from mds_client.c]
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/mds_client.c
fs/ceph/mds_client.h

index 9dd6b836ac9e5b91d60a439995695d72c06c97e5..84edfc60d87a898c810205b912a5eeb8dae9f446 100644 (file)
@@ -7,7 +7,6 @@
 #include <linux/sched.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
-#include <linux/utsname.h>
 #include <linux/ratelimit.h>
 
 #include "super.h"
@@ -884,8 +883,8 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
        void *p;
 
        const char* metadata[][2] = {
-               {"hostname", utsname()->nodename},
-               {"kernel_version", utsname()->release},
+               {"hostname", mdsc->nodename},
+               {"kernel_version", init_utsname()->release},
                {"entity_id", opt->name ? : ""},
                {"root", fsopt->server_path ? : "/"},
                {NULL, NULL}
@@ -3539,6 +3538,8 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
        init_rwsem(&mdsc->pool_perm_rwsem);
        mdsc->pool_perm_tree = RB_ROOT;
 
+       strncpy(mdsc->nodename, utsname()->nodename,
+               sizeof(mdsc->nodename) - 1);
        return 0;
 }
 
index db57ae98ed345e280358a2ac65e75ac6c71e7c2b..636d6b2ec49cbab44954dc8e3e7fb93616e6756d 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/rbtree.h>
 #include <linux/spinlock.h>
 #include <linux/refcount.h>
+#include <linux/utsname.h>
 
 #include <linux/ceph/types.h>
 #include <linux/ceph/messenger.h>
@@ -368,6 +369,8 @@ struct ceph_mds_client {
 
        struct rw_semaphore     pool_perm_rwsem;
        struct rb_root          pool_perm_tree;
+
+       char nodename[__NEW_UTS_LEN + 1];
 };
 
 extern const char *ceph_mds_op_name(int op);