The driver relied on a running finger-detection or capture callback to
observe the deactivating flag and call complete_deactivation(). When the
async loop was broken by a session error from a terminal callback (such
as capture_sm_complete), no further iteration was left to notice the
flag, so the deactivation never completed.
Rather than scatter complete_deactivation() calls after every
fpi_image_device_session_error(), track whether an operation is actually
pending with an "active" flag and let dev_deactivate() complete the
request itself when nothing is in flight.
This keeps the deactivation lifecycle owned by dev_deactivate.
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)