[05/10] libsframe: handle invalid fre_type gracefully
Checks
| Context |
Check |
Description |
| linaro-tcwg-bot/tcwg_binutils_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_binutils_check--master-arm |
success
|
Test passed
|
Commit Message
sframe_fre_start_addr_size() previously hit an sframe_assert, when
encountering an invalid or unsupported fre_type. This may happen in
untrusted input binaries / crafted SFrame data.
Replace sframe_assert in sframe_fre_start_addr_size() with returning
0. Update flip_fre() and sframe_fre_entry_size() to check for
addr_size == 0
and fail gracefully by returning error codes instead of aborting.
Some callers of sframe_fre_start_addr_size () now see additional check
for invalid fre_type and exit early.
This addresses some issues raised in PR libsframe/34273.
---
libsframe/sframe.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
@@ -470,8 +470,7 @@ sframe_fre_start_addr_size (uint32_t fre_type)
addr_size = 4;
break;
default:
- /* No other value is expected. */
- sframe_assert (0);
+ addr_size = 0;
break;
}
return addr_size;
@@ -534,6 +533,8 @@ sframe_fre_entry_size (sframe_frame_row_entry *frep, uint32_t fre_type)
uint8_t fre_info = frep->fre_info;
size_t addr_size = sframe_fre_start_addr_size (fre_type);
+ if (addr_size == 0)
+ return 0;
return (addr_size + sizeof (frep->fre_info)
+ sframe_fre_datawords_bytes_size (fre_info));
@@ -549,6 +550,8 @@ sframe_buf_fre_entry_size (const char *fre_buf, uint32_t fre_type)
return 0;
size_t addr_size = sframe_fre_start_addr_size (fre_type);
+ if (addr_size == 0)
+ return 0;
uint8_t fre_info = *(uint8_t *)(fre_buf + addr_size);
return (addr_size + sizeof (fre_info)
@@ -707,7 +710,7 @@ flip_fre (char *fp, size_t fp_size, uint32_t fre_type, size_t *fre_size)
return sframe_set_errno (&err, SFRAME_ERR_INVAL);
addr_size = sframe_fre_start_addr_size (fre_type);
- if (addr_size > fp_size)
+ if (addr_size == 0 || addr_size > fp_size)
return SFRAME_ERR;
flip_fre_start_address (fp, fre_type);