CAN driver: Fix a problem where the rx_sem count can grow without bounds

This commit is contained in:
Gregory Nutt 2015-07-15 18:20:08 -06:00
parent 38dee32fdc
commit 320c584888
3 changed files with 19 additions and 4 deletions

View File

@ -10725,3 +10725,6 @@
* drivers/lcd/ and include/nuttx/lcd: Modify the SSD1306 LCD driver to
support either the SPI or I2C interface. From Alan Carvalho de Assis
(2015-07-15).
* drivers/can.c: Fix an issue in the CAN driver hwere the rx_sem
count can grow beyond bounds (2015-07-15).

View File

@ -326,7 +326,14 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer,
/* Wait for a message to be received */
ret = sem_wait(&dev->cd_recv.rx_sem);
dev->cd_nrxwaiters++;
do
{
ret = sem_wait(&dev->cd_recv.rx_sem);
}
while (dev->cd_recv.rx_head == dev->cd_recv.rx_tail);
dev->cd_nrxwaiters--;
if (ret < 0)
{
ret = -get_errno();
@ -818,7 +825,11 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr,
* message buffer.
*/
sem_post(&fifo->rx_sem);
if (dev->cd_nrxwaiters > 0)
{
sem_post(&fifo->rx_sem);
}
err = OK;
}

View File

@ -206,10 +206,10 @@ struct can_rtrwait_s
{
sem_t cr_sem; /* Wait for RTR response */
uint16_t cr_id; /* The ID that is waited for */
FAR struct can_msg_s *cr_msg; /* This is where the RTR reponse goes */
FAR struct can_msg_s *cr_msg; /* This is where the RTR response goes */
};
/* This structure defines all of the operations providd by the architecture specific
/* This structure defines all of the operations provided by the architecture specific
* logic. All fields must be provided with non-NULL function pointers by the
* caller of can_register().
*/
@ -284,6 +284,7 @@ struct can_dev_s
uint8_t cd_ocount; /* The number of times the device has been opened */
uint8_t cd_npendrtr; /* Number of pending RTR messages */
uint8_t cd_ntxwaiters; /* Number of threads waiting to enqueue a message */
volatile uint8_t cd_nrxwaiters; /* Number of threads waiting to receive a message */
sem_t cd_closesem; /* Locks out new opens while close is in progress */
sem_t cd_recvsem; /* Used to wakeup user waiting for space in cd_recv.buffer */
struct can_txfifo_s cd_xmit; /* Describes transmit FIFO */