From: Tony Ernst <tee@sgi.com>
Subject: xfs/dmapi: Fix crash due to NULL pointer dereference
References: bnc#735765
Patch-mainline: Depends on DMAPI

 The formatter() call in xfs_bulkstat is passing NULL instead of
 private_data, causing a crash.

Acked-by: Jeff Mahoney <jeffm@suse.com>

---
 fs/xfs/dmapi/xfs_dm.c       |   30 +++++++++++++++---------------
 fs/xfs/linux-2.6/xfs_file.c |    3 +++
 fs/xfs/xfs_itable.c         |    2 +-
 3 files changed, 19 insertions(+), 16 deletions(-)

--- a/fs/xfs/dmapi/xfs_dm.c
+++ b/fs/xfs/dmapi/xfs_dm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.
+ * Copyright (c) 2000-2006,2011 SGI.
  * All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -142,7 +142,7 @@ xfs_dm_send_data_event(
 	int		flags,
 	int		*lock_flags)
 {
-	struct inode	*inode = &ip->i_vnode;
+	struct inode	*inode = VFS_I(ip);
 	int		error;
 	uint16_t	dmstate;
 
@@ -411,7 +411,7 @@ xfs_dm_bulkall_iget_one(
 		return error;
 
 	xfs_ip_to_stat(mp, ino, ip, &xbuf->dx_statinfo);
-	dm_ip_to_handle(&ip->i_vnode, &handle);
+	dm_ip_to_handle(VFS_I(ip), &handle);
 	xfs_dm_handle_to_xstat(xbuf, xstat_sz, &handle, sizeof(handle));
 
 	/* Drop ILOCK_SHARED for call to xfs_attr_get */
@@ -419,7 +419,7 @@ xfs_dm_bulkall_iget_one(
 
 	memset(&xbuf->dx_attrdata, 0, sizeof(dm_vardata_t));
 	error = xfs_attr_get(ip, attr_name, attr_buf, &value_len, ATTR_ROOT);
-	iput(&ip->i_vnode);
+	iput(VFS_I(ip));
 
 	DM_EA_XLATE_ERR(error);
 	if (error && (error != ENOATTR)) {
@@ -555,7 +555,7 @@ xfs_dm_bulkattr_iget_one(
 		return error;
 
 	xfs_ip_to_stat(mp, ino, ip, sbuf);
-	dm_ip_to_handle(&ip->i_vnode, &handle);
+	dm_ip_to_handle(VFS_I(ip), &handle);
 	xfs_dm_handle_to_stat(sbuf, stat_sz, &handle, sizeof(handle));
 
 	xfs_iunlock(ip, XFS_ILOCK_SHARED);
@@ -585,6 +585,7 @@ xfs_dm_bulkattr_one(
 
 	/* Returns positive errors to XFS */
 
+	ASSERT( private_data != NULL );
 	*res = BULKSTAT_RV_NOTHING;
 
 	if (!buffer || xfs_internal_inum(mp, ino))
@@ -711,7 +712,6 @@ xfs_dm_f_set_eventlist(
 	ip->i_d.di_dmevmask = (eventset & max_mask) | (ip->i_d.di_dmevmask & ~max_mask);
 
 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-//	igrab(&ip->i_vnode);
 	xfs_trans_commit(tp, 0);
 	xfs_iunlock(ip, XFS_ILOCK_EXCL);
 
@@ -2993,7 +2993,7 @@ xfs_dm_send_destroy_event(
 	dm_right_t	vp_right)	/* always DM_RIGHT_NULL */
 {
 	/* Returns positive errors to XFS */
-	return -dm_send_destroy_event(&ip->i_vnode, vp_right);
+	return -dm_send_destroy_event(VFS_I(ip), vp_right);
 }
 
 
@@ -3013,10 +3013,10 @@ xfs_dm_send_namesp_event(
 {
 	/* Returns positive errors to XFS */
 	return -dm_send_namesp_event(event, mp ? mp->m_super : NULL,
-				    &ip1->i_vnode, vp1_right,
-				    ip2 ? &ip2->i_vnode : NULL, vp2_right,
-				    name1, name2,
-				    mode, retcode, flags);
+				     VFS_I(ip1), vp1_right,
+				     ip2 ? VFS_I(ip2) : NULL, vp2_right,
+				     name1, name2,
+				     mode, retcode, flags);
 }
 
 STATIC int
@@ -3041,7 +3041,7 @@ xfs_dm_send_unmount_event(
 	int		retcode,	/* errno, if unmount failed */
 	int		flags)
 {
-	dm_send_unmount_event(mp->m_super, ip ? &ip->i_vnode : NULL,
+	dm_send_unmount_event(mp->m_super, ip ? VFS_I(ip) : NULL,
 			      vfsp_right, mode, retcode, flags);
 }
 
@@ -3077,7 +3077,7 @@ xfs_dm_fh_to_inode(
 
 	if (!dmfid->dm_fid_len) {
 		/* filesystem handle */
-		*inode = igrab(&mp->m_rootip->i_vnode);
+		*inode = igrab(VFS_I(mp->m_rootip));
 		if (!*inode)
 			return -ENOENT;
 		return 0;
@@ -3105,7 +3105,7 @@ xfs_dm_fh_to_inode(
 		return -ENOENT;
 	}
 
-	*inode = &ip->i_vnode;
+	*inode = VFS_I(ip);
 	xfs_iunlock(ip, XFS_ILOCK_SHARED);
 	return 0;
 }
@@ -3169,7 +3169,7 @@ xfs_dm_exit(void)
 	dmapi_unregister(&xfs_fs_type);
 }
 
-MODULE_AUTHOR("Silicon Graphics, Inc.");
+MODULE_AUTHOR("SGI");
 MODULE_DESCRIPTION("SGI XFS dmapi subsystem");
 MODULE_LICENSE("GPL");
 
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -1178,6 +1178,9 @@ const struct file_operations xfs_file_op
 	.release	= xfs_file_release,
 	.fsync		= xfs_file_fsync,
 	.fallocate	= xfs_file_fallocate,
+#ifdef HAVE_FOP_OPEN_EXEC
+	.open_exec	= xfs_file_open_exec,
+#endif
 };
 
 const struct file_operations xfs_dir_file_operations = {
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -481,7 +481,7 @@ xfs_bulkstat(
 				 * Get the inode and fill in a single buffer.
 				 */
 				ubused = statstruct_size;
-				error = formatter(mp, ino, ubufp, ubleft, NULL,
+				error = formatter(mp, ino, ubufp, ubleft, private_data,
 						  &ubused, &fmterror);
 				if (fmterror == BULKSTAT_RV_NOTHING) {
 					if (error && error != ENOENT &&
