[10/10] libsframe: fix PR libsframe/34417

Message ID 20260827224146.3391610-11-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
  For crafted SFrame data, malicious content in fre->fre_info may trigger
a datawords_sz calculation to be > MAX_DATAWORD_BYTES.  Check for bounds
before memcpy.

While at it, detect failure in the callers of sframe_decode_fre and
return early.
---
 libsframe/sframe.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
  

Patch

diff --git a/libsframe/sframe.c b/libsframe/sframe.c
index d3af9717fe2..31ef751e1e1 100644
--- a/libsframe/sframe.c
+++ b/libsframe/sframe.c
@@ -1440,6 +1440,9 @@  sframe_decode_fre (const char *fre_buf, sframe_frame_row_entry *fre,
   memset (fre->fre_datawords, 0, MAX_DATAWORD_BYTES);
   /* Get offsets size.  */
   datawords_sz = sframe_fre_datawords_bytes_size (fre->fre_info);
+  if (datawords_sz > MAX_DATAWORD_BYTES)
+    return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);
+
   datawords = fre_buf + addr_size + sizeof (fre->fre_info);
   memcpy (fre->fre_datawords, datawords, datawords_sz);
 
@@ -1925,7 +1928,9 @@  sframe_decoder_get_fre (const sframe_decoder_ctx *ctx,
   for (i = 0; i < fdep->func_num_fres; i++)
    {
      /* Decode the FRE at the current position.  Return it if valid.  */
-     err = sframe_decode_fre (fres, &ifre, fre_type, &esz);
+     if (sframe_decode_fre (fres, &ifre, fre_type, &esz))
+       return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);
+
      if (i == fre_idx)
        {
 	 if (!sframe_fre_sanity_check_p (&ifre))
@@ -2305,7 +2310,8 @@  sframe_encoder_add_fres_buf (sframe_encoder_ctx *ectx,
     {
       ectx_frep = &fre_tbl->entry[fre_tbl->count];
       /* Copy the SFrame FRE data over to the encoder object's fre_tbl.  */
-      sframe_decode_fre (fres, ectx_frep, fre_type, &esz);
+      if (sframe_decode_fre (fres, ectx_frep, fre_type, &esz))
+	return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);
 
       if (!sframe_fre_sanity_check_p (ectx_frep))
 	return sframe_set_errno (&err, SFRAME_ERR_FRE_INVAL);