4 Commits
Author SHA1 Message Date
Ge-org Brohammer dd0f15bf02 tests/realtek: Cover duplicate enrollment errors
Extend the 2541:fa03 storage-error fixture to enroll the same finger
twice and assert FP_DEVICE_ERROR_DATA_DUPLICATE, reusing the device
session the delete test already opened rather than starting a second
one. Compact redundant polling transactions while preserving the
recorded protocol state changes.
2026-09-01 09:55:22 +02:00
Ge-org Brohammer 629860c965 realtek: Report duplicate enrollment as DATA_DUPLICATE
When the sensor rejects an enrollment because the finger is already
present in on-chip storage, fp_check_duplicate_cb() raises
FP_DEVICE_ERROR_PROTO. That error class means "protocol error with the
device", which is not what happened; the device answered correctly.

The practical effect is that fprintd cannot classify the failure.
It already maps FP_DEVICE_ERROR_DATA_DUPLICATE to its "enroll-duplicate"
result, so with PROTO the user is shown "enroll-unknown-error" instead of
being told to try a different finger.

Use FP_DEVICE_ERROR_DATA_DUPLICATE, which exists for exactly this case.

Reproduced on a Realtek 2541:fa03 (Minisforum AI X1 Pro) by enrolling the
same finger twice:

  [realtek] SSM Enroll failed in state 5 with error:
            Current fingerprint is duplicate!
  Device reported enroll completion (print: (nil),
            error: [FP_DEVICE_ERROR_PROTO] Current fingerprint is duplicate!)
  fprintd: enroll_cb: result enroll-unknown-error
2026-08-31 17:46:55 +00:00
Ge-org Brohammer 3a41fa7ccc tests/realtek: Cover the storage error path that returned a freed GError
Deleting a print whose template is not in the sensor's storage makes the
driver fail its task SSM, which is the path that handed an already-freed
GError to fpi_device_delete_complete(). Reading the reported error is
therefore what the test is for.

No enrollment is involved: the test deserializes a stored realtek print
whose template is deliberately not on the device, so the recording needs
no finger presses and the capture stays at 90 packets.

Without the previous commit the test dies rather than fails:

  umockdev-run ... died with <Signals.SIGSEGV: 11>
  1/1 drivers+custom - libfprint:realtek-storage-errors FAIL

The duplicate-enrollment path reaches the same bug through
fp_enroll_ssm_done(), but capturing it needs two full enrollments and
some 1.07M packets of polling traffic, so it is left out here.
2026-08-28 15:19:30 +02:00
Ge-org Brohammer 26d38779e4 realtek: Fix use-after-free of the SSM error in completion handlers
fp_verify_ssm_done(), fp_enroll_ssm_done(), fp_init_ssm_done() and
fp_delete_ssm_done() each overwrite the GError they are given:

  if (fpi_ssm_get_error (ssm))
    error = fpi_ssm_get_error (ssm);

An SSM completion callback is handed an owned copy of the error --
fpi-ssm.c takes a g_error_copy() before invoking the callback -- whereas
fpi_ssm_get_error() is documented as (transfer none), and the machine's
own error is freed by the fpi_ssm_free() that immediately follows the
callback.

Since every fpi_device_*_complete() takes the error as (transfer full),
these handlers leak the copy they own and hand the consumer a pointer
that is freed moments later. The consumer is then left reading a
dangling GError. For fprintd that is fatal: it logs error->message and
dies with a general protection fault inside strlen(), taking the
session's authentication daemon with it.

  kernel: traps: fprintd[67901] general protection fault
                 ip:7fcef3b6429c sp:7ffd5f4128a8 error:0 in libc.so.6

  #0  __strlen_evex ()
  #3  g_vasprintf () at ../glib/gprintf.c:342
  #5  g_strdup_vprintf () at ../glib/gstrfuncs.c:515
  #9  delete_enrolled_fingers (user=... "ge-org",
                               finger=FP_FINGER_RIGHT_INDEX)
        at ../src/device.c:2420
        local_error = 0x563c2628bcb0

The assignment is redundant even where it is not harmful, because the
error passed to the callback is already a copy of the machine's error;
using it directly is both correct and sufficient. fpi_ssm_dup_error()
is available for callers that do need an owned copy. No other driver in
the tree assigns the borrowed SSM error this way.

Reproduced on a Realtek 2541:fa03 (Minisforum AI X1 Pro 470) by
enrolling a finger while a template was already present in on-chip
storage, which takes the delete path shown above. The same driver bug
reaches fprintd a second way, via fp_enroll_ssm_done() ->
fpi_device_enroll_complete() -> fprintd's enroll_cb().
2026-08-28 13:30:33 +02:00