aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2024-01-25 00:02:51 -0500
committerMike Frysinger <vapier@gentoo.org>2024-01-25 00:02:51 -0500
commit77bf161b55dbf340f4498ad26eef3fd7a0dfbcdc (patch)
tree830096d789f04cb9e7adb9786481280efa8df37f
parentar: handle invalid extended filename offsets (diff)
downloadpax-utils-77bf161b55dbf340f4498ad26eef3fd7a0dfbcdc.tar.gz
pax-utils-77bf161b55dbf340f4498ad26eef3fd7a0dfbcdc.tar.bz2
pax-utils-77bf161b55dbf340f4498ad26eef3fd7a0dfbcdc.zip
ar: switch from alloca to malloc
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>
-rw-r--r--meson.build1
-rw-r--r--paxinc.c5
-rw-r--r--porting.h3
3 files changed, 4 insertions, 5 deletions
diff --git a/meson.build b/meson.build
index e891d98..319e3de 100644
--- a/meson.build
+++ b/meson.build
@@ -44,7 +44,6 @@ foreach x : [
'linux/seccomp.h',
'linux/securebits.h',
'sys/prctl.h',
- 'alloca.h',
'elf-hints.h',
'glob.h',
]
diff --git a/paxinc.c b/paxinc.c
index 21844d8..644c0d6 100644
--- a/paxinc.c
+++ b/paxinc.c
@@ -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;
@@ -146,7 +148,7 @@ close_and_ret:
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';
@@ -167,6 +169,7 @@ close_and_ret:
}
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';
diff --git a/porting.h b/porting.h
index 68e2b6c..103d268 100644
--- a/porting.h
+++ b/porting.h
@@ -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