* [PATCH] drivers: tty: Remove redundant memset() in initialize_tty_struct @ 2014-07-10 16:16 Rasmus Villemoes 2014-07-10 16:22 ` Jiri Slaby 0 siblings, 1 reply; 7+ messages in thread From: Rasmus Villemoes @ 2014-07-10 16:16 UTC (permalink / raw) To: Greg Kroah-Hartman, Jiri Slaby; +Cc: linux-kernel, Rasmus Villemoes All callers (all two) of initialize_tty_struct() have just obtained the passed tty_struct from alloc_tty_struct(), which uses kzalloc(). So there is no reason to clear the memory again. Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> --- drivers/tty/tty_io.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 3411071..8199a4e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3015,7 +3015,6 @@ static struct device *tty_get_device(struct tty_struct *tty) void initialize_tty_struct(struct tty_struct *tty, struct tty_driver *driver, int idx) { - memset(tty, 0, sizeof(struct tty_struct)); kref_init(&tty->kref); tty->magic = TTY_MAGIC; tty_ldisc_init(tty); -- 1.9.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] drivers: tty: Remove redundant memset() in initialize_tty_struct 2014-07-10 16:16 [PATCH] drivers: tty: Remove redundant memset() in initialize_tty_struct Rasmus Villemoes @ 2014-07-10 16:22 ` Jiri Slaby 2014-07-10 19:01 ` [PATCH] drivers: tty: Merge alloc_tty_struct and initialize_tty_struct Rasmus Villemoes 0 siblings, 1 reply; 7+ messages in thread From: Jiri Slaby @ 2014-07-10 16:22 UTC (permalink / raw) To: Rasmus Villemoes, Greg Kroah-Hartman; +Cc: linux-kernel On 07/10/2014 06:16 PM, Rasmus Villemoes wrote: > All callers (all two) of initialize_tty_struct() have just obtained > the passed tty_struct from alloc_tty_struct(), which uses > kzalloc(). So there is no reason to clear the memory again. Actually I don't see a reason to have initialize_tty_struct as a separate function. In both cases it is called after alloc_tty_struct. So it would make sense to move the initialization to alloc_tty_struct. (And move try_module_get before alloc_tty_struct in pty_common_install.) Could you do that? -- js suse labs ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] drivers: tty: Merge alloc_tty_struct and initialize_tty_struct 2014-07-10 16:22 ` Jiri Slaby @ 2014-07-10 19:01 ` Rasmus Villemoes 2014-07-12 10:55 ` [PATCH v2] " Rasmus Villemoes 0 siblings, 1 reply; 7+ messages in thread From: Rasmus Villemoes @ 2014-07-10 19:01 UTC (permalink / raw) To: Greg Kroah-Hartman, Jiri Slaby; +Cc: linux-kernel, Rasmus Villemoes The two functions alloc_tty_struct and initialize_tty_struct are always called together. Merge them into alloc_tty_struct, updating its prototype and the only two callers of these functions. Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> --- drivers/tty/pty.c | 19 +++++++++---------- drivers/tty/tty_io.c | 37 +++++++++++++------------------------ include/linux/tty.h | 4 +--- 3 files changed, 23 insertions(+), 37 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 25c9bc7..ac723e3 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -316,7 +316,7 @@ done: * pty_common_install - set up the pty pair * @driver: the pty driver * @tty: the tty being instantiated - * @bool: legacy, true if this is BSD style + * @legacy: true if this is BSD style * * Perform the initial set up for the tty/pty pair. Called from the * tty layer when the port is first opened. @@ -331,18 +331,17 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, int idx = tty->index; int retval = -ENOMEM; - o_tty = alloc_tty_struct(); - if (!o_tty) - goto err; ports[0] = kmalloc(sizeof **ports, GFP_KERNEL); ports[1] = kmalloc(sizeof **ports, GFP_KERNEL); if (!ports[0] || !ports[1]) - goto err_free_tty; + goto err; if (!try_module_get(driver->other->owner)) { /* This cannot in fact currently happen */ - goto err_free_tty; + goto err; } - initialize_tty_struct(o_tty, driver->other, idx); + o_tty = alloc_tty_struct(driver->other, idx); + if (!o_tty) + goto err_put_module; if (legacy) { /* We always use new tty termios data so we can do this @@ -387,12 +386,12 @@ err_free_termios: tty_free_termios(tty); err_deinit_tty: deinitialize_tty_struct(o_tty); + free_tty_struct(o_tty); +err_put_module: module_put(o_tty->driver->owner); -err_free_tty: +err: kfree(ports[0]); kfree(ports[1]); - free_tty_struct(o_tty); -err: return retval; } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 3411071..f63444d 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -157,20 +157,6 @@ static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); /** - * alloc_tty_struct - allocate a tty object - * - * Return a new empty tty structure. The data fields have not - * been initialized in any way but has been zeroed - * - * Locking: none - */ - -struct tty_struct *alloc_tty_struct(void) -{ - return kzalloc(sizeof(struct tty_struct), GFP_KERNEL); -} - -/** * free_tty_struct - free a disused tty * @tty: tty struct to free * @@ -1455,12 +1441,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) if (!try_module_get(driver->owner)) return ERR_PTR(-ENODEV); - tty = alloc_tty_struct(); + tty = alloc_tty_struct(driver, idx); if (!tty) { retval = -ENOMEM; goto err_module_put; } - initialize_tty_struct(tty, driver, idx); tty_lock(tty); retval = tty_driver_install_tty(driver, tty); @@ -3003,19 +2988,21 @@ static struct device *tty_get_device(struct tty_struct *tty) /** - * initialize_tty_struct - * @tty: tty to initialize + * alloc_tty_struct * - * This subroutine initializes a tty structure that has been newly - * allocated. + * This subroutine allocates and initializes a tty structure. * - * Locking: none - tty in question must not be exposed at this point + * Locking: none - tty in question is not exposed at this point */ -void initialize_tty_struct(struct tty_struct *tty, - struct tty_driver *driver, int idx) +struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) { - memset(tty, 0, sizeof(struct tty_struct)); + struct tty_struct *tty; + + tty = kzalloc(sizeof(*tty), GFP_KERNEL); + if (!tty) + return NULL; + kref_init(&tty->kref); tty->magic = TTY_MAGIC; tty_ldisc_init(tty); @@ -3039,6 +3026,8 @@ void initialize_tty_struct(struct tty_struct *tty, tty->index = idx; tty_line_name(driver, idx, tty->name); tty->dev = tty_get_device(tty); + + return tty; } /** diff --git a/include/linux/tty.h b/include/linux/tty.h index 1c3316a..8413294 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -477,13 +477,11 @@ extern int tty_mode_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg); extern void tty_default_fops(struct file_operations *fops); -extern struct tty_struct *alloc_tty_struct(void); +extern struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx); extern int tty_alloc_file(struct file *file); extern void tty_add_file(struct tty_struct *tty, struct file *file); extern void tty_free_file(struct file *file); extern void free_tty_struct(struct tty_struct *tty); -extern void initialize_tty_struct(struct tty_struct *tty, - struct tty_driver *driver, int idx); extern void deinitialize_tty_struct(struct tty_struct *tty); extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx); extern int tty_release(struct inode *inode, struct file *filp); -- 1.9.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2] drivers: tty: Merge alloc_tty_struct and initialize_tty_struct 2014-07-10 19:01 ` [PATCH] drivers: tty: Merge alloc_tty_struct and initialize_tty_struct Rasmus Villemoes @ 2014-07-12 10:55 ` Rasmus Villemoes 2014-07-12 12:16 ` Dan Carpenter 0 siblings, 1 reply; 7+ messages in thread From: Rasmus Villemoes @ 2014-07-12 10:55 UTC (permalink / raw) To: Greg Kroah-Hartman, Jiri Slaby, Dan Carpenter, julia.lawall Cc: linux-kernel, Rasmus Villemoes The two functions alloc_tty_struct and initialize_tty_struct are always called together. Merge them into alloc_tty_struct, updating its prototype and the only two callers of these functions. Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> --- I hope this is sufficient. Thanks, Dan and Julia! v2: Don't cause NULL pointer dereference or use-after-free on error path. Just give module_put the same argument as was given to try_module_get. drivers/tty/pty.c | 21 ++++++++++----------- drivers/tty/tty_io.c | 37 +++++++++++++------------------------ include/linux/tty.h | 4 +--- 3 files changed, 24 insertions(+), 38 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 25c9bc7..9bbdb1d 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -316,7 +316,7 @@ done: * pty_common_install - set up the pty pair * @driver: the pty driver * @tty: the tty being instantiated - * @bool: legacy, true if this is BSD style + * @legacy: true if this is BSD style * * Perform the initial set up for the tty/pty pair. Called from the * tty layer when the port is first opened. @@ -331,18 +331,17 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, int idx = tty->index; int retval = -ENOMEM; - o_tty = alloc_tty_struct(); - if (!o_tty) - goto err; ports[0] = kmalloc(sizeof **ports, GFP_KERNEL); ports[1] = kmalloc(sizeof **ports, GFP_KERNEL); if (!ports[0] || !ports[1]) - goto err_free_tty; + goto err; if (!try_module_get(driver->other->owner)) { /* This cannot in fact currently happen */ - goto err_free_tty; + goto err; } - initialize_tty_struct(o_tty, driver->other, idx); + o_tty = alloc_tty_struct(driver->other, idx); + if (!o_tty) + goto err_put_module; if (legacy) { /* We always use new tty termios data so we can do this @@ -387,12 +386,12 @@ err_free_termios: tty_free_termios(tty); err_deinit_tty: deinitialize_tty_struct(o_tty); - module_put(o_tty->driver->owner); -err_free_tty: - kfree(ports[0]); - kfree(ports[1]); free_tty_struct(o_tty); +err_put_module: + module_put(driver->other->owner); err: + kfree(ports[0]); + kfree(ports[1]); return retval; } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 3411071..f63444d 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -157,20 +157,6 @@ static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); /** - * alloc_tty_struct - allocate a tty object - * - * Return a new empty tty structure. The data fields have not - * been initialized in any way but has been zeroed - * - * Locking: none - */ - -struct tty_struct *alloc_tty_struct(void) -{ - return kzalloc(sizeof(struct tty_struct), GFP_KERNEL); -} - -/** * free_tty_struct - free a disused tty * @tty: tty struct to free * @@ -1455,12 +1441,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) if (!try_module_get(driver->owner)) return ERR_PTR(-ENODEV); - tty = alloc_tty_struct(); + tty = alloc_tty_struct(driver, idx); if (!tty) { retval = -ENOMEM; goto err_module_put; } - initialize_tty_struct(tty, driver, idx); tty_lock(tty); retval = tty_driver_install_tty(driver, tty); @@ -3003,19 +2988,21 @@ static struct device *tty_get_device(struct tty_struct *tty) /** - * initialize_tty_struct - * @tty: tty to initialize + * alloc_tty_struct * - * This subroutine initializes a tty structure that has been newly - * allocated. + * This subroutine allocates and initializes a tty structure. * - * Locking: none - tty in question must not be exposed at this point + * Locking: none - tty in question is not exposed at this point */ -void initialize_tty_struct(struct tty_struct *tty, - struct tty_driver *driver, int idx) +struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) { - memset(tty, 0, sizeof(struct tty_struct)); + struct tty_struct *tty; + + tty = kzalloc(sizeof(*tty), GFP_KERNEL); + if (!tty) + return NULL; + kref_init(&tty->kref); tty->magic = TTY_MAGIC; tty_ldisc_init(tty); @@ -3039,6 +3026,8 @@ void initialize_tty_struct(struct tty_struct *tty, tty->index = idx; tty_line_name(driver, idx, tty->name); tty->dev = tty_get_device(tty); + + return tty; } /** diff --git a/include/linux/tty.h b/include/linux/tty.h index 1c3316a..8413294 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -477,13 +477,11 @@ extern int tty_mode_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg); extern void tty_default_fops(struct file_operations *fops); -extern struct tty_struct *alloc_tty_struct(void); +extern struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx); extern int tty_alloc_file(struct file *file); extern void tty_add_file(struct tty_struct *tty, struct file *file); extern void tty_free_file(struct file *file); extern void free_tty_struct(struct tty_struct *tty); -extern void initialize_tty_struct(struct tty_struct *tty, - struct tty_driver *driver, int idx); extern void deinitialize_tty_struct(struct tty_struct *tty); extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx); extern int tty_release(struct inode *inode, struct file *filp); -- 1.9.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2] drivers: tty: Merge alloc_tty_struct and initialize_tty_struct 2014-07-12 10:55 ` [PATCH v2] " Rasmus Villemoes @ 2014-07-12 12:16 ` Dan Carpenter 2014-07-12 16:47 ` Greg Kroah-Hartman 0 siblings, 1 reply; 7+ messages in thread From: Dan Carpenter @ 2014-07-12 12:16 UTC (permalink / raw) To: Rasmus Villemoes Cc: Greg Kroah-Hartman, Jiri Slaby, julia.lawall, linux-kernel On Sat, Jul 12, 2014 at 12:55:51PM +0200, Rasmus Villemoes wrote: > The two functions alloc_tty_struct and initialize_tty_struct are > always called together. Merge them into alloc_tty_struct, updating its > prototype and the only two callers of these functions. > > Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> > --- > I hope this is sufficient. Thanks, Dan and Julia! Generally Greg's trees can't be rebased. I think you need to send a fix patch. regards, dan carpenter ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] drivers: tty: Merge alloc_tty_struct and initialize_tty_struct 2014-07-12 12:16 ` Dan Carpenter @ 2014-07-12 16:47 ` Greg Kroah-Hartman 2014-07-12 23:44 ` [PATCH] drivers: tty: Fix use-after-free in pty_common_install Rasmus Villemoes 0 siblings, 1 reply; 7+ messages in thread From: Greg Kroah-Hartman @ 2014-07-12 16:47 UTC (permalink / raw) To: Dan Carpenter; +Cc: Rasmus Villemoes, Jiri Slaby, julia.lawall, linux-kernel On Sat, Jul 12, 2014 at 03:16:13PM +0300, Dan Carpenter wrote: > On Sat, Jul 12, 2014 at 12:55:51PM +0200, Rasmus Villemoes wrote: > > The two functions alloc_tty_struct and initialize_tty_struct are > > always called together. Merge them into alloc_tty_struct, updating its > > prototype and the only two callers of these functions. > > > > Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> > > --- > > I hope this is sufficient. Thanks, Dan and Julia! > > Generally Greg's trees can't be rebased. I think you need to send a fix > patch. That is correct. Rasmus, please just send a patch on top of my tree that resolves this issue. thanks, greg k-h ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] drivers: tty: Fix use-after-free in pty_common_install 2014-07-12 16:47 ` Greg Kroah-Hartman @ 2014-07-12 23:44 ` Rasmus Villemoes 0 siblings, 0 replies; 7+ messages in thread From: Rasmus Villemoes @ 2014-07-12 23:44 UTC (permalink / raw) To: Greg Kroah-Hartman, Jiri Slaby, Dan Carpenter, julia.lawall Cc: linux-kernel, Rasmus Villemoes In 2c964a2f "drivers: tty: Merge alloc_tty_struct and initialize_tty_struct", I messed up the refactorization of pty_common_install, causing use-after-free and NULL pointer derefs on various error paths. This should fix it. Reported-by: Julia Lawall <julia.lawall@lip6.fr> Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> --- drivers/tty/pty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index ac723e3..9bbdb1d 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -388,7 +388,7 @@ err_deinit_tty: deinitialize_tty_struct(o_tty); free_tty_struct(o_tty); err_put_module: - module_put(o_tty->driver->owner); + module_put(driver->other->owner); err: kfree(ports[0]); kfree(ports[1]); -- 1.9.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2014-07-12 23:44 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-07-10 16:16 [PATCH] drivers: tty: Remove redundant memset() in initialize_tty_struct Rasmus Villemoes 2014-07-10 16:22 ` Jiri Slaby 2014-07-10 19:01 ` [PATCH] drivers: tty: Merge alloc_tty_struct and initialize_tty_struct Rasmus Villemoes 2014-07-12 10:55 ` [PATCH v2] " Rasmus Villemoes 2014-07-12 12:16 ` Dan Carpenter 2014-07-12 16:47 ` Greg Kroah-Hartman 2014-07-12 23:44 ` [PATCH] drivers: tty: Fix use-after-free in pty_common_install Rasmus Villemoes
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox