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:
parent
8574289493
commit
bf119fbee4
core/embed
gfx
io/display
ltdc_dsi
st-7789
stm32f429i-disc1
vg-2864
sys/mpu/stm32u5
@ -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)) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user