public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "Serge E. Hallyn" <serue@us.ibm.com>
To: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: gregkh@suse.de,
	Containers <containers@lists.linux-foundation.org>,
	linux-kernel@vger.kernel.org, hpa@zytor.com,
	Alan Cox <alan@lxorguk.ukuu.org.uk>
Subject: Re: [PATCH] devpts_get_tty() should validate inode
Date: Tue, 17 Nov 2009 22:03:42 -0600	[thread overview]
Message-ID: <20091118040342.GA19987@us.ibm.com> (raw)
In-Reply-To: <20091118023541.GA14430@us.ibm.com>

Quoting Sukadev Bhattiprolu (sukadev@linux.vnet.ibm.com):
> 
> devpts_get_tty() assumes that the inode passed in is associated with a valid
> pty.  But if the only reference to the pty is via a bind-mount, the inode
> passed to devpts_get_tty() while valid, would refer to a pty that no longer
> exists.
> 
> With a lot of debug effort, Grzegorz Nosek developed a small program (see
> below) to reproduce a crash on recent kernels. This crash is a regression
> introduced by the commit:
> 
> 	commit 527b3e4773628b30d03323a2cb5fb0d84441990f
> 	Author: Sukadev Bhattiprolu <sukadev@us.ibm.com>
> 	Date:   Mon Oct 13 10:43:08 2008 +0100
> 
> To fix, ensure that the dentry associated with the inode has not yet been
> deleted/unhashed by devpts_pty_kill().
> 
> See also:
> https://lists.linux-foundation.org/pipermail/containers/2009-July/019273.html 
> 
> tty-bug.c:
> 
> #define _GNU_SOURCE
> #include <fcntl.h>
> #include <sched.h>
> #include <stdlib.h>
> #include <sys/mount.h>
> #include <sys/signal.h>
> #include <unistd.h>
> #include <stdio.h>
> 
> #include <linux/fs.h>
> 
> void dummy(int sig)
> {
> }
> 
> static int child(void *unused)
> {
> 	int fd;
> 
> 	signal(SIGINT, dummy); signal(SIGHUP, dummy);
> 	pause(); /* cheesy synchronisation to wait for /dev/pts/0 to appear */
> 
> 	mount("/dev/pts/0", "/dev/console", NULL, MS_BIND, NULL);
> 	sleep(2);
> 
> 	fd = open("/dev/console", O_RDWR);
> 	dup(0); dup(0);
> 	write(1, "Hello world!\n", sizeof("Hello world!\n")-1);
> 	return 0;
> }
> 
> int main(void)
> {
> 	pid_t pid;
> 	char *stack;
> 
> 	stack = malloc(16384);
> 	pid = clone(child, stack+16384, CLONE_NEWNS|SIGCHLD, NULL);
> 
> 	open("/dev/ptmx", O_RDWR|O_NOCTTY|O_NONBLOCK);
> 
> 	unlockpt(fd); grantpt(fd);
> 
> 	sleep(2);
> 	kill(pid, SIGHUP);
> 	sleep(1);
> 	return 0; /* exit before child opens /dev/console */
> }
> 
> Reported-by: Grzegorz Nosek <root@localdomain.pl>
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>

fwiw,
Tested-by: Serge Hallyn <serue@us.ibm.com>

> ---
> Index: linux-2.6/fs/devpts/inode.c
> ===================================================================
> --- linux-2.6.orig/fs/devpts/inode.c	2009-10-20 21:11:03.000000000 -0700
> +++ linux-2.6/fs/devpts/inode.c	2009-11-17 16:07:16.000000000 -0800
> @@ -517,11 +517,23 @@
> 
>  struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number)
>  {
> +	struct dentry *dentry;
> +	struct tty_struct *tty;
> +
>  	BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
> 
> +	/* Ensure dentry has not been deleted by devpts_pty_kill() */
> +	dentry = d_find_alias(pts_inode);
> +	if (!dentry)
> +		return NULL;
> +
> +	tty = NULL;
>  	if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
> -		return (struct tty_struct *)pts_inode->i_private;
> -	return NULL;
> +		tty = (struct tty_struct *)pts_inode->i_private;
> +
> +	dput(dentry);
> +
> +	return tty;
>  }
> 
>  void devpts_pty_kill(struct tty_struct *tty)
> _______________________________________________
> Containers mailing list
> Containers@lists.linux-foundation.org
> https://lists.linux-foundation.org/mailman/listinfo/containers

      parent reply	other threads:[~2009-11-18  4:04 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-18  2:35 [PATCH] devpts_get_tty() should validate inode Sukadev Bhattiprolu
2009-11-18  3:44 ` Greg KH
2009-11-18  4:03 ` Serge E. Hallyn [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091118040342.GA19987@us.ibm.com \
    --to=serue@us.ibm.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=containers@lists.linux-foundation.org \
    --cc=gregkh@suse.de \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sukadev@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox