mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-15 04:32:24 +00:00
path_pwd(): Fix use after free (re: 11177d44
)
Of course, we should not free the 'cp' pointer when we still need to use it. Resolves: https://github.com/ksh93/ksh/issues/467 Thanks to @atheik for the report.
This commit is contained in:
parent
f43bb4981f
commit
bc6c5dbdd9
2 changed files with 13 additions and 4 deletions
|
@ -183,6 +183,7 @@ static pid_t command_xargs(const char *path, char *argv[],char *const envp[], in
|
||||||
char *path_pwd(void)
|
char *path_pwd(void)
|
||||||
{
|
{
|
||||||
register char *cp;
|
register char *cp;
|
||||||
|
char tofree = 0;
|
||||||
Namval_t *pwdnod;
|
Namval_t *pwdnod;
|
||||||
/* Don't bother if PWD already set */
|
/* Don't bother if PWD already set */
|
||||||
if(sh.pwd)
|
if(sh.pwd)
|
||||||
|
@ -198,7 +199,6 @@ char *path_pwd(void)
|
||||||
{
|
{
|
||||||
/* Check if $HOME is a path to the PWD; this ensures $PWD == $HOME
|
/* Check if $HOME is a path to the PWD; this ensures $PWD == $HOME
|
||||||
at login, even if $HOME is a path that contains symlinks */
|
at login, even if $HOME is a path that contains symlinks */
|
||||||
char tofree = 0;
|
|
||||||
cp = nv_getval(sh_scoped(HOME));
|
cp = nv_getval(sh_scoped(HOME));
|
||||||
if(!(cp && *cp=='/' && test_inode(cp,e_dot)))
|
if(!(cp && *cp=='/' && test_inode(cp,e_dot)))
|
||||||
{
|
{
|
||||||
|
@ -214,8 +214,6 @@ char *path_pwd(void)
|
||||||
pwdnod = sh_assignok(pwdnod,1);
|
pwdnod = sh_assignok(pwdnod,1);
|
||||||
nv_putval(pwdnod,cp,NV_RDONLY);
|
nv_putval(pwdnod,cp,NV_RDONLY);
|
||||||
}
|
}
|
||||||
if(tofree)
|
|
||||||
free((void*)cp);
|
|
||||||
}
|
}
|
||||||
nv_onattr(pwdnod,NV_EXPORT);
|
nv_onattr(pwdnod,NV_EXPORT);
|
||||||
/* Neither obtained the pwd nor can fall back to sane-ish $PWD: fall back to "." */
|
/* Neither obtained the pwd nor can fall back to sane-ish $PWD: fall back to "." */
|
||||||
|
@ -224,7 +222,9 @@ char *path_pwd(void)
|
||||||
if(!cp || *cp!='/')
|
if(!cp || *cp!='/')
|
||||||
nv_putval(pwdnod,cp=(char*)e_dot,NV_RDONLY);
|
nv_putval(pwdnod,cp=(char*)e_dot,NV_RDONLY);
|
||||||
/* Set shell PWD */
|
/* Set shell PWD */
|
||||||
sh.pwd = sh_strdup(cp);
|
if(!tofree)
|
||||||
|
cp = sh_strdup(cp);
|
||||||
|
sh.pwd = cp;
|
||||||
return((char*)sh.pwd);
|
return((char*)sh.pwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -944,6 +944,15 @@ cd "$tmp/testdir"
|
||||||
wait "$!" 2>/dev/null
|
wait "$!" 2>/dev/null
|
||||||
((!(e = $?))) || err_exit 'shell crashes on failure obtain the PWD on init' \
|
((!(e = $?))) || err_exit 'shell crashes on failure obtain the PWD on init' \
|
||||||
"(got status $e$( ((e>128)) && print -n /SIG && kill -l "$e"))"
|
"(got status $e$( ((e>128)) && print -n /SIG && kill -l "$e"))"
|
||||||
|
cd "$tmp"
|
||||||
|
|
||||||
|
# ======
|
||||||
|
# https://github.com/ksh93/ksh/issues/467
|
||||||
|
[[ -d emptydir ]] || mkdir emptydir
|
||||||
|
got=$(unset PWD; "$SHELL" -c 'echo "$PWD"; pwd; cd emptydir' 2>&1)
|
||||||
|
exp=$PWD$'\n'$PWD
|
||||||
|
[[ $got == "$exp" ]] || err_exit "child shell failed to obtain PWD" \
|
||||||
|
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||||||
|
|
||||||
# ======
|
# ======
|
||||||
exit $((Errors<125?Errors:125))
|
exit $((Errors<125?Errors:125))
|
||||||
|
|
Loading…
Reference in a new issue