Patch "af_unix: fix hard linked sockets on overlay" has been added to the 4.6-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
af_unix: fix hard linked sockets on overlay
to the 4.6-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
af_unix-fix-hard-linked-sockets-on-overlay.patch
and it can be found in the queue-4.6 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
eb0a4a47ae89aaa0674ab3180de6a162f3be2ddfMon Sep 17 00:00:00 2001
From: Miklos Szeredi <[email protected]>
Date: Fri, 20 May 2016 22:13:45 +0200
Subject: af_unix: fix hard linked sockets on overlay
From: Miklos Szeredi <[email protected]>
commit eb0a4a47ae89aaa0674ab3180de6a162f3be2ddf upstream.
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;
}----
--- net/unix/af_unix.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/unix/af_unix.c +3 -3
@@ -315,7 +315,7 @@ static struct sock *unix_find_socket_byi &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(stru 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 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];
Patches currently in stable-queue which might be from [email protected] are
queue-4.6/vfs-add-d_real_inode-helper.patch queue-4.6/af_unix-fix-hard-linked-sockets-on-overlay.patch