Uploaded image for project: 'Lustre'
  1. Lustre
  2. LU-2900

Null pointer dereference in ll_fsync (llite/file.c) from mkdir in an NFS mounted Lustre fs

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Major
    • Lustre 2.4.0
    • Lustre 2.0.0, Lustre 2.2.0, Lustre 2.3.0, Lustre 2.4.0, Lustre 2.1.1, Lustre 2.1.2, Lustre 2.1.3, Lustre 2.1.4
    • SLES11SP1 (Cray Linux Environment)
    • 3
    • 6987

    Description

      When a Lustre file system is mounted via NFS and a mkdir operation is attempted, a null pointer dereference occurs in ll_fsync.

      With 2.x, Lustre added support for different VFS fsync APIs that do not include a dentry parameter.

      To make the logic the same in all cases, the old ll_fsync interface was changed to pull the inode from the f_dentry in the file parameter.

      In some cases when using the old ll_fsync interface, the caller does not set the file parameter resulting in a NULL dereference. The fix to this is to restore the old logic in those cases: when a dentry parameter is provided, get the inode from that parameter rather than the file parameter.

      Here's the current code in llite/file.c (same throughout 2.x):

      #ifdef HAVE_FILE_FSYNC_4ARGS
      int ll_fsync(struct file *file, loff_t start, loff_t end, int data)
      #elif defined(HAVE_FILE_FSYNC_2ARGS)
      int ll_fsync(struct file *file, int data)
      #else
      int ll_fsync(struct file *file, struct dentry *dentry, int data)
      #endif
      {
               struct inode *inode = file->f_dentry->d_inode;
               struct ll_inode_info *lli = ll_i2info(inode);
      

      Here's the proposed fix:

      /* 
       * When dentry is provided (the 'else' case), *file may be null
       * and dentry must be used directly rather than pulled from *file
       * as is done otherwise.
       */
      #ifdef HAVE_FILE_FSYNC_4ARGS
      int ll_fsync(struct file *file, loff_t start, loff_t end, int data)
      #elif defined(HAVE_FILE_FSYNC_2ARGS)
      int ll_fsync(struct file *file, int data)
      #else
      int ll_fsync(struct file *file, struct dentry *dentry, int data)
      #endif
      {
      #if defined(HAVE_FILE_FSYNC_4ARGS) || defined(HAVE_FILE_FSYNC_2ARGS)
              struct inode *inode = file->f_dentry->d_inode;
      #else
              struct inode *inode = dentry->d_inode;
      #endif
              struct ll_inode_info *lli = ll_i2info(inode);
      

      The fix has been tested at Cray, both under the general acceptance-small tests and specifically for the NFS issue.

      I'll be putting the patch in Gerrit shortly.

      Attachments

        Issue Links

          Activity

            People

              bogl Bob Glossman (Inactive)
              paf Patrick Farrell (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: