aeslib: Fix use-after-free in aeslib

If a USB transfer is started but not completed in one go, the wdata we
pass to continue_write_regv() will already be freed by the time we try
to use it again.

Only free() the wdata on error, or when the USB transfer is completed.

Closes: #180
This commit is contained in:
Bastien Nocera 2019-08-08 14:17:15 +02:00
parent 658c301e3c
commit c11126181e

View file

@ -53,12 +53,15 @@ static void write_regv_trf_complete(struct libusb_transfer *transfer)
{ {
struct write_regv_data *wdata = transfer->user_data; struct write_regv_data *wdata = transfer->user_data;
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
wdata->callback(wdata->imgdev, -EIO, wdata->user_data); wdata->callback(wdata->imgdev, -EIO, wdata->user_data);
else if (transfer->length != transfer->actual_length) g_free(wdata);
} else if (transfer->length != transfer->actual_length) {
wdata->callback(wdata->imgdev, -EPROTO, wdata->user_data); wdata->callback(wdata->imgdev, -EPROTO, wdata->user_data);
else g_free(wdata);
} else {
continue_write_regv(wdata); continue_write_regv(wdata);
}
g_free(transfer->buffer); g_free(transfer->buffer);
libusb_free_transfer(transfer); libusb_free_transfer(transfer);
@ -109,6 +112,7 @@ static void continue_write_regv(struct write_regv_data *wdata)
if (offset >= wdata->num_regs) { if (offset >= wdata->num_regs) {
fp_dbg("all registers written"); fp_dbg("all registers written");
wdata->callback(wdata->imgdev, 0, wdata->user_data); wdata->callback(wdata->imgdev, 0, wdata->user_data);
g_free(wdata);
return; return;
} }
if (wdata->regs[offset].reg) if (wdata->regs[offset].reg)
@ -132,6 +136,7 @@ static void continue_write_regv(struct write_regv_data *wdata)
r = do_write_regv(wdata, upper_bound); r = do_write_regv(wdata, upper_bound);
if (r < 0) { if (r < 0) {
wdata->callback(wdata->imgdev, r, wdata->user_data); wdata->callback(wdata->imgdev, r, wdata->user_data);
g_free(wdata);
return; return;
} }
@ -155,8 +160,6 @@ void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs,
wdata->callback = callback; wdata->callback = callback;
wdata->user_data = user_data; wdata->user_data = user_data;
continue_write_regv(wdata); continue_write_regv(wdata);
g_free(wdata);
} }
unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx, unsigned char aes_get_pixel(struct fpi_frame_asmbl_ctx *ctx,