summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-06-12 07:07:20 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-06-12 07:07:20 -0700
commite10a23e3d49b9b123c4eeda62d60182c88f8ee6b (patch)
treee91da47c1ec93d9faa88054170812c8f104f664f
parent8269da30cff5f376940b4d5798e5167e031dab8b (diff)
downloadtxr-e10a23e3d49b9b123c4eeda62d60182c88f8ee6b.tar.gz
txr-e10a23e3d49b9b123c4eeda62d60182c88f8ee6b.tar.bz2
txr-e10a23e3d49b9b123c4eeda62d60182c88f8ee6b.zip
streams: add overflow checks.
* stream.c (open_process): Check that manipulations of nargs do not overflow int type. Use chk_xalloc. Allocation is done before pipe so we have no file descriptors to clean up if chk_xalloc throws. (run): In both versions of run, check that manipulations of nargs don't overflow int and use chk_xalloc.
-rw-r--r--stream.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/stream.c b/stream.c
index a533ee5f..48738bb7 100644
--- a/stream.c
+++ b/stream.c
@@ -3884,6 +3884,7 @@ val open_command(val path, val mode_str)
#if HAVE_FORK_STUFF
val open_process(val name, val mode_str, val args)
{
+ val self = lit("open-process");
struct stdio_mode m, m_r = stdio_mode_init_r;
val mode = normalize_mode(&m, mode_str, m_r);
int input = m.read != 0;
@@ -3904,13 +3905,17 @@ val open_process(val name, val mode_str, val args)
fds_swizzle(&sfds, (input ? FDS_IN : FDS_OUT) | FDS_ERR);
+ if (nargs < 0 || nargs == INT_MAX)
+ uw_throwf(error_s, lit("~s: argument list overflow"), self, nao);
+
+ argv = coerce(char **, chk_xalloc(nargs + 1, sizeof *argv, self));
+
if (pipe(fd) == -1) {
+ free(argv);
uw_throwf(file_error_s, lit("opening pipe ~a, pipe syscall failed: ~d/~s"),
name, num(errno), string_utf8(strerror(errno)), nao);
}
- argv = coerce(char **, chk_malloc((nargs + 1) * sizeof *argv));
-
for (i = 0, iter = cons(name, args); iter; i++, iter = cdr(iter)) {
val arg = car(iter);
argv[i] = utf8_dup_to(c_str(arg));
@@ -4085,6 +4090,7 @@ val open_process(val name, val mode_str, val args)
#if HAVE_FORK_STUFF
static val run(val name, val args)
{
+ val self = lit("run");
pid_t pid;
char **argv = 0;
val iter;
@@ -4095,7 +4101,10 @@ static val run(val name, val args)
args = default_null_arg(args);
nargs = c_num(length(args)) + 1;
- argv = coerce(char **, chk_malloc((nargs + 1) * sizeof *argv));
+ if (nargs < 0 || nargs == INT_MAX)
+ uw_throwf(error_s, lit("~s: argument list overflow"), self, nao);
+
+ argv = coerce(char **, chk_xalloc(nargs + 1, sizeof *argv, self));
for (i = 0, iter = cons(name, args); iter; i++, iter = cdr(iter)) {
val arg = car(iter);
@@ -4158,6 +4167,7 @@ static val sh(val command)
#elif HAVE_WSPAWN
static val run(val command, val args)
{
+ val self = lit("run");
const wchar_t **wargv = 0;
val iter;
int i, nargs, status;
@@ -4172,7 +4182,10 @@ static val run(val command, val args)
fds_swizzle(&sfds, FDS_IN | FDS_OUT | FDS_ERR);
- wargv = coerce(const wchar_t **, chk_malloc((nargs + 2) * sizeof *wargv));
+ if (nargs < 0 || nargs == INT_MAX)
+ uw_throwf(error_s, lit("~s: argument list overflow"), self, nao);
+
+ wargv = coerce(const wchar_t **, chk_xalloc(nargs + 1, sizeof *wargv, self));
for (i = 0, iter = cons(command, args); iter; i++, iter = cdr(iter))
wargv[i] = c_str(car(iter));