bluetooth: hci: spi: avoid rxmsg re-use

Don't re-use the `rxmsg` buffer in the `bt_spi_send` function. This
buffer is still used by the RX thread after releasing the SPI semaphore.
The current re-use can result in buffer corruption if the RX thread is
swapped out as a result of the `k_sem_give`.

Moving the semaphore release later can result in deadlocks due to
buffer allocation being performed while holding the semaphore, so
instead just eliminate the re-use entirely.

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
This commit is contained in:
Jordan Yates 2023-10-19 15:47:47 +10:00 committed by Carles Cufí
commit 322d4c1f98

View file

@ -417,7 +417,9 @@ static void bt_spi_rx_thread(void)
static int bt_spi_send(struct net_buf *buf)
{
uint8_t header[5] = { SPI_WRITE, 0x00, 0x00, 0x00, 0x00 };
uint8_t header_tx[5] = { SPI_WRITE, 0x00, 0x00, 0x00, 0x00 };
uint8_t header_rx[5];
uint8_t rx_first[1];
int ret;
LOG_DBG("");
@ -447,22 +449,22 @@ static int bt_spi_send(struct net_buf *buf)
/* Poll sanity values until device has woken-up */
do {
kick_cs();
ret = bt_spi_transceive(header, 5, rxmsg, 5);
ret = bt_spi_transceive(header_tx, 5, header_rx, 5);
/*
* RX Header (rxmsg) must contain a sanity check Byte and size
* RX Header must contain a sanity check Byte and size
* information. If it does not contain BOTH then it is
* sleeping or still in the initialisation stage (waking-up).
*/
} while ((rxmsg[STATUS_HEADER_READY] != READY_NOW ||
(rxmsg[1] | rxmsg[2] | rxmsg[3] | rxmsg[4]) == 0U) && !ret);
} while ((header_rx[STATUS_HEADER_READY] != READY_NOW ||
(header_rx[1] | header_rx[2] | header_rx[3] | header_rx[4]) == 0U) && !ret);
if (!ret) {
/* Transmit the message */
do {
ret = bt_spi_transceive(buf->data, buf->len,
rxmsg, buf->len);
} while (rxmsg[0] == 0U && !ret);
rx_first, 1);
} while (rx_first[0] == 0U && !ret);
}
release_cs();