From: Andreas Dilger Date: Wed, 5 Mar 2014 18:59:30 +0000 (-0700) Subject: LU-4708 ldiskfs: do not copy NUL terminator from direntry X-Git-Tag: 2.5.57~19 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=a101a95a3f58cde3ed912d074dc283b4083672ff 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. 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 --- 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 b5341621..ae8e51e 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 ac76bf9..fa8f7ca 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)