Skip to contentSkip to conversation

unix: Introduce /proc/net/unix_peers file

PATCH In review Pavel Emelyanov 2 participants 6 messages Dec 1, 2011 – Dec 5, 2011

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover unix: Introduce /proc/net/unix_peers file

Hi.

There's a common problem with unix sockets -- there's no way to determine which tasks are connected to each other with a unix socket. Although the /proc/<pid>/fd/<n> symlink shows a socket inode number, the peers do not share an inode and thus these numbers give no answer.

There have been an attempt last year to print the peer=<number> for unbound sockets in the existing /proc/net/unix file, but it was left unfinished and had problems with bound sockets - for those the peer inode was still unknown and the name didn't help at all.

I'd like to have this ability (determining the unix connection endpoints) implemented and propose to introduce a /proc/net/unix_peers file with socket inode number pairs. For not connected sockets 0 is printed.

Are there strong objections against this approach?

Patches apply to net-next tree.

#1 lore raw

PATCH 1/2 unix: Reformat proc files creation

This just makes codepaths better prepared for yet another proc file creation.

---
 net/unix/af_unix.c |   34 +++++++++++++++++++++++++++-------
 1 files changed, 27 insertions(+), 7 deletions(-)
net/unix/af_unix.c +27 -7
index 466fbcc..4b83a9c 100644
@@ -2326,6 +2326,29 @@ static const struct file_operations unix_seq_fops = {
 	.release	= seq_release_net,
 };
 
+static int unix_proc_create(struct net *net)
+{
+	if (!proc_net_fops_create(net, "unix", 0, &unix_seq_fops))
+		goto out;
+
+	return 0;
+out:
+	return -ENOMEM;
+}
+
+static void unix_proc_destroy(struct net *net)
+{
+	proc_net_remove(net, "unix");
+}
+#else
+static inline int unix_proc_create(struct net *net)
+{
+	return 0;
+}
+
+static inline void unix_proc_destroy(struct net *net)
+{
+}
 #endif
 
 static const struct net_proto_family unix_family_ops = {
@@ -2343,13 +2366,10 @@ static int __net_init unix_net_init(struct net *net)
 	if (unix_sysctl_register(net))
 		goto out;
 
-#ifdef CONFIG_PROC_FS
-	if (!proc_net_fops_create(net, "unix", 0, &unix_seq_fops)) {
+	error = unix_proc_create(net);
+	if (error)
 		unix_sysctl_unregister(net);
-		goto out;
-	}
-#endif
-	error = 0;
+
 out:
 	return error;
 }
@@ -2357,7 +2377,7 @@ out:
 static void __net_exit unix_net_exit(struct net *net)
 {
 	unix_sysctl_unregister(net);
-	proc_net_remove(net, "unix");
+	unix_proc_destroy(net);
 }
 
 static struct pernet_operations unix_net_ops = {
Signature · 1 line
1.5.5.6
#2 lore raw

PATCH 2/2 unix: Add /proc/net/unix_peers file

In reply to Pavel Emelyanov

Currently it's not possible to find out what processes are connected to each other via a unix socket. In the proposed proc file a socket inode number and its peer inode number are shown. With these two at hands it's possible to determine the unix connections endpoints.

---
 net/unix/af_unix.c |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 55 insertions(+), 0 deletions(-)
net/unix/af_unix.c +55 -0
index 4b83a9c..4ce425a 100644
@@ -2305,6 +2305,33 @@ static int unix_seq_show(struct seq_file *seq, void *v)
 	return 0;
 }
 
