[Devel,RHEL7,COMMIT] ms/vfs: Introduce inode-getting helpers for layered/unioned fs environments

Submitted by Konstantin Khorenko on Aug. 9, 2016, 8:15 a.m.

Details

Message ID 201608090815.u798FEqQ014940@finist_cl7.x64_64.work.ct
State New
Series "overlayfs: missing detection of hardlinks in vfs_rename() on overlayfs"
Headers show

Commit Message

Konstantin Khorenko Aug. 9, 2016, 8:15 a.m.
The commit is pushed to "branch-rh7-3.10.0-327.22.2.vz7.16.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.22.2.vz7.16.3
------>
commit 9edce03cf9c588b0d2cd4ea563c3962e183b3a3b
Author: Maxim Patlasov <mpatlasov@virtuozzo.com>
Date:   Tue Aug 9 12:15:14 2016 +0400

    ms/vfs: Introduce inode-getting helpers for layered/unioned fs environments
    
    Patchset description:
    
    overlayfs: missing detection of hardlinks in vfs_rename() on overlayfs
    
    As correctly explained in CVE-2016-6198
    (https://bugzilla.redhat.com/show_bug.cgi?id=1355654):
    
    > It was found that the vfs_rename() function did not detect hard links on
    > overlayfs. A local, unprivileged user could use the rename syscall on
    > overlayfs on top of xfs to crash the system.
    
    The series backport necessary bits from upstream to fix it.
    
    Maxim Patlasov (4):
          VFS: Introduce inode-getting helpers for layered/unioned fs environments
          overlayfs: introduce d_select_inode dentry operation
          vfs: add vfs_select_inode() helper
          vfs: rename: check backing inode being equal
    
    =====================================
    This patch description:
    
    The patch backports upstream commit 155e35d4daa804582f75acaa2c74ec797a89c615:
    
    > VFS: Introduce inode-getting helpers for layered/unioned fs environments
    >
    > Introduce some function for getting the inode (and also the dentry) in an
    > environment where layered/unioned filesystems are in operation.
    >
    > The problem is that we have places where we need *both* the union dentry and
    > the lower source or workspace inode or dentry available, but we can only have
    > a handle on one of them.  Therefore we need to derive the handle to the other
    > from that.
    >
    > The idea is to introduce an extra field in struct dentry that allows the union
    > dentry to refer to and pin the lower dentry.
    >
    > Signed-off-by: David Howells <dhowells@redhat.com>
    > Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
    
    https://jira.sw.ru/browse/PSBM-47981
    
    Signed-off-by: Maxim Patlasov <mpatlasov@virtuozzo.com>
---
 include/linux/dcache.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

Patch hide | download patch | download mbox

diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index b55fb2e..2f6e4d8 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -470,4 +470,61 @@  static inline unsigned long vfs_pressure_ratio(unsigned long val)
 {
 	return mult_frac(val, sysctl_vfs_cache_pressure, 100);
 }
+
+/**
+ * d_inode - Get the actual inode of this dentry
+ * @dentry: The dentry to query
+ *
+ * This is the helper normal filesystems should use to get at their own inodes
+ * in their own dentries and ignore the layering superimposed upon them.
+ */
+static inline struct inode *d_inode(const struct dentry *dentry)
+{
+	return dentry->d_inode;
+}
+
+/**
+ * d_inode_rcu - Get the actual inode of this dentry with ACCESS_ONCE()
+ * @dentry: The dentry to query
+ *
+ * This is the helper normal filesystems should use to get at their own inodes
+ * in their own dentries and ignore the layering superimposed upon them.
+ */
+static inline struct inode *d_inode_rcu(const struct dentry *dentry)
+{
+	return ACCESS_ONCE(dentry->d_inode);
+}
+
+/**
+ * d_backing_inode - Get upper or lower inode we should be using
+ * @upper: The upper layer
+ *
+ * This is the helper that should be used to get at the inode that will be used
+ * if this dentry were to be opened as a file.  The inode may be on the upper
+ * dentry or it may be on a lower dentry pinned by the upper.
+ *
+ * Normal filesystems should not use this to access their own inodes.
+ */
+static inline struct inode *d_backing_inode(const struct dentry *upper)
+{
+	struct inode *inode = upper->d_inode;
+
+	return inode;
+}
+
+/**
+ * d_backing_dentry - Get upper or lower dentry we should be using
+ * @upper: The upper layer
+ *
+ * This is the helper that should be used to get the dentry of the inode that
+ * will be used if this dentry were opened as a file.  It may be the upper
+ * dentry or it may be a lower dentry pinned by the upper.
+ *
+ * Normal filesystems should not use this to access their own dentries.
+ */
+static inline struct dentry *d_backing_dentry(struct dentry *upper)
+{
+	return upper;
+}
+
 #endif	/* __LINUX_DCACHE_H */