Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91b32f54 authored by Peter Hurley's avatar Peter Hurley Committed by Greg Kroah-Hartman
Browse files

serial: core: Fix port count when uart_open() errors



A port count mismatch occurs if mutex_lock_interruptible()
exits uart_open() and the port has already been opened. This may
prematurely close a port on an open tty. Since uart_close() is _always_
called if uart_open() fails, the port count must be corrected if errors
occur.

Always increment the port count in uart_open(), regardless of errors;
always decrement the port count in uart_close(). Note that
tty_port_close_start() decrements the port count when uart_open()
was successful.

Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 64dbee31
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -1338,8 +1338,16 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
	struct uart_port *uport;
	unsigned long flags;

	if (!state)
	if (!state) {
		struct uart_driver *drv = tty->driver->driver_state;

		state = drv->state + tty->index;
		port = &state->port;
		spin_lock_irq(&port->lock);
		--port->count;
		spin_unlock_irq(&port->lock);
		return;
	}

	uport = state->uart_port;
	port = &state->port;
@@ -1556,6 +1564,10 @@ static int uart_open(struct tty_struct *tty, struct file *filp)

	pr_debug("uart_open(%d) called\n", line);

	spin_lock_irq(&port->lock);
	++port->count;
	spin_unlock_irq(&port->lock);

	/*
	 * We take the semaphore here to guarantee that we won't be re-entered
	 * while allocating the state structure, or while we request any IRQs
@@ -1568,17 +1580,11 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
		goto end;
	}

	port->count++;
	if (!state->uart_port || state->uart_port->flags & UPF_DEAD) {
		retval = -ENXIO;
		goto err_dec_count;
		goto err_unlock;
	}

	/*
	 * Once we set tty->driver_data here, we are guaranteed that
	 * uart_close() will decrement the driver module use count.
	 * Any failures from here onwards should not touch the count.
	 */
	tty->driver_data = state;
	state->uart_port->state = state;
	state->port.low_latency =
@@ -1599,8 +1605,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)

end:
	return retval;
err_dec_count:
	port->count--;
err_unlock:
	mutex_unlock(&port->mutex);
	goto end;
}