RTEMS | CAN Bus Coverity Flagged Access Past End of Array (#5248)
Joel Sherrill (@joel)
gitlab at rtems.org
Fri May 16 19:42:38 UTC 2025
Joel Sherrill created an issue: https://gitlab.rtems.org/rtems/rtos/rtems/-/issues/5248
Assignee: Gedare Bloom
## Summary
Coverity Scan [1642617](https://scan5.scan.coverity.com/#/project-view/30909/10069?selectedIssue=1642617) identifies a write past the end of a buffer in ctucanfd.c.
```
1. Condition rtems_can_test_bit(1, &chip->flags) == 0, taking false branch.
7. Condition rtems_can_test_bit(1, &chip->flags) == 0, taking false branch.
1297 if ( rtems_can_test_bit( RTEMS_CAN_CHIP_RUNNING, &chip->flags ) == 0 ) {
1298 /* Abort all filled HW buffers. */
1299 for ( int i = 0; i < internal->txb_prio_tail[0]; i++ ) {
1300 txtb_id = ctucanfd_txb_from_order( internal->txb_order, i );
1301
1302 if ( ctucanfd_get_tx_status( internal, txtb_id ) == TXT_ETY ) {
1303 txb_info = &internal->txb_info[txtb_id];
1304 if ( txb_info != NULL ) {
1305 rtems_can_queue_filter_frame_to_edges(
1306 &chip->qends_dev->base,
1307 txb_info->edge,
1308 &txb_info->slot->frame,
1309 CAN_FRAME_TXERR
1310 );
1311 rtems_can_queue_free_outslot(
1312 &chip->qends_dev->base,
1313 txb_info->edge,
1314 txb_info->slot
1315 );
1316 txb_info->slot = NULL;
1317 txb_info->edge = NULL;
1318 ctucanfd_txb_free( internal, i );
1319 }
1320 } else {
1321 ctucanfd_give_txtb_cmd( internal, TXT_CMD_SET_ABORT, txtb_id );
1322 abort_recheck = 1;
1323 }
1324 }
1325
1326 /* Clear the FIFOs filled with frames to be sent. */
1327 while ( rtems_can_queue_test_outslot( qends, &qedge, &slot ) >= 0 ) {
1328 /* Filter these frames back to the application as TX error frames. */
1329 rtems_can_queue_filter_frame_to_edges(
1330 &chip->qends_dev->base,
1331 qedge,
1332 &slot->frame,
1333 CAN_FRAME_TXERR
1334 );
1335 rtems_can_queue_free_outslot(
1336 &chip->qends_dev->base,
1337 qedge,
1338 slot
1339 );
1340 rtems_can_stats_add_tx_error( &chip->chip_stats );
1341 }
1342
1343 if ( internal->txb_prio_tail[0] == 0 ) {
1344 /* Notify the stop function all frames were aborted/sent back */
1345 rtems_binary_semaphore_post( &chip->stop_sem );
1346 }
2. Condition internal->txb_prio_tail[0] < internal->ntxbufs, taking true branch.
8. Condition internal->txb_prio_tail[0] < internal->ntxbufs, taking true branch.
1347 } else if ( internal->txb_prio_tail[0] < internal->ntxbufs ) {
1348 /* We have some space in HW buffers for outgoing messages,
1349 * chek whether there is something to send.
1350 */
1351 ret = rtems_can_queue_test_outslot( qends, &qedge, &slot );
3. Condition ret >= 0, taking true branch.
9. Condition ret >= 0, taking true branch.
1352 if ( ret >= 0 ) {
1353 unsigned int txb_order_idx = internal->txb_prio_tail[0];
10. assignment: Assigning: txtb_id = ctucanfd_txb_from_order(internal->txb_order, txb_order_idx). The value of txtb_id may now be up to 15.
1354 unsigned int txtb_id = ctucanfd_txb_from_order (
1355 internal->txb_order,
1356 txb_order_idx
1357 );
1358 ctucanfd_check_state( internal, "before insert_frame" );
1359 /* Insert frame to HW buffer */
1360 bool ok = ctucanfd_insert_frame( internal, &slot->frame, txtb_id );
4. Condition ok == 1, taking false branch.
11. Condition ok == 1, taking true branch.
1361 if ( ok == true ) {
1362 /* Frame inserted succesfully, update TX buffer representation,
1363 * buffer priorities and set buffer as ready.
1364 */
12. alias: Assigning: txb_info = &internal->txb_info[txtb_id]. txb_info may now point to as high as element 15 of internal->txb_info (which consists of 8 8-byte elements).
1365 txb_info = &internal->txb_info[txtb_id];
CID 1642617: (#1 of 1): Out-of-bounds write (OVERRUN)
13. overrun-local: Overrunning array of 64 bytes at byte offset 120 by dereferencing pointer txb_info.
1366 txb_info->edge = qedge;
1367 txb_info->slot = slot;
1368 ctucanfd_txb_add( internal, txb_order_idx, qedge->edge_prio );
1369 ctucanfd_write32(
1370 internal,
1371 CTUCANFD_TX_PRIORITY,
1372 ctucanfd_txb_order2prio( internal->txb_order )
1373 );
1374 ctucanfd_give_txtb_cmd( internal, TXT_CMD_SET_READY, txtb_id );
1375 ctucanfd_give_txtb_cmd( internal, TXT_CMD_SET_READY, txtb_id );
1376 ctucanfd_check_state( internal, "after insert_frame succeed" );
1377 continue;
1378 } else {
1379 /* Insert failed, schedule frame for later processing */
1380 ctucanfd_check_state( internal, "before insert_frame failed" );
1381 rtems_can_queue_push_back_outslot( qends, qedge, slot );
1382 }
1383 }
5. Falling through to end of if statement.
1384 } else {
1385 /* There is no free space in HW buffers. Check whether pending
1386 * message has higher priority class then some message in HW buffers.
1387 */
1388 int pending_prio = -1;
1389 int avail_prio;
1390 for (
1391 avail_prio = 1;
1392 avail_prio < RTEMS_CAN_QUEUE_PRIO_NR;
1393 avail_prio++
1394 ) {
1395 if ( internal->txb_prio_tail[avail_prio] < internal->ntxbufs ) {
1396 pending_prio = rtems_can_queue_pending_outslot_prio(
1397 qends,
1398 avail_prio
1399 );
1400 break;
1401 }
1402 }
```
## Steps to reproduce
### Pre-set options
--
View it on GitLab: https://gitlab.rtems.org/rtems/rtos/rtems/-/issues/5248
You're receiving this email because of your account on gitlab.rtems.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/bugs/attachments/20250516/9c183f06/attachment.htm>
More information about the bugs
mailing list