]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
elfclassify: Fix invalid realloc when growing ar member path
authorMatej Smycka <matejsmycka@gmail.com>
Fri, 3 Jul 2026 10:30:18 +0000 (12:30 +0200)
committerMark Wielaard <mark@klomp.org>
Fri, 3 Jul 2026 14:56:39 +0000 (16:56 +0200)
check_ar_members() builds the "ar_path[member]" string in a heap buffer
full_path allocated with malloc().  When a member name does not fit, the
grow path reallocated current_path instead of full_path:

    char *new_path = realloc (current_path, path_size);
    ...
    free (full_path);

On the first archive member current_path still points at ar_path, which
is the caller's path string (an argv[] entry or the getdelim() stdin
buffer), not the malloc'd full_path.  Reallocating that non-owned
pointer is invalid -- it is either not heap-allocated at all or aliases
a buffer owned elsewhere -- and the following free(full_path) then
releases the real buffer, corrupting the heap.  It is reachable with

    eu-elfclassify --elf-archive FILE

on an archive whose first member name is longer than the initial guess
(2 * strlen(ar_path) + 24).

Grow full_path itself and let realloc() release the old block.

Signed-off-by: Matej Smycka <matejsmycka@gmail.com>
src/elfclassify.c

index 80a376a4945988a772046faa0d93f80d7f31189f..63caebdc7a3b30c34dced477f3b3dfbf56a56a5b 100644 (file)
@@ -858,7 +858,7 @@ check_ar_members (void)
       if (path_size < strlen (ar_path) + strlen (ar_name) + 3)
        {
          path_size = strlen (ar_path) + strlen (ar_name) + 24;
-         char *new_path = realloc (current_path, path_size);
+         char *new_path = realloc (full_path, path_size);
          if (new_path == NULL)
            {
              issue (ENOMEM, N_("allocating a member string name storage"));
@@ -867,7 +867,6 @@ check_ar_members (void)
              break;
            }
 
-         free (full_path);
          full_path = new_path;
        }