All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Zaidman <michael.zaidman@gmail.com>
To: chrysh@christina-quast.de, daniel.beer@igorinstitute.com,
	jikos@kernel.org
Cc: linux-kernel@vger.kernel.org, linux-input@vger.kernel.org,
	linux-serial@vger.kernel.org, ilpo.jarvinen@linux.intel.com,
	johan@kernel.org, gregkh@linuxfoundation.org, equinox@diac24.net,
	michael.zaidman@gmail.com
Subject: [PATCH v1 05/19] hid-ft260: fix unprotected write_buf concurrent access
Date: Sat, 10 Feb 2024 23:51:33 +0200	[thread overview]
Message-ID: <20240210215147.77629-6-michael.zaidman@gmail.com> (raw)
In-Reply-To: <20240210215147.77629-1-michael.zaidman@gmail.com>

The UART code uses the write_buf unsafely, compromising the data integrity
of both I2C and UART channels.

The I2C channel uses the write_buf to send the HID reports. It uses mutex
to make it atomically. For UART to use this buffer, it should grab the
same mutex first. But then it will degrade the performance of both
channels. The better approach is to have a separate Tx buffer for UART.

I fixed it and briefly tested the data integrity simultaneously writing
via I2C and UART channels.

Signed-off-by: Michael Zaidman <michael.zaidman@gmail.com>
---
 drivers/hid/hid-ft260.c | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/drivers/hid/hid-ft260.c b/drivers/hid/hid-ft260.c
index 77638cae595e..3d6beac0b8b6 100644
--- a/drivers/hid/hid-ft260.c
+++ b/drivers/hid/hid-ft260.c
@@ -38,9 +38,12 @@ MODULE_PARM_DESC(debug, "Toggle FT260 debugging messages");
 			pr_info("%s: " format, __func__, ##arg);	  \
 	} while (0)
 
-#define FT260_REPORT_MAX_LENGTH (64)
-#define FT260_I2C_DATA_REPORT_ID(len) (FT260_I2C_REPORT_MIN + (len - 1) / 4)
-#define FT260_UART_DATA_REPORT_ID(len) (FT260_UART_REPORT_MIN + (len - 1) / 4)
+#define FT260_REPORT_MAX_LEN (64)
+#define FT260_DATA_REPORT_ID(min, len) (min + (len - 1) / 4)
+#define FT260_I2C_DATA_REPORT_ID(len) \
+		FT260_DATA_REPORT_ID(FT260_I2C_REPORT_MIN, len)
+#define FT260_UART_DATA_REPORT_ID(len) \
+		FT260_DATA_REPORT_ID(FT260_UART_REPORT_MIN, len)
 
 #define FT260_WAKEUP_NEEDED_AFTER_MS (4800) /* 5s minus 200ms margin */
 
@@ -56,7 +59,8 @@ MODULE_PARM_DESC(debug, "Toggle FT260 debugging messages");
  * read payload length to be 180 bytes.
  */
 #define FT260_RD_DATA_MAX (180)
-#define FT260_WR_DATA_MAX (60)
+#define FT260_WR_I2C_DATA_MAX (60)
+#define FT260_WR_UART_DATA_MAX (62)
 
 /*
  * Device interface configuration.
@@ -229,7 +233,7 @@ struct ft260_i2c_write_request_report {
 	u8 address;		/* 7-bit I2C address */
 	u8 flag;		/* I2C transaction condition */
 	u8 length;		/* data payload length */
