[05/10] libsframe: handle invalid fre_type gracefully

Message ID 20260827224146.3391610-6-ibhagatgnu@gmail.com
State New
Headers
Series fix two PRs and guard against bad data |

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

Indu Bhagat Aug. 27, 2026, 10:41 p.m. UTC
  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(-)
  

Patch

diff --git a/libsframe/sframe.c b/libsframe/sframe.c
index 4742e4550c2..51b6bf57c05 100644
--- a/libsframe/sframe.c
+++ b/libsframe/sframe.c
@@ -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);