1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-04-09 11:55:58 +00:00

feat(core): improve display/dma2d syscall verifiers

[no changelog]
This commit is contained in:
cepetr 2025-03-03 16:33:10 +01:00 committed by cepetr
parent 8574289493
commit bf119fbee4
9 changed files with 190 additions and 0 deletions
core/embed
gfx
bitblt/stm32
inc/gfx
io/display
sys/mpu/stm32u5

View File

@ -109,6 +109,10 @@ bool dma2d_rgb565_fill(const gfx_bitblt_t* bb) {
return false;
}
if (!gfx_bitblt_check_dst_x(bb, 16)) {
return false;
}
dma2d_wait();
if (!dma2d_accessible(bb->dst_row)) {
@ -233,6 +237,11 @@ bool dma2d_rgb565_copy_mono4(const gfx_bitblt_t* params) {
return false;
}
if (!gfx_bitblt_check_dst_x(params, 16) ||
!gfx_bitblt_check_src_x(params, 4)) {
return false;
}
const gfx_color16_t* src_gradient = NULL;
gfx_bitblt_t bb_copy = *params;
@ -291,6 +300,10 @@ bool dma2d_rgb565_copy_rgb565(const gfx_bitblt_t* bb) {
return false;
}
if (!gfx_bitblt_check_dst_x(bb, 16) || !gfx_bitblt_check_src_x(bb, 16)) {
return false;
}
dma2d_wait();
if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) {
@ -355,6 +368,11 @@ bool dma2d_rgb565_blend_mono4(const gfx_bitblt_t* params) {
return false;
}
if (!gfx_bitblt_check_dst_x(params, 16) ||
!gfx_bitblt_check_src_x(params, 4)) {
return false;
}
dma2d_wait();
gfx_bitblt_t bb_copy = *params;
@ -421,6 +439,10 @@ bool dma2d_rgb565_blend_mono8(const gfx_bitblt_t* bb) {
return false;
}
if (!gfx_bitblt_check_dst_x(bb, 16) || !gfx_bitblt_check_src_x(bb, 8)) {
return false;
}
dma2d_wait();
if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) {
@ -460,6 +482,10 @@ bool dma2d_rgba8888_fill(const gfx_bitblt_t* bb) {
return false;
}
if (!gfx_bitblt_check_dst_x(bb, 32)) {
return false;
}
dma2d_wait();
if (!dma2d_accessible(bb->dst_row)) {
@ -547,6 +573,11 @@ bool dma2d_rgba8888_copy_mono4(const gfx_bitblt_t* params) {
return false;
}
if (!gfx_bitblt_check_dst_x(params, 32) ||
!gfx_bitblt_check_src_x(params, 4)) {
return false;
}
dma2d_wait();
const gfx_color32_t* src_gradient = NULL;
@ -606,6 +637,10 @@ bool dma2d_rgba8888_copy_rgb565(const gfx_bitblt_t* bb) {
return false;
}
if (!gfx_bitblt_check_dst_x(bb, 32) || !gfx_bitblt_check_src_x(bb, 16)) {
return false;
}
dma2d_wait();
if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) {
@ -670,6 +705,11 @@ bool dma2d_rgba8888_blend_mono4(const gfx_bitblt_t* params) {
return false;
}
if (!gfx_bitblt_check_dst_x(params, 32) ||
!gfx_bitblt_check_src_x(params, 4)) {
return false;
}
dma2d_wait();
gfx_bitblt_t bb_copy = *params;
@ -736,6 +776,10 @@ bool dma2d_rgba8888_blend_mono8(const gfx_bitblt_t* bb) {
return false;
}
if (!gfx_bitblt_check_dst_x(bb, 32) || !gfx_bitblt_check_src_x(bb, 8)) {
return false;
}
dma2d_wait();
if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) {
@ -775,6 +819,10 @@ bool dma2d_rgba8888_copy_mono8(const gfx_bitblt_t* bb) {
return false;
}
if (!gfx_bitblt_check_dst_x(bb, 32) || !gfx_bitblt_check_src_x(bb, 8)) {
return false;
}
dma2d_wait();
if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) {
@ -806,6 +854,10 @@ bool dma2d_rgba8888_copy_rgba8888(const gfx_bitblt_t* bb) {
return false;
}
if (!gfx_bitblt_check_dst_x(bb, 32) || !gfx_bitblt_check_src_x(bb, 32)) {
return false;
}
dma2d_wait();
if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) {
@ -843,6 +895,10 @@ static bool dma2d_rgba8888_copy_ycbcr(const gfx_bitblt_t* bb, uint32_t css) {
return false;
}
if (!gfx_bitblt_check_dst_x(bb, 32)) {
return false;
}
dma2d_wait();
if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) {

View File

@ -87,6 +87,27 @@ void gfx_bitblt_deinit(void);
#endif // KERNEL_MODE
// Checks if src_x and width are within the bounds of the source bitmap
static inline bool gfx_bitblt_check_src_x(const gfx_bitblt_t* bb,
size_t pixel_bits) {
return (bb->src_x + bb->width >= bb->src_x) && // overflow check
(((bb->src_x + bb->width) * pixel_bits + 7) / 8 <= bb->src_stride);
}
// Checks if dst_x and width are within the bounds of the destination bitmap
static inline bool gfx_bitblt_check_dst_x(const gfx_bitblt_t* bb,
size_t pixel_bits) {
return (bb->dst_x + bb->width >= bb->dst_x) && // overflow check
(((bb->dst_x + bb->width) * pixel_bits + 7) / 8 <= bb->dst_stride);
}
// Checks if dst_y and height are within the bounds of the destination bitmap
static inline bool gfx_bitblt_check_dst_y(const gfx_bitblt_t* bb,
size_t fb_size) {
return (bb->dst_y + bb->height >= bb->dst_y) && // overflow check
(bb->dst_y + bb->height) * bb->dst_stride <= fb_size;
}
// If the bitblt operation is asynchronous, waits until it's finished
void gfx_bitblt_wait(void);

View File

@ -16,6 +16,12 @@ void display_copy_rgb565(const gfx_bitblt_t *bb) {
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride;
if (!gfx_bitblt_check_dst_x(&bb_new, 16) ||
!gfx_bitblt_check_src_x(&bb_new, 16) ||
!gfx_bitblt_check_dst_y(&bb_new, fb.size)) {
return;
}
gfx_rgb565_copy_rgb565(&bb_new);
}
@ -30,6 +36,11 @@ void display_fill(const gfx_bitblt_t *bb) {
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride;
if (!gfx_bitblt_check_dst_x(&bb_new, 16) ||
!gfx_bitblt_check_dst_y(&bb_new, fb.size)) {
return;
}
gfx_rgb565_fill(&bb_new);
}
@ -44,6 +55,12 @@ void display_copy_mono1p(const gfx_bitblt_t *bb) {
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride;
if (!gfx_bitblt_check_dst_x(&bb_new, 16) ||
!gfx_bitblt_check_src_x(&bb_new, 1) ||
!gfx_bitblt_check_dst_y(&bb_new, fb.size)) {
return;
}
gfx_rgb565_copy_mono1p(&bb_new);
}

View File

@ -18,6 +18,11 @@ void display_fill(const gfx_bitblt_t *bb) {
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride;
if (!gfx_bitblt_check_dst_x(&bb_new, 32) ||
!gfx_bitblt_check_dst_y(&bb_new, fb.size)) {
return;
}
gfx_rgba8888_fill(&bb_new);
}
@ -32,6 +37,12 @@ void display_copy_rgb565(const gfx_bitblt_t *bb) {
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride;
if (!gfx_bitblt_check_dst_x(&bb_new, 32) ||
!gfx_bitblt_check_src_x(&bb_new, 16) ||
!gfx_bitblt_check_dst_y(&bb_new, fb.size)) {
return;
}
gfx_rgba8888_copy_rgb565(&bb_new);
}
@ -46,6 +57,12 @@ void display_copy_mono1p(const gfx_bitblt_t *bb) {
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride;
if (!gfx_bitblt_check_dst_x(&bb_new, 32) ||
!gfx_bitblt_check_src_x(&bb_new, 1) ||
!gfx_bitblt_check_dst_y(&bb_new, fb.size)) {
return;
}
gfx_rgba8888_copy_mono1p(&bb_new);
}

View File

@ -279,6 +279,11 @@ void display_fill(const gfx_bitblt_t *bb) {
bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride;
if (!gfx_bitblt_check_dst_x(&bb_new, 16) ||
!gfx_bitblt_check_dst_y(&bb_new, fb.size)) {
return;
}
gfx_rgb565_fill(&bb_new);
}
@ -293,6 +298,12 @@ void display_copy_rgb565(const gfx_bitblt_t *bb) {
bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride;
if (!gfx_bitblt_check_dst_x(&bb_new, 16) ||
!gfx_bitblt_check_src_x(&bb_new, 16) ||
!gfx_bitblt_check_dst_y(&bb_new, fb.size)) {
return;
}
gfx_rgb565_copy_rgb565(&bb_new);
}
@ -307,6 +318,12 @@ void display_copy_mono1p(const gfx_bitblt_t *bb) {
bb_new.dst_row = (uint16_t *)((uintptr_t)fb.ptr + fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride;
if (!gfx_bitblt_check_dst_x(&bb_new, 16) ||
!gfx_bitblt_check_src_x(&bb_new, 1) ||
!gfx_bitblt_check_dst_y(&bb_new, fb.size)) {
return;
}
gfx_rgb565_copy_mono1p(&bb_new);
}

View File

@ -79,6 +79,27 @@ static inline void set_window(const gfx_bitblt_t* bb) {
bb->dst_y + bb->height + 1);
}
// Checks if the destination rectangle is withing the display bounds
static inline bool gfx_bitblt_check_dst_xy(const gfx_bitblt_t* bb) {
if (bb->dst_x + bb->width < bb->dst_x) { // overflow check
return false;
}
if (bb->dst_x + bb->width > DISPLAY_RESX) {
return false;
}
if (bb->dst_y + bb->height < bb->dst_y) { // overflow check
return false;
}
if (bb->dst_y + bb->height > DISPLAY_RESY) {
return false;
}
return true;
}
// For future notice, if we ever want to do a new model using progressive
// rendering.
//
@ -88,6 +109,10 @@ static inline void set_window(const gfx_bitblt_t* bb) {
// to one with DMA2D while copying the other to the display with DMA.
void display_fill(const gfx_bitblt_t* bb) {
if (!gfx_bitblt_check_dst_xy(bb)) {
return;
}
set_window(bb);
uint16_t height = bb->height;
@ -100,6 +125,10 @@ void display_fill(const gfx_bitblt_t* bb) {
}
void display_copy_rgb565(const gfx_bitblt_t* bb) {
if (!gfx_bitblt_check_dst_xy(bb) || !gfx_bitblt_check_src_x(bb, 16)) {
return;
}
set_window(bb);
uint16_t* src_ptr = (uint16_t*)bb->src_row + bb->src_x;
@ -114,6 +143,10 @@ void display_copy_rgb565(const gfx_bitblt_t* bb) {
}
void display_copy_mono1p(const gfx_bitblt_t* bb) {
if (!gfx_bitblt_check_dst_xy(bb) || !gfx_bitblt_check_src_x(bb, 1)) {
return;
}
set_window(bb);
uint8_t* src = (uint8_t*)bb->src_row;

View File

@ -165,6 +165,11 @@ void display_fill(const gfx_bitblt_t *bb) {
bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t);
if (!gfx_bitblt_check_dst_x(&bb_new, 16) ||
!gfx_bitblt_check_dst_y(&bb_new, FRAME_BUFFER_SIZE)) {
return;
}
gfx_rgb565_fill(&bb_new);
}
@ -179,6 +184,12 @@ void display_copy_rgb565(const gfx_bitblt_t *bb) {
bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t);
if (!gfx_bitblt_check_dst_x(&bb_new, 16) ||
!gfx_bitblt_check_src_x(&bb_new, 16) ||
!gfx_bitblt_check_dst_y(&bb_new, FRAME_BUFFER_SIZE)) {
return;
}
gfx_rgb565_copy_rgb565(&bb_new);
}
@ -193,6 +204,12 @@ void display_copy_mono1p(const gfx_bitblt_t *bb) {
bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t);
if (!gfx_bitblt_check_dst_x(&bb_new, 16) ||
!gfx_bitblt_check_src_x(&bb_new, 1) ||
!gfx_bitblt_check_dst_y(&bb_new, FRAME_BUFFER_SIZE)) {
return;
}
gfx_rgb565_copy_mono1p(&bb_new);
}

View File

@ -436,6 +436,11 @@ void display_fill(const gfx_bitblt_t *bb) {
bb_new.dst_row = &(((uint8_t *)fb.ptr)[DISPLAY_RESX * bb_new.dst_y]);
bb_new.dst_stride = DISPLAY_RESX;
if (!gfx_bitblt_check_dst_x(&bb_new, 8) ||
!gfx_bitblt_check_dst_y(&bb_new, fb.size)) {
return;
}
gfx_mono8_fill(&bb_new);
}
@ -450,6 +455,12 @@ void display_copy_mono1p(const gfx_bitblt_t *bb) {
bb_new.dst_row = &(((uint8_t *)fb.ptr)[DISPLAY_RESX * bb_new.dst_y]);
bb_new.dst_stride = DISPLAY_RESX;
if (!gfx_bitblt_check_dst_x(&bb_new, 8) ||
!gfx_bitblt_check_src_x(&bb_new, 1) ||
!gfx_bitblt_check_dst_y(&bb_new, fb.size)) {
return;
}
gfx_mono8_copy_mono1p(&bb_new);
}

View File

@ -306,6 +306,7 @@ bool mpu_inside_active_fb(const void* addr, size_t size) {
irq_key_t lock = irq_lock();
bool result =
((uintptr_t)addr + size >= (uintptr_t)addr) && // overflow check
((uintptr_t)addr >= drv->active_fb_addr) &&
((uintptr_t)addr + size <= drv->active_fb_addr + drv->active_fb_size);