--- /dev/null
+From f6488c9ba51d65410e2dbc4345413c0d9120971e Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Wed, 27 Feb 2013 20:10:34 -0500
+Subject: nfs: don't allow nfs_find_actor to match inodes of the wrong type
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit f6488c9ba51d65410e2dbc4345413c0d9120971e upstream.
+
+Benny Halevy reported the following oops when testing RHEL6:
+
+<7>nfs_update_inode: inode 892950 mode changed, 0040755 to 0100644
+<1>BUG: unable to handle kernel NULL pointer dereference at (null)
+<1>IP: [<ffffffffa02a52c5>] nfs_closedir+0x15/0x30 [nfs]
+<4>PGD 81448a067 PUD 831632067 PMD 0
+<4>Oops: 0000 [#1] SMP
+<4>last sysfs file: /sys/kernel/mm/redhat_transparent_hugepage/enabled
+<4>CPU 6
+<4>Modules linked in: fuse bonding 8021q garp ebtable_nat ebtables be2iscsi iscsi_boot_sysfs bnx2i cnic uio cxgb4i cxgb4 cxgb3i libcxgbi cxgb3 mdio ib_iser rdma_cm ib_cm iw_cm ib_sa ib_mad ib_core ib_addr iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi softdog bridge stp llc xt_physdev ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 xt_multiport iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 dm_round_robin dm_multipath objlayoutdriver2(U) nfs(U) lockd fscache auth_rpcgss nfs_acl sunrpc vhost_net macvtap macvlan tun kvm_intel kvm be2net igb dca ptp pps_core microcode serio_raw sg iTCO_wdt iTCO_vendor_support i7core_edac edac_core shpchp ext4 mbcache jbd2 sd_mod crc_t10dif ahci dm_mirror dm_region_hash dm_log dm_mod [last unloaded: scsi_wait_scan]
+<4>
+<4>Pid: 6332, comm: dd Not tainted 2.6.32-358.el6.x86_64 #1 HP ProLiant DL170e G6 /ProLiant DL170e G6
+<4>RIP: 0010:[<ffffffffa02a52c5>] [<ffffffffa02a52c5>] nfs_closedir+0x15/0x30 [nfs]
+<4>RSP: 0018:ffff88081458bb98 EFLAGS: 00010292
+<4>RAX: ffffffffa02a52b0 RBX: 0000000000000000 RCX: 0000000000000003
+<4>RDX: ffffffffa02e45a0 RSI: ffff88081440b300 RDI: ffff88082d5f5760
+<4>RBP: ffff88081458bba8 R08: 0000000000000000 R09: 0000000000000000
+<4>R10: 0000000000000772 R11: 0000000000400004 R12: 0000000040000008
+<4>R13: ffff88082d5f5760 R14: ffff88082d6e8800 R15: ffff88082f12d780
+<4>FS: 00007f728f37e700(0000) GS:ffff8800456c0000(0000) knlGS:0000000000000000
+<4>CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
+<4>CR2: 0000000000000000 CR3: 0000000831279000 CR4: 00000000000007e0
+<4>DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+<4>DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
+<4>Process dd (pid: 6332, threadinfo ffff88081458a000, task ffff88082fa0e040)
+<4>Stack:
+<4> 0000000040000008 ffff88081440b300 ffff88081458bbf8 ffffffff81182745
+<4><d> ffff88082d5f5760 ffff88082d6e8800 ffff88081458bbf8 ffffffffffffffea
+<4><d> ffff88082f12d780 ffff88082d6e8800 ffffffffa02a50a0 ffff88082d5f5760
+<4>Call Trace:
+<4> [<ffffffff81182745>] __fput+0xf5/0x210
+<4> [<ffffffffa02a50a0>] ? do_open+0x0/0x20 [nfs]
+<4> [<ffffffff81182885>] fput+0x25/0x30
+<4> [<ffffffff8117e23e>] __dentry_open+0x27e/0x360
+<4> [<ffffffff811c397a>] ? inotify_d_instantiate+0x2a/0x60
+<4> [<ffffffff8117e4b9>] lookup_instantiate_filp+0x69/0x90
+<4> [<ffffffffa02a6679>] nfs_intent_set_file+0x59/0x90 [nfs]
+<4> [<ffffffffa02a686b>] nfs_atomic_lookup+0x1bb/0x310 [nfs]
+<4> [<ffffffff8118e0c2>] __lookup_hash+0x102/0x160
+<4> [<ffffffff81225052>] ? selinux_inode_permission+0x72/0xb0
+<4> [<ffffffff8118e76a>] lookup_hash+0x3a/0x50
+<4> [<ffffffff81192a4b>] do_filp_open+0x2eb/0xdd0
+<4> [<ffffffff8104757c>] ? __do_page_fault+0x1ec/0x480
+<4> [<ffffffff8119f562>] ? alloc_fd+0x92/0x160
+<4> [<ffffffff8117de79>] do_sys_open+0x69/0x140
+<4> [<ffffffff811811f6>] ? sys_lseek+0x66/0x80
+<4> [<ffffffff8117df90>] sys_open+0x20/0x30
+<4> [<ffffffff8100b072>] system_call_fastpath+0x16/0x1b
+<4>Code: 65 48 8b 04 25 c8 cb 00 00 83 a8 44 e0 ff ff 01 5b 41 5c c9 c3 90 55 48 89 e5 53 48 83 ec 08 0f 1f 44 00 00 48 8b 9e a0 00 00 00 <48> 8b 3b e8 13 0c f7 ff 48 89 df e8 ab 3d ec e0 48 83 c4 08 31
+<1>RIP [<ffffffffa02a52c5>] nfs_closedir+0x15/0x30 [nfs]
+<4> RSP <ffff88081458bb98>
+<4>CR2: 0000000000000000
+
+I think this is ultimately due to a bug on the server. The client had
+previously found a directory dentry. It then later tried to do an atomic
+open on a new (regular file) dentry. The attributes it got back had the
+same filehandle as the previously found directory inode. It then tried
+to put the filp because it failed the aops tests for O_DIRECT opens, and
+oopsed here because the ctx was still NULL.
+
+Obviously the root cause here is a server issue, but we can take steps
+to mitigate this on the client. When nfs_fhget is called, we always know
+what type of inode it is. In the event that there's a broken or
+malicious server on the other end of the wire, the client can end up
+crashing because the wrong ops are set on it.
+
+Have nfs_find_actor check that the inode type is correct after checking
+the fileid. The fileid check should rarely ever match, so it should only
+rarely ever get to this check. In the case where we have a broken
+server, we may see two different inodes with the same i_ino, but the
+client should be able to cope with them without crashing.
+
+This should fix the oops reported here:
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=913660
+
+Reported-by: Benny Halevy <bhalevy@tonian.com>
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/inode.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -224,6 +224,8 @@ nfs_find_actor(struct inode *inode, void
+
+ if (NFS_FILEID(inode) != fattr->fileid)
+ return 0;
++ if ((S_IFMT & inode->i_mode) != (S_IFMT & fattr->mode))
++ return 0;
+ if (nfs_compare_fh(NFS_FH(inode), fh))
+ return 0;
+ if (is_bad_inode(inode) || NFS_STALE(inode))
--- /dev/null
+From 4c239ba63bccc9d0f2829815a31f7972e925ab7f Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 22 Mar 2013 11:44:04 -0700
+Subject: vfs,proc: guarantee unique inodes in /proc
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 51f0885e5415b4cc6535e9cdcc5145bfbc134353 upstream.
+
+Dave Jones found another /proc issue with his Trinity tool: thanks to
+the namespace model, we can have multiple /proc dentries that point to
+the same inode, aliasing directories in /proc/<pid>/net/ for example.
+
+This ends up being a total disaster, because it acts like hardlinked
+directories, and causes locking problems. We rely on the topological
+sort of the inodes pointed to by dentries, and if we have aliased
+directories, that odering becomes unreliable.
+
+In short: don't do this. Multiple dentries with the same (directory)
+inode is just a bad idea, and the namespace code should never have
+exposed things this way. But we're kind of stuck with it.
+
+This solves things by just always allocating a new inode during /proc
+dentry lookup, instead of using "iget_locked()" to look up existing
+inodes by superblock and number. That actually simplies the code a bit,
+at the cost of potentially doing more inode [de]allocations.
+
+That said, the inode lookup wasn't free either (and did a lot of locking
+of inodes), so it is probably not that noticeable. We could easily keep
+the old lookup model for non-directory entries, but rather than try to
+be excessively clever this just implements the minimal and simplest
+workaround for the problem.
+
+Reported-and-tested-by: Dave Jones <davej@redhat.com>
+Analyzed-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[bwh: Backported to 3.2:
+ - Adjust context
+ - Never drop the pde reference in proc_get_inode(), as callers only
+ expect this when we return an existing inode, and we never do that now]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/proc/inode.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+--- a/fs/proc/inode.c
++++ b/fs/proc/inode.c
+@@ -443,12 +443,10 @@ static const struct file_operations proc
+
+ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
+ {
+- struct inode * inode;
++ struct inode *inode = new_inode_pseudo(sb);
+
+- inode = iget_locked(sb, de->low_ino);
+- if (!inode)
+- return NULL;
+- if (inode->i_state & I_NEW) {
++ if (inode) {
++ inode->i_ino = de->low_ino;
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+ PROC_I(inode)->fd = 0;
+ PROC_I(inode)->pde = de;
+@@ -477,9 +475,7 @@ struct inode *proc_get_inode(struct supe
+ inode->i_fop = de->proc_fops;
+ }
+ }
+- unlock_new_inode(inode);
+- } else
+- pde_put(de);
++ }
+ return inode;
+ }
+