Commit 9cbef308 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull staging driver fixes from Greg KH:
 "Here are two small staging driver fixes for 5.15-rc3:

   - greybus tty use-after-free bugfix

   - r8188eu ioctl overlap build warning fix

  Note, the r8188eu ioctl has been entirely removed for 5.16-rc1, but
  it's good to get this fixed now for people using this in 5.15.

  Both of these have been in linux-next for a while with no reported
  issues"

* tag 'staging-5.15-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
  staging: r8188eu: fix -Wrestrict warnings
  staging: greybus: uart: fix tty use after free
parents f9d4be25 aa3233ea
Loading
Loading
Loading
Loading
+32 −30
Original line number Diff line number Diff line
@@ -761,6 +761,17 @@ static void gb_tty_port_shutdown(struct tty_port *port)
	gbphy_runtime_put_autosuspend(gb_tty->gbphy_dev);
}

static void gb_tty_port_destruct(struct tty_port *port)
{
	struct gb_tty *gb_tty = container_of(port, struct gb_tty, port);

	if (gb_tty->minor != GB_NUM_MINORS)
		release_minor(gb_tty);
	kfifo_free(&gb_tty->write_fifo);
	kfree(gb_tty->buffer);
	kfree(gb_tty);
}

static const struct tty_operations gb_ops = {
	.install =		gb_tty_install,
	.open =			gb_tty_open,
@@ -786,6 +797,7 @@ static const struct tty_port_operations gb_port_ops = {
	.dtr_rts =		gb_tty_dtr_rts,
	.activate =		gb_tty_port_activate,
	.shutdown =		gb_tty_port_shutdown,
	.destruct =		gb_tty_port_destruct,
};

static int gb_uart_probe(struct gbphy_device *gbphy_dev,
@@ -798,17 +810,11 @@ static int gb_uart_probe(struct gbphy_device *gbphy_dev,
	int retval;
	int minor;

	gb_tty = kzalloc(sizeof(*gb_tty), GFP_KERNEL);
	if (!gb_tty)
		return -ENOMEM;

	connection = gb_connection_create(gbphy_dev->bundle,
					  le16_to_cpu(gbphy_dev->cport_desc->id),
					  gb_uart_request_handler);
	if (IS_ERR(connection)) {
		retval = PTR_ERR(connection);
		goto exit_tty_free;
	}
	if (IS_ERR(connection))
		return PTR_ERR(connection);

	max_payload = gb_operation_get_payload_size_max(connection);
	if (max_payload < sizeof(struct gb_uart_send_data_request)) {
@@ -816,13 +822,23 @@ static int gb_uart_probe(struct gbphy_device *gbphy_dev,
		goto exit_connection_destroy;
	}

	gb_tty = kzalloc(sizeof(*gb_tty), GFP_KERNEL);
	if (!gb_tty) {
		retval = -ENOMEM;
		goto exit_connection_destroy;
	}

	tty_port_init(&gb_tty->port);
	gb_tty->port.ops = &gb_port_ops;
	gb_tty->minor = GB_NUM_MINORS;

	gb_tty->buffer_payload_max = max_payload -
			sizeof(struct gb_uart_send_data_request);

	gb_tty->buffer = kzalloc(gb_tty->buffer_payload_max, GFP_KERNEL);
	if (!gb_tty->buffer) {
		retval = -ENOMEM;
		goto exit_connection_destroy;
		goto exit_put_port;
	}

	INIT_WORK(&gb_tty->tx_work, gb_uart_tx_write_work);
@@ -830,7 +846,7 @@ static int gb_uart_probe(struct gbphy_device *gbphy_dev,
	retval = kfifo_alloc(&gb_tty->write_fifo, GB_UART_WRITE_FIFO_SIZE,
			     GFP_KERNEL);
	if (retval)
		goto exit_buf_free;
		goto exit_put_port;

	gb_tty->credits = GB_UART_FIRMWARE_CREDITS;
	init_completion(&gb_tty->credits_complete);
@@ -844,7 +860,7 @@ static int gb_uart_probe(struct gbphy_device *gbphy_dev,
		} else {
			retval = minor;
		}
		goto exit_kfifo_free;
		goto exit_put_port;
	}

	gb_tty->minor = minor;
@@ -853,9 +869,6 @@ static int gb_uart_probe(struct gbphy_device *gbphy_dev,
	init_waitqueue_head(&gb_tty->wioctl);
	mutex_init(&gb_tty->mutex);

	tty_port_init(&gb_tty->port);
	gb_tty->port.ops = &gb_port_ops;

	gb_tty->connection = connection;
	gb_tty->gbphy_dev = gbphy_dev;
	gb_connection_set_data(connection, gb_tty);
@@ -863,7 +876,7 @@ static int gb_uart_probe(struct gbphy_device *gbphy_dev,

	retval = gb_connection_enable_tx(connection);
	if (retval)
		goto exit_release_minor;
		goto exit_put_port;

	send_control(gb_tty, gb_tty->ctrlout);

@@ -890,16 +903,10 @@ static int gb_uart_probe(struct gbphy_device *gbphy_dev,

exit_connection_disable:
	gb_connection_disable(connection);
exit_release_minor:
	release_minor(gb_tty);
exit_kfifo_free:
	kfifo_free(&gb_tty->write_fifo);
exit_buf_free:
	kfree(gb_tty->buffer);
exit_put_port:
	tty_port_put(&gb_tty->port);
exit_connection_destroy:
	gb_connection_destroy(connection);
exit_tty_free:
	kfree(gb_tty);

	return retval;
}
@@ -930,15 +937,10 @@ static void gb_uart_remove(struct gbphy_device *gbphy_dev)
	gb_connection_disable_rx(connection);
	tty_unregister_device(gb_tty_driver, gb_tty->minor);

	/* FIXME - free transmit / receive buffers */

	gb_connection_disable(connection);
	tty_port_destroy(&gb_tty->port);
	gb_connection_destroy(connection);
	release_minor(gb_tty);
	kfifo_free(&gb_tty->write_fifo);
	kfree(gb_tty->buffer);
	kfree(gb_tty);

	tty_port_put(&gb_tty->port);
}

static int gb_tty_init(void)
+4 −4
Original line number Diff line number Diff line
@@ -5373,7 +5373,7 @@ static int rtw_mp_read_reg(struct net_device *dev,
			pnext++;
			if (*pnext != '\0') {
				strtout = simple_strtoul(pnext, &ptmp, 16);
				  sprintf(extra, "%s %d", extra, strtout);
				sprintf(extra + strlen(extra), " %d", strtout);
			} else {
				  break;
			}
@@ -5405,7 +5405,7 @@ static int rtw_mp_read_reg(struct net_device *dev,
			pnext++;
			if (*pnext != '\0') {
				strtout = simple_strtoul(pnext, &ptmp, 16);
				sprintf(extra, "%s %d", extra, strtout);
				sprintf(extra + strlen(extra), " %d", strtout);
			} else {
				break;
			}
@@ -5512,7 +5512,7 @@ static int rtw_mp_read_rf(struct net_device *dev,
		pnext++;
		if (*pnext != '\0') {
			  strtou = simple_strtoul(pnext, &ptmp, 16);
			  sprintf(extra, "%s %d", extra, strtou);
			  sprintf(extra + strlen(extra), " %d", strtou);
		} else {
			  break;
		}