* [PATCH 0/2] more overlayfs hard link fixes
@ 2016-05-20 20:48 Miklos Szeredi
2016-05-20 20:48 ` [PATCH 1/2] vfs: add d_real_inode() helper Miklos Szeredi
2016-05-20 20:48 ` [PATCH 2/2] af_unix: fix hard linked sockets on overlay Miklos Szeredi
0 siblings, 2 replies; 3+ messages in thread
From: Miklos Szeredi @ 2016-05-20 20:48 UTC (permalink / raw)
To: Al Viro; +Cc: linux-kernel, linux-fsdevel, David Howells
Hi Al,
Git tree (with previously posted vfs patches as well) is available here:
git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs.git d_real
Please pull.
Thanks,
Miklos
---
Miklos Szeredi (5):
vfs: add d_real_inode() helper
af_unix: fix hard linked sockets on overlay
vfs: merge .d_select_inode() into .d_real()
vfs: document ->d_real()
vfs: clean up documentation
---
Documentation/filesystems/Locking | 4 ++--
Documentation/filesystems/vfs.txt | 39 +++++++++++++++++++++++++--------------
fs/dcache.c | 3 ---
fs/namei.c | 2 +-
fs/open.c | 17 +++++++++++++----
fs/overlayfs/inode.c | 31 ++++++++++---------------------
fs/overlayfs/overlayfs.h | 2 +-
fs/overlayfs/super.c | 17 +++++++++++++----
include/linux/dcache.h | 35 ++++++++++++++++++++---------------
include/linux/fs.h | 2 +-
net/unix/af_unix.c | 6 +++---
11 files changed, 89 insertions(+), 69 deletions(-)
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] vfs: add d_real_inode() helper
2016-05-20 20:48 [PATCH 0/2] more overlayfs hard link fixes Miklos Szeredi
@ 2016-05-20 20:48 ` Miklos Szeredi
2016-05-20 20:48 ` [PATCH 2/2] af_unix: fix hard linked sockets on overlay Miklos Szeredi
1 sibling, 0 replies; 3+ messages in thread
From: Miklos Szeredi @ 2016-05-20 20:48 UTC (permalink / raw)
To: Al Viro; +Cc: linux-kernel, linux-fsdevel, David Howells
Needed by the following fix.
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Cc: <stable@vger.kernel.org>
---
include/linux/dcache.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 7e9422cb5989..ad5d582f9b14 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -576,5 +576,17 @@ static inline struct inode *vfs_select_inode(struct dentry *dentry,
return inode;
}
+/**
+ * d_real_inode - Return the real inode
+ * @dentry: The dentry to query
+ *
+ * If dentry is on an union/overlay, then return the underlying, real inode.
+ * Otherwise return d_inode().
+ */
+static inline struct inode *d_real_inode(struct dentry *dentry)
+{
+ return d_backing_inode(d_real(dentry));
+}
+
#endif /* __LINUX_DCACHE_H */
--
2.5.5
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] af_unix: fix hard linked sockets on overlay
2016-05-20 20:48 [PATCH 0/2] more overlayfs hard link fixes Miklos Szeredi
2016-05-20 20:48 ` [PATCH 1/2] vfs: add d_real_inode() helper Miklos Szeredi
@ 2016-05-20 20:48 ` Miklos Szeredi
1 sibling, 0 replies; 3+ messages in thread
From: Miklos Szeredi @ 2016-05-20 20:48 UTC (permalink / raw)
To: Al Viro; +Cc: linux-kernel, linux-fsdevel, David Howells
Overlayfs uses separate inodes even in the case of hard links on the
underlying filesystems. This is a problem for AF_UNIX socket
implementation which indexes sockets based on the inode. This resulted in
hard linked sockets not working.
The fix is to use the real, underlying inode.
Test case follows:
-- ovl-sock-test.c --
#include <unistd.h>
#include <err.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCK "test-sock"
#define SOCK2 "test-sock2"
int main(void)
{
int fd, fd2;
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
.sun_path = SOCK,
};
struct sockaddr_un addr2 = {
.sun_family = AF_UNIX,
.sun_path = SOCK2,
};
unlink(SOCK);
unlink(SOCK2);
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
err(1, "socket");
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
err(1, "bind");
if (listen(fd, 0) == -1)
err(1, "listen");
if (link(SOCK, SOCK2) == -1)
err(1, "link");
if ((fd2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
err(1, "socket");
if (connect(fd2, (struct sockaddr *) &addr2, sizeof(addr2)) == -1)
err (1, "connect");
return 0;
}
----
Reported-by: Alexander Morozov <alexandr.morozov@docker.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Cc: <stable@vger.kernel.org>
---
net/unix/af_unix.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 8269da73e9e5..7748199b3568 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -315,7 +315,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i)
&unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
struct dentry *dentry = unix_sk(s)->path.dentry;
- if (dentry && d_backing_inode(dentry) == i) {
+ if (dentry && d_real_inode(dentry) == i) {
sock_hold(s);
goto found;
}
@@ -911,7 +911,7 @@ static struct sock *unix_find_other(struct net *net,
err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
if (err)
goto fail;
- inode = d_backing_inode(path.dentry);
+ inode = d_real_inode(path.dentry);
err = inode_permission(inode, MAY_WRITE);
if (err)
goto put_fail;
@@ -1048,7 +1048,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
goto out_up;
}
addr->hash = UNIX_HASH_SIZE;
- hash = d_backing_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
+ hash = d_real_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
spin_lock(&unix_table_lock);
u->path = u_path;
list = &unix_socket_table[hash];
--
2.5.5
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-05-20 20:48 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-20 20:48 [PATCH 0/2] more overlayfs hard link fixes Miklos Szeredi
2016-05-20 20:48 ` [PATCH 1/2] vfs: add d_real_inode() helper Miklos Szeredi
2016-05-20 20:48 ` [PATCH 2/2] af_unix: fix hard linked sockets on overlay Miklos Szeredi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).