1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Fix buffer overflows and memory leaks caught by ASAN (#282)

The changes in this commit allow ksh to be built and run with
ASan[*], although for now it only works under vmalloc. Example
command to build ksh with ASan:
$ bin/package make CCFLAGS='-O0 -g -fsanitize=address'

[*] https://en.wikipedia.org/wiki/AddressSanitizer

src/cmd/INIT/mamake.c:
- Fix a few memory leaks in mamake. This doesn't fix all of the
  memory leaks ASan complains about (there is one remaining in the
  view() function), but it's enough to get ksh to build under ASan.

src/lib/libast/features/map.c,
src/lib/libast/misc/glob.c:
- Rename the ast globbing functions to _ast_glob() and
  _ast_globfree(). Without this change the globbing tests fail
  under ASan. See: 2c49eb6e

src/cmd/ksh93/sh/{init,io,nvtree,subshell}.c:
- Fix buffer overflows by using strncmp(3) instead of memcmp(3).

src/cmd/ksh93/sh/name.c:
- Fix another invalid usage of memcmp by using strncmp instead.
  This change is also in one of Red Hat's patches:
  https://git.centos.org/rpms/ksh/blob/c8s/f/SOURCES/ksh-20120801-nv_open-memcmp.patch

Resolves: https://github.com/ksh93/ksh/issues/230
This commit is contained in:
Johnothan King 2021-04-22 10:13:12 -07:00 committed by GitHub
parent 9530f09b08
commit 01c01fe8f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 35 additions and 10 deletions

View file

@ -1079,13 +1079,23 @@ push(char* file, Stdio_t* fp, int flags)
else if (++state.sp >= &state.streams[elementsof(state.streams)])
report(3, "input stream stack overflow", NiL, (unsigned long)0);
if (state.sp->fp = fp)
state.sp->file = "pipeline";
{
if(state.sp->file)
free(state.sp->file);
state.sp->file = strdup("pipeline");
if(!state.sp->file)
report(3, "out of memory [push]", NiL, (unsigned long)0);
}
else if (flags & STREAM_PIPE)
report(3, "pipe error", file, (unsigned long)0);
else if (!file || !strcmp(file, "-") || !strcmp(file, "/dev/stdin"))
{
flags |= STREAM_KEEP;
state.sp->file = "/dev/stdin";
if(state.sp->file)
free(state.sp->file);
state.sp->file = strdup("/dev/stdin");
if(!state.sp->file)
report(3, "out of memory [push]", NiL, (unsigned long)0);
state.sp->fp = stdin;
}
else
@ -1095,6 +1105,8 @@ push(char* file, Stdio_t* fp, int flags)
{
if (!(state.sp->fp = fopen(path, "r")))
report(3, "cannot read", path, (unsigned long)0);
if(state.sp->file)
free(state.sp->file);
state.sp->file = duplicate(path);
drop(buf);
}
@ -1446,6 +1458,7 @@ require(char* lib, int dontcare)
Buf_t* tmp;
struct stat st;
int tofree = 0;
static int dynamic = -1;
if (dynamic < 0)
@ -1490,7 +1503,10 @@ require(char* lib, int dontcare)
}
}
if (r != lib)
{
tofree = 1;
r = duplicate(r);
}
search(state.vars, lib, r);
append(tmp, lib + 2);
append(tmp, ".req");
@ -1519,6 +1535,8 @@ require(char* lib, int dontcare)
}
}
fclose(f);
if(tofree)
free(r);
r = use(buf);
}
else if (dontcare)
@ -1533,7 +1551,11 @@ require(char* lib, int dontcare)
append(tmp, "rm -f x.${!-$$}.[cox]\n");
append(tmp, "exit $c\n");
if (execute(expand(buf, use(tmp))))
{
if(tofree)
free(r);
r = "";
}
}
r = duplicate(r);
search(state.vars, lib, r);