-
Notifications
You must be signed in to change notification settings - Fork 37
Fix/add frame checks for uvc #340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is being reviewed by Cursor Bugbot
Details
Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
|
|
||
| // Check mjpeg frame start | ||
| if (uvc_stream->dynamic.vs_format.format == UVC_VS_FORMAT_MJPEG && | ||
| payload_data[0] != 0xff && payload_data[1] != 0xd8) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Wrong boolean operator in MJPEG SOI validation check
The MJPEG SOI (Start of Image) check uses && instead of ||. A valid JPEG starts with bytes 0xFF 0xD8. The current condition payload_data[0] != 0xff && payload_data[1] != 0xd8 only evaluates to true when both bytes are wrong, so frames with only one incorrect byte (like 0x00 0xD8 or 0xFF 0x00) will incorrectly pass validation. The condition needs || (OR) to skip frames where either byte is wrong.
Additional Locations (1)
| .urb_size = 10 * 1024, | ||
| }, | ||
| }; | ||
| BaseType_t task_created = xTaskCreatePinnedToCore(frame_handling_task, "mjpeg_handling", 4096, (void *)&stream_mjpeg_config, EXAMPLE_USB_HOST_PRIORITY - 2, NULL, tskNO_AFFINITY); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Stack-local config passed to task causes use-after-free
The stream_mjpeg_config and stream_h265_config variables are local to start_uvc_frame_handling_tasks() but their addresses are passed to xTaskCreatePinnedToCore. When this function returns, those stack variables go out of scope. The newly created tasks copy the config in frame_handling_task() at line 110, but there is no synchronization to ensure the task runs before the function returns. This creates a race condition where the task may read garbage from deallocated stack memory.
Additional Locations (1)
| frame_info_list[stream_index][i].v_res, | ||
| UVC_DESC_DWFRAMEINTERVAL_TO_FPS(frame_info_list[stream_index][i].default_interval)); | ||
| } | ||
| start_uvc_frame_handling_tasks(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Multiple streams trigger duplicate task creation
When EXAMPLE_NUMBER_OF_STREAMS is greater than 1, the uvc_event_cb callback is triggered separately for each stream index that connects. Each invocation calls start_uvc_frame_handling_tasks(), which unconditionally creates tasks for all streams. This results in duplicate task instances being created - for example, with 2 streams, the tasks would be created twice, causing 4 task instances instead of 2. The old code created tasks once at startup in app_main(), but the new event-driven approach lacks a guard to ensure tasks are only created once.
29d392e to
747a7ea
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is being reviewed by Cursor Bugbot
Details
Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
|
|
||
| // Check mjpeg frame start | ||
| if (uvc_stream->dynamic.vs_format.format == UVC_VS_FORMAT_MJPEG && | ||
| (payload_data[0] != 0xff || payload_data[1] != 0xd8)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: MJPEG SOI check accesses payload without bounds verification
The MJPEG SOI marker check accesses payload_data[0] and payload_data[1] without first verifying that payload_data_len >= 2. The header validation function uvc_frame_payload_header_validate only ensures packet_len > header_len, meaning the payload data could be just 1 byte. If a malformed packet arrives with exactly 1 byte of payload after the header, accessing payload_data[1] causes an out-of-bounds read.
Additional Locations (1)
| _stream_config.usb.uvc_stream_index = 1; | ||
| _stream_config.vs_format.h_res = frame_info_list[1][0].h_res; | ||
| _stream_config.vs_format.v_res = frame_info_list[1][0].v_res; | ||
| _stream_config.vs_format.fps = UVC_DESC_DWFRAMEINTERVAL_TO_FPS(frame_info_list[1][0].default_interval); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Example accesses uninitialized frame_info_list for second stream
When EXAMPLE_NUMBER_OF_STREAMS > 1, start_uvc_frame_handling_tasks() accesses frame_info_list[1][0] to read h_res, v_res, and default_interval. However, this function is called immediately after the first UVC_HOST_DRIVER_EVENT_DEVICE_CONNECTED callback for stream index 0. The second callback (for stream index 1) increments device_count to 2 and breaks early due to the "Multiple devices connected" check, so frame_info_list[1] is never populated. This results in a NULL pointer dereference.
Description
basic_uvc_streamexample to automatically open the first available formatRelated
Testing
Checklist
Before submitting a Pull Request, please ensure the following:
Note
Validate UVC headers and MJPEG SOI, harden bulk EOF handling, auto-pick first available stream format in example, relocate UVC types header, and bump to 2.4.1.
uvc_frame_payload_header_validate()and use it in ISOC/BULK paths to reject invalid payloads.examples/basic_uvc_stream):event_cbto get frame list and start tasks; auto-select first available format (derive FPS fromdefault_interval).usb_types_uvc.htoprivate_includeand update includes.2.4.1; updateCHANGELOG.md.Written by Cursor Bugbot for commit 747a7ea. This will update automatically on new commits. Configure here.