-	u8 data[FT260_WR_DATA_MAX]; /* data payload */
+	u8 data[FT260_WR_I2C_DATA_MAX]; /* data payload */
 } __packed;
 
 struct ft260_i2c_read_request_report {
@@ -249,7 +253,7 @@ struct ft260_input_report {
 struct ft260_uart_write_request_report {
 	u8 report;		/* FT260_UART_REPORT */
 	u8 length;		/* data payload length */
-	u8 data[] __counted_by(length);	/* variable data payload */
+	u8 data[FT260_WR_UART_DATA_MAX]; /* data payload */
 } __packed;
 
 struct ft260_configure_uart_request {
@@ -318,10 +322,10 @@ struct ft260_device {
 	struct work_struct wakeup_work;
 	bool reschedule_work;
 
-
 	struct completion wait;
 	struct mutex lock;
-	u8 write_buf[FT260_REPORT_MAX_LENGTH];
+	u8 i2c_wr_buf[FT260_REPORT_MAX_LEN];
+	u8 uart_wr_buf[FT260_REPORT_MAX_LEN];
 	unsigned long need_wakeup_at;
 	u8 *read_buf;
 	u16 read_idx;
@@ -503,7 +507,7 @@ static int ft260_i2c_write(struct ft260_device *dev, u8 addr, u8 *data,
 	int ret, wr_len, idx = 0;
 	struct hid_device *hdev = dev->hdev;
 	struct ft260_i2c_write_request_report *rep =
-		(struct ft260_i2c_write_request_report *)dev->write_buf;
+		(struct ft260_i2c_write_request_report *)dev->i2c_wr_buf;
 
 	if (len < 1)
 		return -EINVAL;
@@ -511,12 +515,12 @@ static int ft260_i2c_write(struct ft260_device *dev, u8 addr, u8 *data,
 	rep->flag = FT260_FLAG_START;
 
 	do {
-		if (len <= FT260_WR_DATA_MAX) {
+		if (len <= FT260_WR_I2C_DATA_MAX) {
 			wr_len = len;
 			if (flag == FT260_FLAG_START_STOP)
 				rep->flag |= FT260_FLAG_STOP;
 		} else {
-			wr_len = FT260_WR_DATA_MAX;
+			wr_len = FT260_WR_I2C_DATA_MAX;
 		}
 
 		rep->report = FT260_I2C_DATA_REPORT_ID(wr_len);
@@ -552,7 +556,7 @@ static int ft260_smbus_write(struct ft260_device *dev, u8 addr, u8 cmd,
 	int len = 4;
 
 	struct ft260_i2c_write_request_report *rep =
-		(struct ft260_i2c_write_request_report *)dev->write_buf;
+		(struct ft260_i2c_write_request_report *)dev->i2c_wr_buf;
 
 	if (data_len >= sizeof(rep->data))
 		return -EINVAL;
@@ -1167,10 +1171,10 @@ static int ft260_uart_transmit_chars(struct ft260_device *port)
 		goto tty_out;
 	}
 
-	rep = (struct ft260_uart_write_request_report *)port->write_buf;
+	rep = (struct ft260_uart_write_request_report *)port->uart_wr_buf;
 
 	do {
-		len = min(data_len, FT260_WR_DATA_MAX);
+		len = min(data_len, FT260_WR_UART_DATA_MAX);
 
 		rep->report = FT260_UART_DATA_REPORT_ID(len);
 		rep->length = len;
-- 
2.40.1


  parent reply	other threads:[~2024-02-10 21:53 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-10 21:51 [PATCH v1 00/19] hid-ft260: Fixes for serial driver patch v4 Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 01/19] hid-ft260: fix incompatible-pointer-types error Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 02/19] hid-ft260: fix Wformat warning Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 03/19] hid-ft260: fix i2c driver regression in ft260_raw_event Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 04/19] hid-ft260: remove dead code in ft260_uart_receive_chars Michael Zaidman
2024-02-10 21:51 ` Michael Zaidman [this message]
2024-02-10 21:51 ` [PATCH v1 06/19] hid-ft260: uart: enable wakeup workaround Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 07/19] hid-ft260: depend wakeup workaround activation on uart baud rate Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 08/19] hid-ft260: depend wakeup workaround activation on eeprom config Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 09/19] hid-ft260: uart: wakeup device early to not lose rx data Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 10/19] hid-ft260: uart: do not configure baud rate twice Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 11/19] hid-ft260: uart: do not disable wakeup workaround twice Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 12/19] hid-ft260: uart: use kfifo_avail for fifo write room check Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 13/19] hid-ft260: improve usb interface type detection logic Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 14/19] hid-ft260: uart: cleanup and refactoring Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 15/19] hid-ft260: uart: remove FIXME for wake-up workaround Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 16/19] hid-ft260: uart: suppress unhandled report 0xb1 dmesg Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 17/19] hid-ft260: uart: arm wake-up timer unconditionally on tty session start Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 18/19] hid-ft260: uart: fix rx data loss after device reopening Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 19/19] hid-ft260: uart: improve write performance Michael Zaidman
2024-02-23 21:22   ` Michael Zaidman
2024-02-13 10:20 ` [PATCH v1 00/19] hid-ft260: Fixes for serial driver patch v4 Jiri Kosina
2024-02-23 13:07   ` Christina Quast

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240210215147.77629-6-michael.zaidman@gmail.com \
    --to=michael.zaidman@gmail.com \
    --cc=chrysh@christina-quast.de \
    --cc=daniel.beer@igorinstitute.com \
    --cc=equinox@diac24.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=jikos@kernel.org \
    --cc=johan@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.