Whamcloud - gitweb
LU-2900 llite: Null deref in ll_fsync:mkdir on NFSmounted Lus
authorPatrick Farrell <paf@cray.com>
Mon, 18 Mar 2013 16:09:46 +0000 (11:09 -0500)
committerOleg Drokin <oleg.drokin@intel.com>
Fri, 29 Mar 2013 15:58:12 +0000 (11:58 -0400)
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 f_dentry
in the *file parameter.

In some cases when using the old ll_fsync interface, the
caller does not set the f_dentry part of 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.

Signed-off-by: Patrick Farrell <paf@cray.com>
Change-Id: I93ecf04e23121c76e571383d74e2fc902565614e
Reviewed-on: http://review.whamcloud.com/5585
Reviewed-by: Bob Glossman <bob.glossman@intel.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Keith Mannthey <keith.mannthey@intel.com>
Reviewed-by: Cory Spitz <spitzcor@cray.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/llite/file.c

index f5301af..14e38cf 100644 (file)
@@ -2411,15 +2411,25 @@ int cl_sync_file_range(struct inode *inode, loff_t start, loff_t end,
        RETURN(result);
 }
 
+/*
+ * When dentry is provided (the 'else' case), *file->f_dentry may be
+ * null and dentry must be used directly rather than pulled from
+ * *file->f_dentry as is done otherwise.
+ */
+
 #ifdef HAVE_FILE_FSYNC_4ARGS
 int ll_fsync(struct file *file, loff_t start, loff_t end, int data)
+{
+       struct dentry *dentry = file->f_dentry;
 #elif defined(HAVE_FILE_FSYNC_2ARGS)
 int ll_fsync(struct file *file, int data)
+{
+       struct dentry *dentry = file->f_dentry;
 #else
 int ll_fsync(struct file *file, struct dentry *dentry, int data)
-#endif
 {
-        struct inode *inode = file->f_dentry->d_inode;
+#endif
+        struct inode *inode = dentry->d_inode;
         struct ll_inode_info *lli = ll_i2info(inode);
         struct ptlrpc_request *req;
         struct obd_capa *oc;