+static int unix_peers_seq_show(struct seq_file *seq, void *v)
+{
+	struct sock *s = v, *peer;
+	unsigned long ino, peer_ino = 0;
+
+	if (v == SEQ_START_TOKEN)
+		return 0;
+
+	unix_state_lock(s);
+	ino = sock_i_ino(s);
+	peer = unix_peer(s);
+	if (peer)
+		sock_hold(peer);
+	unix_state_unlock(s);
+
+	if (peer) {
+		unix_state_lock(peer);
+		peer_ino = sock_i_ino(peer);
+		unix_state_unlock(peer);
+
+		sock_put(peer);
+	}
+
+	seq_printf(seq, "%5lu %5lu\n", ino, peer_ino);
+	return 0;
+}
+
 static const struct seq_operations unix_seq_ops = {
 	.start  = unix_seq_start,
 	.next   = unix_seq_next,
@@ -2326,18 +2353,46 @@ static const struct file_operations unix_seq_fops = {
 	.release	= seq_release_net,
 };
 
+static const struct seq_operations unix_peers_seq_ops = {
+	.start  = unix_seq_start,
+	.next   = unix_seq_next,
+	.stop   = unix_seq_stop,
+	.show   = unix_peers_seq_show,
+};
+
+static int unix_peers_seq_open(struct inode *inode, struct file *file)
+{
+	return seq_open_net(inode, file, &unix_peers_seq_ops,
+			    sizeof(struct unix_iter_state));
+}
+
+static const struct file_operations unix_peers_seq_fops = {
+	.owner		= THIS_MODULE,
+	.open		= unix_peers_seq_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release_net,
+};
+
 static int unix_proc_create(struct net *net)
 {
 	if (!proc_net_fops_create(net, "unix", 0, &unix_seq_fops))
 		goto out;
 
+	if (!proc_net_fops_create(net, "unix_peers", 0, &unix_peers_seq_fops))
+		goto out_peers;
+
 	return 0;
+
+out_peers:
+	proc_net_remove(net, "unix");
 out:
 	return -ENOMEM;
 }
 
 static void unix_proc_destroy(struct net *net)
 {
+	proc_net_remove(net, "unix_peers");
 	proc_net_remove(net, "unix");
 }
 #else
Signature · 1 line
1.5.5.6
maintainer
#3 lore raw

Re: [PATCH 2/2] unix: Add /proc/net/unix_peers file

From: Pavel Emelyanov <[email protected]>
Date: Thu, 01 Dec 2011 21:42:06 +0400

Quoted 6 lines

Currently it's not possible to find out what processes are connected to each other via a unix socket. In the proposed proc file a socket inode number and its peer inode number are shown. With these two at hands it's possible to determine the unix connections endpoints.

I'm basically against new networking procfs based information retrieval mechanisms.

Please extend the netlink socket dumping so that it works with AF_UNIX sockets and subsequently added the necessary netlink attribute to provide the peer value.

I plan to stand pretty firm on this, so you may want to save your effort and use said effort to implement this properly.

Thanks.

#4 lore raw

Re: [PATCH 2/2] unix: Add /proc/net/unix_peers file

Quoted 8 lines · David Miller

From: Pavel Emelyanov <[email protected]>
Date: Thu, 01 Dec 2011 21:42:06 +0400

Quoted 5 lines

Currently it's not possible to find out what processes are connected to each other via a unix socket. In the proposed proc file a socket inode number and its peer inode number are shown. With these two at hands it's possible to determine the unix connections endpoints.

Quoted 4 lines
Quoted 1 line

I'm basically against new networking procfs based information retrieval mechanisms.

So am I, just wanted to bring this topic up again.

Quoted 3 lines

Please extend the netlink socket dumping so that it works with AF_UNIX sockets and subsequently added the necessary netlink attribute to provide the peer value.

OK, will do it this way. AFAIU you're talking about the NETLINK_INET_DIAG, right?

Quoted 6 lines

I plan to stand pretty firm on this, so you may want to save your effort and use said effort to implement this properly.

Thanks.
.

Thanks,
Pavel

maintainer
#5 lore raw

Re: [PATCH 2/2] unix: Add /proc/net/unix_peers file

From: Pavel Emelyanov <[email protected]>
Date: Mon, 05 Dec 2011 14:25:11 +0400

Quoted 6 lines · David Miller
Quoted 3 lines

Please extend the netlink socket dumping so that it works with AF_UNIX sockets and subsequently added the necessary netlink attribute to provide the peer value.

OK, will do it this way. AFAIU you're talking about the NETLINK_INET_DIAG, right?

Yes.

If that framework, for some reason, doesn't fit AF_UNIX sockets well or needs to be genericized, please feel free to do whatever you think is necessary to address that.

Thanks.