Whamcloud - gitweb
LU-12169 llite: fill copied dentry name's ending char properly 11/34611/3
authorWang Shilong <wshilong@ddn.com>
Mon, 8 Apr 2019 13:22:45 +0000 (21:22 +0800)
committerOleg Drokin <green@whamcloud.com>
Tue, 30 Apr 2019 03:37:50 +0000 (03:37 +0000)
Dentry name expect an extra '\0'. and dentry_len won't calcualte
extra '\0' for it, but we should allocate memory and fill it
when copying dentry name by ourselves.

Otherwise, lu_name_is_valid_2() will try to access @name[len]
and check whether it is '\0'. this is invalid memory access.
We will possibly hit a crash if the first access that bit is '\0'.
and the bit overwritten by someone else, and finally we failed
sanity check in mdc_name_pack().

LustreError: 157839:0:(mdc_lib.c:137:mdc_pack_name()) LBUG

Fixes: f575b65("LU-12020 llite: make sure name pack atomic")
Change-Id: I533e19a0e6efb0fca5a46bcdbdb0006d1b1bedab
Signed-off-by: Wang Shilong <wshilong@ddn.com>
Reviewed-on: https://review.whamcloud.com/34611
Tested-by: Jenkins
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Gu Zheng <gzheng@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/obd_support.h
lustre/llite/file.c
lustre/tests/sanity.sh

index d4a2029..f2a07ef 100644 (file)
@@ -562,6 +562,7 @@ extern char obd_jobid_var[];
 #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE           0x140c
 #define OBD_FAIL_LLITE_IMUTEX_SEC                  0x140e
 #define OBD_FAIL_LLITE_IMUTEX_NOSEC                0x140f
+#define OBD_FAIL_LLITE_OPEN_BY_NAME                0x1410
 
 #define OBD_FAIL_FID_INDIR     0x1501
 #define OBD_FAIL_FID_INLMA     0x1502
index 4e063f5..4d39246 100644 (file)
@@ -509,12 +509,14 @@ static int ll_intent_file_open(struct dentry *de, void *lmm, int lmmsize,
 
        /* if server supports open-by-fid, or file name is invalid, don't pack
         * name in open request */
-       if (!(exp_connect_flags(sbi->ll_md_exp) & OBD_CONNECT_OPEN_BY_FID)) {
+       if (OBD_FAIL_CHECK(OBD_FAIL_LLITE_OPEN_BY_NAME) ||
+           !(exp_connect_flags(sbi->ll_md_exp) & OBD_CONNECT_OPEN_BY_FID)) {
 retry:
                len = de->d_name.len;
-               name = kmalloc(len, GFP_NOFS);
+               name = kmalloc(len + 1, GFP_NOFS);
                if (!name)
                        RETURN(-ENOMEM);
+
                /* race here */
                spin_lock(&de->d_lock);
                if (len != de->d_name.len) {
@@ -523,12 +525,12 @@ retry:
                        goto retry;
                }
                memcpy(name, de->d_name.name, len);
+               name[len] = '\0';
                spin_unlock(&de->d_lock);
 
                if (!lu_name_is_valid_2(name, len)) {
                        kfree(name);
-                       name = NULL;
-                       len = 0;
+                       RETURN(-ESTALE);
                }
        }
 
index 8724c8f..c60de09 100755 (executable)
@@ -19690,6 +19690,23 @@ test_418() {
 }
 run_test 418 "df and lfs df outputs match"
 
+test_419()
+{
+       local dir=$DIR/$tdir
+
+       mkdir -p $dir
+       touch $dir/file
+
+       cancel_lru_locks mdc
+
+       #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
+       $LCTL set_param fail_loc=0x1410
+       cat $dir/file
+       $LCTL set_param fail_loc=0
+       rm -rf $dir
+}
+run_test 419 "Verify open file by name doesn't crash kernel"
+
 prep_801() {
        [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
        [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&