Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp6181602pxb; Mon, 8 Nov 2021 04:36:35 -0800 (PST) X-Google-Smtp-Source: ABdhPJwS1VlvKbycqWQ9maiwEA46j18NR9K8RkWsybwdoCFPBB/gK2weBYrQaABwIPWhrWYRFpHP X-Received: by 2002:a17:906:d930:: with SMTP id rn16mr45235284ejb.223.1636374995537; Mon, 08 Nov 2021 04:36:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1636374995; cv=none; d=google.com; s=arc-20160816; b=RpJkRs1BM9x5P+OpfkNIR/LhpAYRP/DKeCkV5xYnn8alCcf3S6Gs9AhiSeEq01L3Xr uMYDY4xoDqxLSq5ICpn60N+4jnxYEVKEJdUgRNjxGaF/GNH+ObTB8cWzftJQgvn8Xivj r97qd4uVFWlIGjk+rr5H20VqMOzgkyvK3FHaFT13VqyOQAjoknuHCUvP+G6vm71nRio/ HMNdGiTuL0clXuwFc2iNi+4XpNce0FsnqQLRIKMsR20v0z2lgnaxr7I0dJOmi3ZofBcW WFiDY5fBHBiDr1SQS2/bPHrmRqFsuNGWnJOmN3Y1Kp06vimVvHn4KYk7GnIT1nXBoHHb W2zQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=qjW3YE5tzNLo5uJG4SMYSbMHYu85EZ6Z3Je3j425KlU=; b=wI/bgF8wUCK/H6n6SWQinJOAha3BvpoOLQcZd0GNZuqlqK18vDcXV2p59WFCTfnUEa gV3TC+TZrwMUWvyk3IQogaSb6pa6iQIewq7B68v/8Aan16ib48V63rXuZFVAijYknIOQ t9jooSNnQznMPXS0HijXtjN+OahLk1rPaBGSghMGDL57n7a0V8RGJme7jFwtbmi2dtHs zYodkepFoUcYh1zF1CamaP3CVeXnVEq19Tbk5lYucJieotnyEg2PaPOxCEq1KyyZsJLM 2H9obsZQUaw0HrEwPj746Lw+RfkoKlBoeTpQWqVVA1dBvB+D/07AIG0vZlp+ZxUjnOxL wvqA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=i1MGeUtU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id hd37si9412152ejc.569.2021.11.08.04.36.09; Mon, 08 Nov 2021 04:36:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=i1MGeUtU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238260AbhKHJAc (ORCPT + 99 others); Mon, 8 Nov 2021 04:00:32 -0500 Received: from mail.kernel.org ([198.145.29.99]:46594 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238257AbhKHJAc (ORCPT ); Mon, 8 Nov 2021 04:00:32 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id F09F261029; Mon, 8 Nov 2021 08:57:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1636361868; bh=4wX+AII9Jyg6qEH+gRo7jIvJFABgSTjwEbhe7sn+sAA=; h=From:To:Cc:Subject:Date:From; b=i1MGeUtUKVpbNlY0JBiAfnYuiX/FAlw/CfpbJ7ClhJTWXW/QaO6Cpl8dHS0npTjys r9ZkRwTJRmJsh5Up0j1U4WXMT5Vhe4arYzH/jWPAVGqhnK5bM4s2Y6jX7eG00B4kjz n9lL8yCxDNeTqwGzMxxABjYtWLuEzUVtvT1wrpvGgrEvf1G2i8Q39uVg19nvmqCVYp xTdBbmpkXn70Dzl63LFjg2TIXXMpComAh3VJ35AXDl/EiKBB/eiGorFmIcyKsY4uI+ 0rH5bqLYQed03vsRsro+wNQUgP5T7C2IO8XTVAWEdgiTliTTST+aKP+db1dPjoiTeG hEQtMtFpoOGuA== Received: from johan by xi.lan with local (Exim 4.94.2) (envelope-from ) id 1mk0TI-0003JJ-53; Mon, 08 Nov 2021 09:57:44 +0100 From: Johan Hovold To: Greg Kroah-Hartman Cc: Jiri Slaby , linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Johan Hovold , Baruch Siach , stable@vger.kernel.org, Rob Herring Subject: [PATCH] serial: core: fix transmit-buffer reset and memleak Date: Mon, 8 Nov 2021 09:54:31 +0100 Message-Id: <20211108085431.12637-1-johan@kernel.org> X-Mailer: git-send-email 2.32.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit 761ed4a94582 ("tty: serial_core: convert uart_close to use tty_port_close") converted serial core to use tty_port_close() but failed to notice that the transmit buffer still needs to be freed on final close. Not freeing the transmit buffer means that the buffer is no longer cleared on next open so that any ioctl() waiting for the buffer to drain might wait indefinitely (e.g. on termios changes) or that stale data can end up being transmitted in case tx is restarted. Furthermore, the buffer of any port that has been opened would leak on driver unbind. Note that the port lock is held when clearing the buffer pointer due to the ldisc race worked around by commit a5ba1d95e46e ("uart: fix race between uart_put_char() and uart_shutdown()"). Also note that the tty-port shutdown() callback is not called for console ports so it is not strictly necessary to free the buffer page after releasing the lock (cf. d72402145ace ("tty/serial: do not free trasnmit buffer page under port lock")). Reported-by: Baruch Siach Link: https://lore.kernel.org/r/319321886d97c456203d5c6a576a5480d07c3478.1635781688.git.baruch@tkos.co.il Fixes: 761ed4a94582 ("tty: serial_core: convert uart_close to use tty_port_close") Cc: stable@vger.kernel.org # 4.9 Cc: Rob Herring Signed-off-by: Johan Hovold --- drivers/tty/serial/serial_core.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 0e2e35ab64c7..58834698739c 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1542,6 +1542,7 @@ static void uart_tty_port_shutdown(struct tty_port *port) { struct uart_state *state = container_of(port, struct uart_state, port); struct uart_port *uport = uart_port_check(state); + char *buf; /* * At this point, we stop accepting input. To do this, we @@ -1563,8 +1564,18 @@ static void uart_tty_port_shutdown(struct tty_port *port) */ tty_port_set_suspended(port, 0); - uart_change_pm(state, UART_PM_STATE_OFF); + /* + * Free the transmit buffer. + */ + spin_lock_irq(&uport->lock); + buf = state->xmit.buf; + state->xmit.buf = NULL; + spin_unlock_irq(&uport->lock); + if (buf) + free_page((unsigned long)buf); + + uart_change_pm(state, UART_PM_STATE_OFF); } static void uart_wait_until_sent(struct tty_struct *tty, int timeout) -- 2.32.0