Skip to content

Commit

Permalink
ar: switch from alloca to malloc
Browse files Browse the repository at this point in the history
If alloca allocates too much stack space, program behavior is undefined,
and basically we segfault.  There is no way to check whether this will
happen ahead of time, so our only choice is to switch to malloc.  If we
try to allocate too much memory from the heap, we'll get a NULL pointer,
and we can diagnose & exit ourselves.  Kind of sucks as alloca was a
perfect fit here, but since the size is coming directly from user input,
we can't trust it is always "reasonable".

Bug: https://bugs.gentoo.org/890579
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
  • Loading branch information
vapier committed Jan 25, 2024
1 parent f2af478 commit 77bf161
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 5 deletions.
1 change: 0 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ foreach x : [
'linux/seccomp.h',
'linux/securebits.h',
'sys/prctl.h',
'alloca.h',
'elf-hints.h',
'glob.h',
]
Expand Down
5 changes: 4 additions & 1 deletion paxinc.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,13 @@ static uint64_t ar_read_ascii_number(const char *numstr, size_t ndigits, int bas
archive_member *ar_next(archive_handle *ar)
{
char *s;
char *heap_s = NULL;
ssize_t len = 0;
static archive_member ret;

if (ar->skip && lseek(ar->fd, ar->skip, SEEK_CUR) == -1) {
close_and_ret:
free(heap_s);
free(ar->extfn);
close(ar->fd);
ar->extfn = NULL;
Expand Down Expand Up @@ -146,7 +148,7 @@ archive_member *ar_next(archive_handle *ar)
if (read(ar->fd, ret.buf.formatted.name, len) != len)
goto close_and_ret;
} else {
s = alloca(sizeof(char) * len + 1);
s = heap_s = xmalloc(sizeof(char) * (len + 1));
if (read(ar->fd, s, len) != len)
goto close_and_ret;
s[len] = '\0';
Expand All @@ -167,6 +169,7 @@ archive_member *ar_next(archive_handle *ar)
}

snprintf(ret.name, sizeof(ret.name), "%s:%s", ar->filename, s);
free(heap_s);
ret.name[sizeof(ret.name) - 1] = '\0';
if ((s=strchr(ret.name+strlen(ar->filename), '/')) != NULL)
*s = '\0';
Expand Down
3 changes: 0 additions & 3 deletions porting.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@
#include <time.h>
#include <unistd.h>
#include "elf.h"
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
#ifdef HAVE_SYS_PRCTL_H
# include <sys/prctl.h>
# ifdef HAVE_LINUX_SECCOMP_H
Expand Down

0 comments on commit 77bf161

Please sign in to comment.