mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2026-09-10 21:06:51 +00:00
uru4000: Prevent a buffer overflow on reading the device image data
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)
This commit is contained in:
committed by
Marco Trevisan
parent
63be3884d6
commit
ad8a6f6b17
@@ -681,10 +681,10 @@ calc_dev2 (struct uru4k_image *img)
|
|||||||
static void
|
static void
|
||||||
imaging_run_state (FpiSsm *ssm, FpDevice *_dev)
|
imaging_run_state (FpiSsm *ssm, FpDevice *_dev)
|
||||||
{
|
{
|
||||||
|
g_autoptr(FpImage) fpimg = NULL;
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
|
||||||
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (_dev);
|
FpiDeviceUru4000 *self = FPI_DEVICE_URU4000 (_dev);
|
||||||
struct uru4k_image *img = self->img_data;
|
struct uru4k_image *img = self->img_data;
|
||||||
FpImage *fpimg;
|
|
||||||
uint32_t key;
|
uint32_t key;
|
||||||
uint8_t flags, num_lines;
|
uint8_t flags, num_lines;
|
||||||
int i, r, to, dev2;
|
int i, r, to, dev2;
|
||||||
@@ -798,6 +798,17 @@ imaging_run_state (FpiSsm *ssm, FpDevice *_dev)
|
|||||||
num_lines = img->block_info[i].num_lines;
|
num_lines = img->block_info[i].num_lines;
|
||||||
if (num_lines == 0)
|
if (num_lines == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if ((size_t) r + num_lines > IMAGE_HEIGHT ||
|
||||||
|
(size_t) to + (size_t) num_lines * IMAGE_WIDTH > fpimg->width * fpimg->height)
|
||||||
|
{
|
||||||
|
fp_err ("bad captured image: block %d (%d lines) overflows buffer",
|
||||||
|
i, num_lines);
|
||||||
|
fpi_ssm_mark_failed (ssm,
|
||||||
|
fpi_device_error_new (FP_DEVICE_ERROR_PROTO));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy (&fpimg->data[to], &img->data[r][0],
|
memcpy (&fpimg->data[to], &img->data[r][0],
|
||||||
num_lines * IMAGE_WIDTH);
|
num_lines * IMAGE_WIDTH);
|
||||||
if (!(flags & BLOCKF_NOT_PRESENT))
|
if (!(flags & BLOCKF_NOT_PRESENT))
|
||||||
@@ -814,7 +825,8 @@ imaging_run_state (FpiSsm *ssm, FpDevice *_dev)
|
|||||||
*/
|
*/
|
||||||
if (self->profile->image_not_flipped)
|
if (self->profile->image_not_flipped)
|
||||||
fpimg->flags |= FPI_IMAGE_V_FLIPPED | FPI_IMAGE_H_FLIPPED;
|
fpimg->flags |= FPI_IMAGE_V_FLIPPED | FPI_IMAGE_H_FLIPPED;
|
||||||
fpi_image_device_image_captured (dev, fpimg);
|
|
||||||
|
fpi_image_device_image_captured (dev, g_steal_pointer (&fpimg));
|
||||||
|
|
||||||
if (self->activate_state == FPI_IMAGE_DEVICE_STATE_CAPTURE)
|
if (self->activate_state == FPI_IMAGE_DEVICE_STATE_CAPTURE)
|
||||||
fpi_ssm_jump_to_state (ssm, IMAGING_CAPTURE);
|
fpi_ssm_jump_to_state (ssm, IMAGING_CAPTURE);
|
||||||
|
|||||||
Reference in New Issue
Block a user