libjade: handle received bytes in the same way as the serial device
What changed, and why it matters
This change updates how the libjade test/development library feeds data into the Jade firmware's message handler. Previously, large messages could be rejected outright if they exceeded the input buffer. Now, data is fed in chunks, matching how real serial-port data arrives. The commit message says this is for testing real-world communication behavior, and it explicitly notes that Bluetooth message handling is still different. There is no direct evidence in the commit that this fixes an exploitable security bug.
Review handle_data() to confirm it safely rejects oversized or malformed chunked input, since libjade_send() now delegates rejection rather than pre-checking. Treat this as a code-quality/test-fidelity improvement unless further evidence shows it addresses a reachable vulnerability.
Security signals we found
Buffer handling logic changed from reject-on-overflow to chunked streaming
Incomplete messages are no longer rejected by libjade_send(); rejection is delegated to handle_data()
SOURCE_SERIAL is now explicitly set for all libjade-injected messages
Commit message frames change as test/behavior alignment, not a security fix
Evidence from the diff
The libjade_send() function in libjade/libjade.c was rewritten to stream incoming bytes through handle_data() in chunks rather than requiring the entire message to fit in _libjade_serial_data_in at once. It now sets SOURCE_SERIAL, loops while data remains, computes remaining buffer space, copies a chunk, and calls handle_data() with reject_incomplete=false. The previous implementation returned false if size would overflow the buffer. This aligns libjade’s behavior with the actual serial device implementation and improves test fidelity. The commit message flags BLE handling as still divergent.
Changed components
libjade/libjade.clibjade_send()handle_data() message processing pathInspect captured patch +18 / −10
diff --git a/libjade/libjade.c b/libjade/libjade.c
index 16c42e9..127ae39 100644
--- a/libjade/libjade.c
+++ b/libjade/libjade.c
@@ -475,17 +475,25 @@ static uint8_t _libjade_serial_data_in[MAX_INPUT_MSG_SIZE + 1] = { 0 };
static size_t _libjade_serial_read_ptr = 0;
static TickType_t _libjade_last_processing_time = 0;
-bool libjade_send(const uint8_t* data, const size_t size)
-{
- if (_libjade_serial_read_ptr + size >= MAX_INPUT_MSG_SIZE) {
- return false;
+bool libjade_send(const uint8_t* data, size_t size)
+{
+ // Pass messages as though they come from the serial interface
+ _libjade_serial_data_in[0] = SOURCE_SERIAL;
+ while (size) {
+ const size_t remaining_bytes = MAX_INPUT_MSG_SIZE - _libjade_serial_read_ptr;
+ const size_t to_write = size > remaining_bytes ? remaining_bytes : size;
+
+ JADE_ASSERT(_libjade_serial_read_ptr + to_write <= MAX_INPUT_MSG_SIZE);
+ memcpy(_libjade_serial_data_in + 1 + _libjade_serial_read_ptr, data, to_write);
+ // Don't reject incomplete messages. If the buffer is full,
+ // handle_data() will reject the entire buffer for us. Any
+ // valid messages will be removed from the front of the buffer.
+ const bool reject_incomplete = false;
+ handle_data(_libjade_serial_data_in, &_libjade_serial_read_ptr, to_write, &_libjade_last_processing_time,
+ reject_incomplete);
+ data += to_write;
+ size -= to_write;
}
- // Pass the message through as though it came from the serial interface
- uint8_t* data_with_source = _libjade_serial_data_in;
- data_with_source[0] = SOURCE_SERIAL;
- memcpy(data_with_source + 1 + _libjade_serial_read_ptr, data, size);
- const bool reject_incomplete = false;
- handle_data(data_with_source, &_libjade_serial_read_ptr, size, &_libjade_last_processing_time, reject_incomplete);
return true;
}
Why this scored 29/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.