Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752835AbdFEQp4 (ORCPT ); Mon, 5 Jun 2017 12:45:56 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:60454 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753614AbdFEQaq (ORCPT ); Mon, 5 Jun 2017 12:30:46 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Johan Hovold , Rob Herring Subject: [PATCH 4.11 049/115] serdev: fix tty-port client deregistration Date: Mon, 5 Jun 2017 18:17:22 +0200 Message-Id: <20170605153059.050981476@linuxfoundation.org> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170605153056.650217313@linuxfoundation.org> References: <20170605153056.650217313@linuxfoundation.org> User-Agent: quilt/0.65 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2185 Lines: 74 4.11-stable review patch. If anyone has any objections, please let me know. ------------------ From: Johan Hovold commit aee5da7838787f8ed47f825dbe09e2812acdf97b upstream. The port client data must be set when registering the serdev controller or client deregistration will fail (and the serdev devices are left registered and allocated) if the port was never opened in between. Make sure to clear the port client data on any probe errors to avoid a use-after-free when the client is later deregistered unconditionally (e.g. in a tty-port deregistration helper). Also move port client operation initialisation to registration. Note that the client ops must be restored on failed probe. Fixes: bed35c6dfa6a ("serdev: add a tty port controller driver") Signed-off-by: Johan Hovold Reviewed-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serdev/serdev-ttyport.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) --- a/drivers/tty/serdev/serdev-ttyport.c +++ b/drivers/tty/serdev/serdev-ttyport.c @@ -101,9 +101,6 @@ static int ttyport_open(struct serdev_co return PTR_ERR(tty); serport->tty = tty; - serport->port->client_ops = &client_ops; - serport->port->client_data = ctrl; - if (tty->ops->open) tty->ops->open(serport->tty, NULL); else @@ -181,6 +178,7 @@ struct device *serdev_tty_port_register( struct device *parent, struct tty_driver *drv, int idx) { + const struct tty_port_client_operations *old_ops; struct serdev_controller *ctrl; struct serport *serport; int ret; @@ -199,15 +197,22 @@ struct device *serdev_tty_port_register( ctrl->ops = &ctrl_ops; + old_ops = port->client_ops; + port->client_ops = &client_ops; + port->client_data = ctrl; + ret = serdev_controller_add(ctrl); if (ret) - goto err_controller_put; + goto err_reset_data; dev_info(&ctrl->dev, "tty port %s%d registered\n", drv->name, idx); return &ctrl->dev; -err_controller_put: +err_reset_data: + port->client_data = NULL; + port->client_ops = old_ops; serdev_controller_put(ctrl); + return ERR_PTR(ret); }