[PATCH 07/10] libsframe: guard against buffer over-read in sframe_fde_tbl_init

Indu Bhagat <[email protected]>
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
In SFrame V3, the FDE attribute data is stored near the SFrame FREs.  In
sframe_fde_tbl_init(), for SFrame V3 format,
fdep->sfdi_func_start_fre_off was used to index into fre_buf without
verifying if sfdi_func_start_fre_off + sizeof(sframe_func_desc_attr_v3)
<= fre_buf_len.  If left unchecked, this may cause buffer over-reads in case
of invalid SFrame data.

Pass FRE buffer len to sframe_fde_tbl_init(), and validate
sfdi_func_start_fre_off against that guard before reading FDE attribute
data.
---
 libsframe/sframe.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/libsframe/sframe.c b/libsframe/sframe.c
index 288d7c0d873..f047342a782 100644
--- a/libsframe/sframe.c
+++ b/libsframe/sframe.c
@@ -140,8 +140,8 @@ sframe_fde_tbl_alloc (sf_fde_tbl **fde_tbl, unsigned int num_fdes)
 
 static int
 sframe_fde_tbl_init (sf_fde_tbl *fde_tbl, const char *fde_buf,
-		     const char *fre_buf, size_t *fidx_size,
-		     unsigned int num_fdes, uint8_t ver)
+		     const char *fre_buf, size_t fre_buf_len,
+		     size_t *fidx_size, unsigned int num_fdes, uint8_t ver)
 {
   if (ver == SFRAME_VERSION_3 && SFRAME_VERSION == SFRAME_VERSION_3)
     {
@@ -155,6 +155,10 @@ sframe_fde_tbl_init (sf_fde_tbl *fde_tbl, const char *fde_buf,
 	  fde_tbl->entry[i].func_start_fre_off = fdep->sfdi_func_start_fre_off;
 	  /* V3 organizes the following data closer to the SFrame FREs for the
 	     function.  Access them via the sfde_func_start_fre_off.  */
+	  if (fdep->sfdi_func_start_fre_off > fre_buf_len
+	      || (sizeof (sframe_func_desc_attr_v3)
+		  > (fre_buf_len - fdep->sfdi_func_start_fre_off)))
+	    return SFRAME_ERR;
 	  const sframe_func_desc_attr_v3 *fattr
 	    = (sframe_func_desc_attr_v3 *)(fre_buf
 					   + fdep->sfdi_func_start_fre_off);
@@ -1535,7 +1539,7 @@ sframe_decode (const char *sf_buf, size_t sf_size, int *errp)
 
   /* SFrame FDEs are at an offset of sfh_fdeoff from SFrame header end.  */
   if (sframe_fde_tbl_init (dctx->sfd_funcdesc, frame_buf + dhp->sfh_fdeoff,
-			   frame_buf + dhp->sfh_freoff,
+			   frame_buf + dhp->sfh_freoff, dhp->sfh_fre_len,
 			   &fidx_size, dhp->sfh_num_fdes, sfp->sfp_version))
     {
       sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL);
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.