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.
_______________________________________________ bugs mailing list bugs@rtems.org http://lists.rtems.org/mailman/listinfo/bugs