Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752493AbdHPRNC (ORCPT ); Wed, 16 Aug 2017 13:13:02 -0400 Received: from mx2.mailbox.org ([80.241.60.215]:37155 "EHLO mx2.mailbox.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752417AbdHPRNA (ORCPT ); Wed, 16 Aug 2017 13:13:00 -0400 From: Christian Brauner To: linux-kernel@vger.kernel.org, serge@hallyn.com, torvalds@linux-foundation.org, viro@zeniv.linux.org.uk Cc: Christian Brauner Subject: [PATCH 1/1] devpts: use dynamic_dname() to generate proc name Date: Wed, 16 Aug 2017 19:12:11 +0200 Message-Id: <20170816171211.4021-2-christian.brauner@ubuntu.com> In-Reply-To: <20170816171211.4021-1-christian.brauner@ubuntu.com> References: <20170816171211.4021-1-christian.brauner@ubuntu.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2664 Lines: 62 Recently the kernel has implemented the TIOCGPTPEER ioctl() call which allows users to retrieve an fd for the slave side of a pty solely based on the corresponding fd for the master side. The ioctl()-based fd retrieval however causes the "/proc//fd/" symlink to point to the wrong dentry. Currently, it will always point to "/". With the symlink pointing to the wrong path any interesting path-based operation on the slave side will fail. Also this will cause ttyname{_r}() to falsely report that this fd does not return to a tty. So I really think this needs to be fixed. The fix however doesn't seem super obvious to me. It seems the most straightforward way for now is to behave like the implementation of pipes and sockets that implement a dynamic_dname() method to correctly set the content of the "/proc//fd/" symlink without requiring special-casing in the proc implementation itself. I prefer this approach. The downside of this however is that in case the devpts is not mounted at its standard "/dev/pts" location but e.g. at "/mnt" the content of the corresponding "/proc//fd/" symlink will still be "/dev/pts/" although it should likely be "/mnt/" into their implementation of ptsname{_r}() and so wouldn't be affected by this change at all. Furthermore, mounting devpts somewhere other than "/dev/pts" (e.g. "/mnt") doesn't seem to work and from what I gather from LKML is not really expected nor supported to work. Signed-off-by: Christian Brauner --- fs/devpts/inode.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 108df2e3602c..1b1b9b0813e8 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -369,6 +369,18 @@ static const struct super_operations devpts_sops = { .show_options = devpts_show_options, }; +/* + * pty_peer_dname() is called from d_path(). + */ +static char *pty_peer_dname(struct dentry *dentry, char *buffer, int buflen) +{ + return dynamic_dname(dentry, buffer, buflen, "/dev/pts/%pd", dentry); +} + +static const struct dentry_operations devpts_dops = { + .d_dname = pty_peer_dname, +}; + static void *new_pts_fs_info(struct super_block *sb) { struct pts_fs_info *fsi; @@ -397,6 +409,7 @@ devpts_fill_super(struct super_block *s, void *data, int silent) s->s_magic = DEVPTS_SUPER_MAGIC; s->s_op = &devpts_sops; s->s_time_gran = 1; + s->s_d_op = &devpts_dops; error = -ENOMEM; s->s_fs_info = new_pts_fs_info(s); -- 2.13.3