Whamcloud - gitweb
LU-14781 osp: osp_object_free access NULL pointer 42/45442/1
authorBobi Jam <bobijam@whamcloud.com>
Tue, 2 Nov 2021 07:27:59 +0000 (15:27 +0800)
committerBobi Jam <bobijam@whamcloud.com>
Wed, 3 Nov 2021 03:14:59 +0000 (11:14 +0800)
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

lustre/osp/osp_dev.c

index 4413ef8..88c0924 100644 (file)
@@ -135,6 +135,14 @@ static struct lu_object *osp_object_alloc(const struct lu_env *env,
 
                l->lo_ops = &osp_lu_obj_ops;
 
+               /**
+                * in case osp_object_free() is called without osp_object_init()
+                * as lu_object_find_at() could allocate an osp_object then
+                * find another one has created it, and it will free this
+                * osp_object without osp_object_init() to initialize the list
+                * while osp_object_free() will access this NULL list_head.
+                */
+               INIT_LIST_HEAD(&o->opo_xattr_list);
                return l;
        } else {
                return NULL;