[Devel,RHEL7,COMMIT] ms/devpts: if initialization failed, don't crash when opening /dev/ptmx

Submitted by Konstantin Khorenko on Aug. 7, 2017, 12:56 p.m.

Details

Message ID 201708071256.v77Cuo8l018355@finist_cl7.x64_64.work.ct
State New
Series "Series without cover letter"
Headers show

Commit Message

Konstantin Khorenko Aug. 7, 2017, 12:56 p.m.
The commit is pushed to "branch-rh7-3.10.0-514.26.1.vz7.35.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-514.26.1.vz7.35.1
------>
commit 15e94b7c7d4b6998ab4e9546bb1ab1318d081ec2
Author: Josh Triplett <josh@joshtriplett.org>
Date:   Mon Aug 7 16:56:49 2017 +0400

    ms/devpts: if initialization failed, don't crash when opening /dev/ptmx
    
    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.
    
    [akpm@linux-foundation.org: remove unneeded static]
    Signed-off-by: Josh Triplett <josh@joshtriplett.org>
    Reported-by: Fengguang Wu <fengguang.wu@intel.com>
    Reviewed-by: Peter Hurley <peter@hurleysoftware.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    
    Cherry-pick ms commit 9ce71148b027e2bd27016139cae1c39401587695
    https://jira.sw.ru/browse/PSBM-67757
    
    Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
 fs/devpts/inode.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index c0f5f56..1940f6d 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -613,11 +613,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);
@@ -705,12 +712,16 @@  static int __init init_devpts_fs(void)
 	struct ctl_table_header *table;
 
 	if (!err) {
+		struct vfsmount *mnt;
+
 		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;