Whamcloud - gitweb
LU-14781 osp: osp_object_free access NULL pointer 42/45442/3
authorBobi Jam <bobijam@whamcloud.com>
Tue, 2 Nov 2021 07:27:59 +0000 (15:27 +0800)
committerOleg Drokin <green@whamcloud.com>
Tue, 30 Nov 2021 03:46:07 +0000 (03:46 +0000)
If a osp_object is created by multiple threads at the same time,
lu_object_find_at() could allocate an osp_object without object
initialization, before hash inserting of the object, it find another
object has been created and inserted by another thread, it will free
the unintialized osp_object, and osp_object_free() will access
an uninitialized list_head (opo_xattr_list).

This patch initialize osp_object::opo_xattr_list in its allocation
function.

Call trace:
            lu_object_free.isra.30+0xf2/0x170 [obdclass]
            lu_object_find_at+0x496/0x930 [obdclass]
            lod_initialize_objects+0x3e4/0xba0 [lod]
            lod_parse_striping+0x693/0xc20 [lod]
            lod_striping_load+0x2b2/0x660 [lod]
            lod_declare_destroy+0x12b/0x600 [lod]
            mdd_declare_finish_unlink+0x91/0x210 [mdd]
            mdd_unlink+0x48f/0xab0 [mdd]
            mdt_reint_unlink+0xc32/0x1550 [mdt]
            mdt_reint_rec+0x83/0x210 [mdt]
            mdt_reint_internal+0x6e1/0xb00 [mdt]
            mdt_reint+0x67/0x140 [mdt]
            tgt_request_handle+0xaee/0x15f0 [ptlrpc]
            ptlrpc_server_handle_request+0x24b/0xab0 [ptlrpc]
            ptlrpc_main+0xb34/0x1470 [ptlrpc]
            kthread+0xd1/0xe0

Signed-off-by: Bobi Jam <bobijam@whamcloud.com>
Change-Id: Ib86aca5b41e94a1758f177655ea3a0f680335e0f
Reviewed-on: https://review.whamcloud.com/45442
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.com>
lustre/osp/osp_dev.c
lustre/osp/osp_object.c

index 4413ef8..c316b52 100644 (file)
@@ -112,33 +112,38 @@ static struct lu_object *osp_object_alloc(const struct lu_env *env,
                                          const struct lu_object_header *hdr,
                                          struct lu_device *d)
 {
-       struct lu_object_header *h = NULL;
-       struct osp_object       *o;
-       struct lu_object        *l;
+       struct osp_object *o;
 
        OBD_SLAB_ALLOC_PTR_GFP(o, osp_object_kmem, GFP_NOFS);
        if (o != NULL) {
-               l = &o->opo_obj.do_lu;
+               struct lu_object *l = &o->opo_obj.do_lu;
 
                /* If hdr is NULL, it means the object is not built
                 * from the top dev(MDT/OST), usually it happens when
                 * building striped object, like data object on MDT or
                 * striped object for directory */
                if (hdr == NULL) {
-                       h = &o->opo_header;
+                       struct lu_object_header *h = &o->opo_header;
+
                        lu_object_header_init(h);
                        dt_object_init(&o->opo_obj, h, d);
                        lu_object_add_top(h, l);
                } else {
-                       dt_object_init(&o->opo_obj, h, d);
+                       dt_object_init(&o->opo_obj, NULL, d);
                }
 
                l->lo_ops = &osp_lu_obj_ops;
 
+               init_rwsem(&o->opo_sem);
+               INIT_LIST_HEAD(&o->opo_xattr_list);
+               INIT_LIST_HEAD(&o->opo_invalidate_cb_list);
+               spin_lock_init(&o->opo_lock);
+               init_rwsem(&o->opo_invalidate_sem);
+
                return l;
-       } else {
-               return NULL;
        }
+
+       return NULL;
 }
 
 /**
index 8126eb0..52a12c4 100644 (file)
@@ -2285,15 +2285,12 @@ static const struct dt_object_operations osp_obj_ops = {
 static int osp_object_init(const struct lu_env *env, struct lu_object *o,
                           const struct lu_object_conf *conf)
 {
-       struct osp_object       *po = lu2osp_obj(o);
-       int                     rc = 0;
+       struct osp_object *po = lu2osp_obj(o);
+       int rc = 0;
+
        ENTRY;
 
-       spin_lock_init(&po->opo_lock);
        o->lo_header->loh_attr |= LOHA_REMOTE;
-       INIT_LIST_HEAD(&po->opo_xattr_list);
-       INIT_LIST_HEAD(&po->opo_invalidate_cb_list);
-       init_rwsem(&po->opo_invalidate_sem);
 
        if (is_ost_obj(o)) {
                po->opo_obj.do_ops = &osp_obj_ops;
@@ -2316,8 +2313,8 @@ static int osp_object_init(const struct lu_env *env, struct lu_object *o,
                                rc = 0;
                        }
                }
-               init_rwsem(&po->opo_sem);
        }
+
        RETURN(rc);
 }