From: Patrick Farrell Date: Mon, 18 Mar 2013 16:09:46 +0000 (-0500) Subject: LU-2900 llite: Null deref in ll_fsync:mkdir on NFSmounted Lus X-Git-Tag: 2.3.64~65 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=a7811634d45319dc3812fa652c727367fa290a24;hp=e78df92a33634b78df30733deb8123598ef55d35 LU-2900 llite: Null deref in ll_fsync:mkdir on NFSmounted Lus 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 Change-Id: I93ecf04e23121c76e571383d74e2fc902565614e Reviewed-on: http://review.whamcloud.com/5585 Reviewed-by: Bob Glossman Tested-by: Hudson Tested-by: Maloo Reviewed-by: Keith Mannthey Reviewed-by: Cory Spitz Reviewed-by: Oleg Drokin --- diff --git a/lustre/llite/file.c b/lustre/llite/file.c index f5301af..14e38cf 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -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;