From be6781d6fb56dff7fc509bed80ce0ee0f675a107 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Wed, 5 Mar 2014 11:59:30 -0700 Subject: [PATCH] LU-4708 ldiskfs: do not copy NUL terminator from direntry Do not try to copy a NUL terminator from the source dirent if there is no dir_data for that record. This can happen with 1.x filesystems that do not have a dirdata field in the dirent to store the FID. The target buffer is expected to be NUL terminated, and this is handled by using kzalloc() to allocate it and zero out the buffer, but the source buffer may not have a trailing NUL byte if it is a multiple of 4 bytes in length. If the dirent is aligned at the end of the directory block/page this can cause an oops by accessing beyond the end of the page, or will otherwise copy a garbage byte to the target buffer. Lustre commit: a101a95a3f58cde3ed912d074dc283b4083672ff Lustre change: http://review.whamcloud.com/9510 Signed-off-by: Andreas Dilger Change-Id: Iab52f916d7571b3d2587255280c72a52c60399c9 Reviewed-on: http://review.whamcloud.com/9510 Tested-by: Jenkins Reviewed-by: Niu Yawei Tested-by: Maloo Reviewed-by: Fan Yong Reviewed-by: Oleg Drokin Reviewed-on: http://review.whamcloud.com/9662 --- ldiskfs/kernel_patches/patches/rhel6.3/ext4_data_in_dirent.patch | 4 ++-- ldiskfs/kernel_patches/patches/sles11sp2/ext4_data_in_dirent.patch | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ldiskfs/kernel_patches/patches/rhel6.3/ext4_data_in_dirent.patch b/ldiskfs/kernel_patches/patches/rhel6.3/ext4_data_in_dirent.patch index 72c2395..a6f586b 100644 --- a/ldiskfs/kernel_patches/patches/rhel6.3/ext4_data_in_dirent.patch +++ b/ldiskfs/kernel_patches/patches/rhel6.3/ext4_data_in_dirent.patch @@ -57,7 +57,7 @@ changes in ext4_add_entry() interface required. struct fname *fname, *new_fn; struct dir_private_info *info; int len; -+ int extra_data = 1; ++ int extra_data = 0; info = (struct dir_private_info *) dir_file->private_data; p = &info->root.rb_node; @@ -67,7 +67,7 @@ changes in ext4_add_entry() interface required. + if (dirent->file_type & EXT4_DIRENT_LUFID) + extra_data = ext4_get_dirent_data_len(dirent); + -+ len = sizeof(struct fname) + dirent->name_len + extra_data; ++ len = sizeof(struct fname) + dirent->name_len + extra_data + 1; + new_fn = kzalloc(len, GFP_KERNEL); if (!new_fn) diff --git a/ldiskfs/kernel_patches/patches/sles11sp2/ext4_data_in_dirent.patch b/ldiskfs/kernel_patches/patches/sles11sp2/ext4_data_in_dirent.patch index 973ccad..c77192c 100644 --- a/ldiskfs/kernel_patches/patches/sles11sp2/ext4_data_in_dirent.patch +++ b/ldiskfs/kernel_patches/patches/sles11sp2/ext4_data_in_dirent.patch @@ -54,7 +54,7 @@ struct fname *fname, *new_fn; struct dir_private_info *info; int len; -+ int extra_data = 1; ++ int extra_data = 0; info = dir_file->private_data; p = &info->root.rb_node; @@ -64,7 +64,7 @@ + if (dirent->file_type & EXT4_DIRENT_LUFID) + extra_data = ext4_get_dirent_data_len(dirent); + -+ len = sizeof(struct fname) + dirent->name_len + extra_data; ++ len = sizeof(struct fname) + dirent->name_len + extra_data + 1; + new_fn = kzalloc(len, GFP_KERNEL); if (!new_fn) -- 1.8.3.1