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:
parent
9530f09b08
commit
01c01fe8f6
8 changed files with 35 additions and 10 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue