From: Qian Yingjin Date: Sat, 30 Nov 2024 06:48:31 +0000 (+0800) Subject: LU-18510 llite: free op_data upon error only when alloc inside X-Git-Tag: 2.16.51~19 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=5bac854028d7bb4067ddad6fb2a4522eeb716782;p=fs%2Flustre-release.git LU-18510 llite: free op_data upon error only when alloc inside In ll_prep_md_op_data() for preparing md_op_data, it should free @op_data upon ll_setup_filename() failure only when @op_data is allocated inside. Otherwise, it will double free @op_data for the pass-in case and may cause sanity-sec/63 crash as follows: ll_prep_md_op_data()) lustre: failed to setup filename: rc = -126 RIP: 0010:set_freepointer.part.57+0x0/0x10 kfree+0x238/0x250 ll_prep_md_op_data+0x2af/0x870 [lustre] sa_prep_data+0xde/0x350 [lustre] sa_statahead+0x3b9/0xd20 [lustre] ll_statahead_thread+0x151f/0x2210 [lustre] Fixes: 4d38566a004 (LU-13717 sec: filename encryption) Test-Parameters: testlist=sanity-sec env=ONLY=63,ONLY_REPEAT=250 Signed-off-by: Qian Yingjin Change-Id: Ia46635e5bab17e21f4c411e7497e8f70711eb4e4 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/57291 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Marc Vef Reviewed-by: Sebastien Buisson Reviewed-by: Oleg Drokin --- diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index b677b0f..76820db 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -3854,6 +3854,7 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data, void *data) { struct llcrypt_name fname = { 0 }; + bool op_data_alloc_inside = true; int rc; LASSERT(i1 != NULL); @@ -3876,6 +3877,8 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data, if (op_data == NULL) OBD_ALLOC_PTR(op_data); + else + op_data_alloc_inside = false; if (op_data == NULL) return ERR_PTR(-ENOMEM); @@ -3948,7 +3951,8 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data, if (rc) { CERROR("%s: failed to setup filename: rc = %d\n", ll_i2sbi(i1)->ll_fsname, rc); - ll_finish_md_op_data(op_data); + if (op_data_alloc_inside) + ll_finish_md_op_data(op_data); return ERR_PTR(rc); } if (pfid && !fid_is_zero(pfid)) {