All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Hurley <peter@hurleysoftware.com>
To: Josh Triplett <josh@joshtriplett.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Fengguang Wu <fengguang.wu@intel.com>,
	Iulia Manda <iulia.manda21@gmail.com>,
	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
	Fabian Frederick <fabf@skynet.be>,
	Linux Memory Management List <linux-mm@kvack.org>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] devpts: If initialization failed, don't crash when opening /dev/ptmx
Date: Thu, 07 May 2015 13:52:37 -0400	[thread overview]
Message-ID: <554BA665.5010000@hurleysoftware.com> (raw)
In-Reply-To: <20150507003547.GA6862@jtriplet-mobl1>

On 05/06/2015 08:35 PM, Josh Triplett wrote:
> If devpts failed to initialize, it would store an ERR_PTR in the global
> devpts_mnt.  A subsequent open of /dev/ptmx would call devpts_new_index,
> which would dereference devpts_mnt and crash.
> 
> Avoid storing invalid values in devpts_mnt; leave it NULL instead.
> Make both devpts_new_index and devpts_pty_new fail gracefully with
> ENODEV in that case, which then becomes the return value to the
> userspace open call on /dev/ptmx.
> 
> Signed-off-by: Josh Triplett <josh@joshtriplett.org>
> ---
> 
> This fixes a crash found by Fengguang Wu's 0-day service ("BUG: unable to
> handle kernel paging request at ffffffee").  It doesn't yet fix the underlying
> initialization failure in init_devpts_fs, but it stops that failure from
> becoming a kernel crash.  I'm working on the initialization failure now.
> 
>  fs/devpts/inode.c | 30 +++++++++++++++++++++++-------
>  1 file changed, 23 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
> index cfe8466..03e9076 100644
> --- a/fs/devpts/inode.c
> +++ b/fs/devpts/inode.c
> @@ -142,6 +142,8 @@ static inline struct super_block *pts_sb_from_inode(struct inode *inode)
>  	if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
>  		return inode->i_sb;
>  #endif
> +	if (!devpts_mnt)
> +		return NULL;
>  	return devpts_mnt->mnt_sb;
>  }
>  
> @@ -525,10 +527,14 @@ static struct file_system_type devpts_fs_type = {
>  int devpts_new_index(struct inode *ptmx_inode)
>  {
>  	struct super_block *sb = pts_sb_from_inode(ptmx_inode);
> -	struct pts_fs_info *fsi = DEVPTS_SB(sb);
> +	struct pts_fs_info *fsi;
>  	int index;
>  	int ida_ret;
>  
> +	if (!sb)
> +		return -ENODEV;
> +
> +	fsi = DEVPTS_SB(sb);
>  retry:
>  	if (!ida_pre_get(&fsi->allocated_ptys, GFP_KERNEL))
>  		return -ENOMEM;
> @@ -584,11 +590,18 @@ struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index,
>  	struct dentry *dentry;
>  	struct super_block *sb = pts_sb_from_inode(ptmx_inode);
>  	struct inode *inode;
> -	struct dentry *root = sb->s_root;
> -	struct pts_fs_info *fsi = DEVPTS_SB(sb);
> -	struct pts_mount_opts *opts = &fsi->mount_opts;
> +	struct dentry *root;
> +	struct pts_fs_info *fsi;
> +	struct pts_mount_opts *opts;
>  	char s[12];
>  
> +	if (!sb)
> +		return ERR_PTR(-ENODEV);
> +
> +	root = sb->s_root;
> +	fsi = DEVPTS_SB(sb);
> +	opts = &fsi->mount_opts;
> +
>  	inode = new_inode(sb);
>  	if (!inode)
>  		return ERR_PTR(-ENOMEM);
> @@ -676,12 +689,15 @@ static int __init init_devpts_fs(void)
>  	struct ctl_table_header *table;
>  
>  	if (!err) {
> +		static struct vfsmount *mnt;
                ^^^^^^
Not static storage. Other than that,

Reviewed-by: Peter Hurley <peter@hurleysoftware.com>

>  		table = register_sysctl_table(pty_root_table);
> -		devpts_mnt = kern_mount(&devpts_fs_type);
> -		if (IS_ERR(devpts_mnt)) {
> -			err = PTR_ERR(devpts_mnt);
> +		mnt = kern_mount(&devpts_fs_type);
> +		if (IS_ERR(mnt)) {
> +			err = PTR_ERR(mnt);
>  			unregister_filesystem(&devpts_fs_type);
>  			unregister_sysctl_table(table);
> +		} else {
> +			devpts_mnt = mnt;
>  		}
>  	}
>  	return err;
> 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

WARNING: multiple messages have this Message-ID (diff)
From: Peter Hurley <peter@hurleysoftware.com>
To: Josh Triplett <josh@joshtriplett.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Fengguang Wu <fengguang.wu@intel.com>,
	Iulia Manda <iulia.manda21@gmail.com>,
	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
	Fabian Frederick <fabf@skynet.be>,
	Linux Memory Management List <linux-mm@kvack.org>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] devpts: If initialization failed, don't crash when opening /dev/ptmx
Date: Thu, 07 May 2015 13:52:37 -0400	[thread overview]
Message-ID: <554BA665.5010000@hurleysoftware.com> (raw)
In-Reply-To: <20150507003547.GA6862@jtriplet-mobl1>

On 05/06/2015 08:35 PM, Josh Triplett wrote:
> If devpts failed to initialize, it would store an ERR_PTR in the global
> devpts_mnt.  A subsequent open of /dev/ptmx would call devpts_new_index,
> which would dereference devpts_mnt and crash.
> 
> Avoid storing invalid values in devpts_mnt; leave it NULL instead.
> Make both devpts_new_index and devpts_pty_new fail gracefully with
> ENODEV in that case, which then becomes the return value to the
> userspace open call on /dev/ptmx.
> 
> Signed-off-by: Josh Triplett <josh@joshtriplett.org>
> ---
> 
> This fixes a crash found by Fengguang Wu's 0-day service ("BUG: unable to
> handle kernel paging request at ffffffee").  It doesn't yet fix the underlying
> initialization failure in init_devpts_fs, but it stops that failure from
> becoming a kernel crash.  I'm working on the initialization failure now.
> 
>  fs/devpts/inode.c | 30 +++++++++++++++++++++++-------
>  1 file changed, 23 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
> index cfe8466..03e9076 100644
> --- a/fs/devpts/inode.c
> +++ b/fs/devpts/inode.c
> @@ -142,6 +142,8 @@ static inline struct super_block *pts_sb_from_inode(struct inode *inode)
>  	if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
>  		return inode->i_sb;
>  #endif
> +	if (!devpts_mnt)
> +		return NULL;
>  	return devpts_mnt->mnt_sb;
>  }
>  
> @@ -525,10 +527,14 @@ static struct file_system_type devpts_fs_type = {
>  int devpts_new_index(struct inode *ptmx_inode)
>  {
>  	struct super_block *sb = pts_sb_from_inode(ptmx_inode);
> -	struct pts_fs_info *fsi = DEVPTS_SB(sb);
> +	struct pts_fs_info *fsi;
>  	int index;
>  	int ida_ret;
>  
> +	if (!sb)
> +		return -ENODEV;
> +
> +	fsi = DEVPTS_SB(sb);
>  retry:
>  	if (!ida_pre_get(&fsi->allocated_ptys, GFP_KERNEL))
>  		return -ENOMEM;
> @@ -584,11 +590,18 @@ struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index,
>  	struct dentry *dentry;
>  	struct super_block *sb = pts_sb_from_inode(ptmx_inode);
>  	struct inode *inode;
> -	struct dentry *root = sb->s_root;
> -	struct pts_fs_info *fsi = DEVPTS_SB(sb);
> -	struct pts_mount_opts *opts = &fsi->mount_opts;
> +	struct dentry *root;
> +	struct pts_fs_info *fsi;
> +	struct pts_mount_opts *opts;
>  	char s[12];
>  
> +	if (!sb)
> +		return ERR_PTR(-ENODEV);
> +
> +	root = sb->s_root;
> +	fsi = DEVPTS_SB(sb);
> +	opts = &fsi->mount_opts;
> +
>  	inode = new_inode(sb);
>  	if (!inode)
>  		return ERR_PTR(-ENOMEM);
> @@ -676,12 +689,15 @@ static int __init init_devpts_fs(void)
>  	struct ctl_table_header *table;
>  
>  	if (!err) {
> +		static struct vfsmount *mnt;
                ^^^^^^
Not static storage. Other than that,

Reviewed-by: Peter Hurley <peter@hurleysoftware.com>

>  		table = register_sysctl_table(pty_root_table);
> -		devpts_mnt = kern_mount(&devpts_fs_type);
> -		if (IS_ERR(devpts_mnt)) {
> -			err = PTR_ERR(devpts_mnt);
> +		mnt = kern_mount(&devpts_fs_type);
> +		if (IS_ERR(mnt)) {
> +			err = PTR_ERR(mnt);
>  			unregister_filesystem(&devpts_fs_type);
>  			unregister_sysctl_table(table);
> +		} else {
> +			devpts_mnt = mnt;
>  		}
>  	}
>  	return err;
> 


  reply	other threads:[~2015-05-07 17:52 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-07  0:35 [PATCH] devpts: If initialization failed, don't crash when opening /dev/ptmx Josh Triplett
2015-05-07  0:35 ` Josh Triplett
2015-05-07 17:52 ` Peter Hurley [this message]
2015-05-07 17:52   ` Peter Hurley
2015-05-07 18:34   ` josh
2015-05-07 18:34     ` josh
2015-05-07 19:26 ` [PATCHv2] " Josh Triplett
2015-05-07 19:26   ` Josh Triplett
2015-05-07 22:59 ` [PATCH] " Andrew Morton
2015-05-07 22:59   ` Andrew Morton
2015-05-07 23:24   ` Peter Hurley
2015-05-07 23:24     ` Peter Hurley
2015-05-08  0:37   ` josh
2015-05-08  0:37     ` josh

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=554BA665.5010000@hurleysoftware.com \
    --to=peter@hurleysoftware.com \
    --cc=akpm@linux-foundation.org \
    --cc=fabf@skynet.be \
    --cc=fengguang.wu@intel.com \
    --cc=iulia.manda21@gmail.com \
    --cc=josh@joshtriplett.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=paulmck@linux.vnet.ibm.com \
    --cc=torvalds@linux-foundation.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.