[binutils-gdb] Double-free sframe_decode tempbuf

Alan Modra amodra@sourceware.org
Wed Feb 11 05:05:56 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=82861a890114ce7ab1a88325ec133e60afdf2ff6

commit 82861a890114ce7ab1a88325ec133e60afdf2ff6
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Feb 11 15:30:24 2026 +1030

    Double-free sframe_decode tempbuf
    
    If an error occurs after assigning tempbuf to dctx->sfd_buf, then
    tempbuf will be freed twice.  Avoid that by moving tempbuf and its
    free on errors into the block where it is used.
    
            * sframe.c (sframe_decode): Localise tempbuf.

Diff:
---
 libsframe/sframe.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/libsframe/sframe.c b/libsframe/sframe.c
index 1805872d94b..37590f3c11c 100644
--- a/libsframe/sframe.c
+++ b/libsframe/sframe.c
@@ -1407,7 +1407,6 @@ sframe_decode (const char *sf_buf, size_t sf_size, int *errp)
   const sframe_header *dhp;
   sframe_decoder_ctx *dctx;
   char *frame_buf;
-  char *tempbuf = NULL;
 
   size_t fidx_size;
   uint32_t fre_bytes;
@@ -1442,7 +1441,7 @@ sframe_decode (const char *sf_buf, size_t sf_size, int *errp)
   if (foreign_endian)
     {
       /* Allocate a new buffer and initialize it.  */
-      tempbuf = (char *) malloc (sf_size * sizeof (char));
+      char *tempbuf = malloc (sf_size * sizeof (char));
       if (tempbuf == NULL)
 	return sframe_ret_set_errno (errp, SFRAME_ERR_NOMEM);
       memcpy (tempbuf, sf_buf, sf_size);
@@ -1451,12 +1450,14 @@ sframe_decode (const char *sf_buf, size_t sf_size, int *errp)
       if (flip_header (tempbuf, sfp->sfp_version))
 	{
 	  sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL);
+	  free (tempbuf);
 	  goto decode_fail_free;
 	}
       /* Flip the rest of the SFrame section data buffer.  */
       if (flip_sframe (tempbuf, sf_size, 0))
 	{
 	  sframe_ret_set_errno (errp, SFRAME_ERR_BUF_INVAL);
+	  free (tempbuf);
 	  goto decode_fail_free;
 	}
 
@@ -1517,8 +1518,6 @@ sframe_decode (const char *sf_buf, size_t sf_size, int *errp)
   return dctx;
 
 decode_fail_free:
-  if (foreign_endian && tempbuf != NULL)
-    free (tempbuf);
   sframe_decoder_free (&dctx);
   dctx = NULL;
   return dctx;


More information about the Binutils-cvs mailing list