Whamcloud - gitweb
LU-4708 ldiskfs: do not copy NUL terminator from direntry 62/9662/3
authorAndreas Dilger <andreas.dilger@intel.com>
Wed, 5 Mar 2014 18:59:30 +0000 (11:59 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 29 Apr 2014 00:53:35 +0000 (00:53 +0000)
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 <andreas.dilger@intel.com>
Change-Id: Iab52f916d7571b3d2587255280c72a52c60399c9
Reviewed-on: http://review.whamcloud.com/9510
Tested-by: Jenkins
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
Reviewed-on: http://review.whamcloud.com/9662

ldiskfs/kernel_patches/patches/rhel6.3/ext4_data_in_dirent.patch
ldiskfs/kernel_patches/patches/sles11sp2/ext4_data_in_dirent.patch

index 72c2395..a6f586b 100644 (file)
@@ -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)
index 973ccad..c77192c 100644 (file)
@@ -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)