When tapping on the sensor rather than swiping through it, super RSR will
drop slices with 0-3 pixels of Y motion. In such case, self->strips_len is
zero and causing protocol error. Handle such cases by calling for a re-scan.
Closes: https://gitlab.freedesktop.org/libfprint/libfprint/-/work_items/786
Assisted-by: DeepSeek:deepseek-v4-pro-preview
Signed-off-by: Shengyu Qu <wiagn@4d2.org>
In some cases, the driver generates error, but complete_deactivation() is not
called after calling fpi_image_device_session_error(). In this case, fprintd
would be waiting for fpi_image_device_deactivate_complete() forever. Fix by
adding calls for complete_deactivation();
Closes: https://gitlab.freedesktop.org/libfprint/libfprint/-/work_items/786
Assisted-by: DeepSeek:deepseek-v4-pro-preview
Signed-off-by: Shengyu Qu <wiagn@4d2.org>
We cannot assume that two NBIS prints are matching without going through
proper NBIS checks, so we cannot do a check on the scanned print without
an extra thread, which is rather an overkill.
So let's just do the check for prints we can actually compare (raw ones
for now)
We used to enroll and verify always the same prints, which made
generating the very same enrolled prints, that simplifies the libfprint
matching.
To make this a bit more real, let's apply some transformations to the
print images before sending them each time
The device may report a number of enrolled fingers but this value is not
checked against the data, so let's do it to prevent an overflow
Reported by: Keith Linneman (LinnemanLabs)
The message parser trusted the device-supplied payload length without
checking it against the number of bytes actually received.
A malicious or malfunctioning reader could thus drive an out-of-bounds
read past the received buffer.
Reject a header whose declared payload would extend past the received
data (and a too-short header).
Reported by: Keith Linneman (LinnemanLabs)
The frame length and the offset (which depends on the device-supplied
frame type) are derived from device bytes, so validate both the source
read (against the response buffer) and the destination write (against
the image buffer) before copying.
A malicious or malfunctioning device could otherwise drive a negative
(huge once unsigned) or out-of-bounds length.
Note: the response is reassembled across several USB transfers, so the
bound here is the response buffer capacity rather than a single
transfer's actual_length.
Reported by: Keith Linneman (LinnemanLabs)
num_lines comes from the device for each block and is summed into
the source row index (r) and destination byte offset (to).
Neither the per-block value nor the running totals are otherwise bound,
so a malicious device could drive the copy past the source
(IMAGE_HEIGHT rows) or destination buffer.
Reported by: Keith Linneman (LinnemanLabs)
The SSM error is stolen and then we pass to the resume/suspend callback
potentially leading to a double-free.
So copy it before re-using it.
Reported by: Keith Linneman (LinnemanLabs)
fp_device_finalize calls g_slist_free_full() to destroy any still-pending
timeout sources.
Each g_source_destroy call triggers timeout_finalize, which tries to
remove the current source from the sources list.
This may lead to a double-free, as iterating over a list deleting items
is not supported.
Add a regression test that adds a timeout with a long delay and immediately
finalizes the device while the timeout is still pending.
The slack of 250ms wasn't enough on loaded CI systems, causing frequent
flaky failures (e.g. 2276ms actual vs 2250ms limit, or 2294ms vs 2250ms).
Double the slacks to 500ms for the 2s transitions and 1000ms for the
5s transition to absorb system load noise while still catching real
timing regressions.