mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
macro.c: varsub(): Fix use-after-free problem
When varsub(), which "handles $param, ${param}, and ${param op word}", handles arrays, it obtains an 'ap' array pointer once using nv_arrayptr(np). In several locations it calls nv_putsub() which may call array_grow() which invalidates that pointer. But the pointer is never updated. So whenver an array grows, there is a use-after-free problem, easily caught by AddresSanitizer. This commit makes sure the 'ap' pointer, if non-null, is refreshed whenever nv_putsub() may previously have been called.
This commit is contained in:
parent
064baa372e
commit
ad229fd5ee
1 changed files with 30 additions and 6 deletions
|
@ -1224,6 +1224,8 @@ retry1:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case S_ALP:
|
case S_ALP:
|
||||||
|
{
|
||||||
|
Namval_t *np_orig;
|
||||||
if(c=='.' && type==0)
|
if(c=='.' && type==0)
|
||||||
goto nosub;
|
goto nosub;
|
||||||
offset = stktell(stkp);
|
offset = stktell(stkp);
|
||||||
|
@ -1365,23 +1367,28 @@ retry1:
|
||||||
#endif /* SHOPT_FILESCAN */
|
#endif /* SHOPT_FILESCAN */
|
||||||
np = 0;
|
np = 0;
|
||||||
}
|
}
|
||||||
|
np_orig = np;
|
||||||
ap = np?nv_arrayptr(np):0;
|
ap = np?nv_arrayptr(np):0;
|
||||||
if(type)
|
if(type)
|
||||||
{
|
{
|
||||||
if(mp->dotdot)
|
if(mp->dotdot)
|
||||||
{
|
{
|
||||||
Namval_t *nq;
|
|
||||||
#if SHOPT_FIXEDARRAY
|
#if SHOPT_FIXEDARRAY
|
||||||
if(ap && !ap->fixed && (nq=nv_opensub(np)))
|
if(ap && !ap->fixed)
|
||||||
#else
|
#else
|
||||||
if(ap && (nq=nv_opensub(np)))
|
if(ap)
|
||||||
#endif /* SHOPT_FIXEDARRAY */
|
#endif /* SHOPT_FIXEDARRAY */
|
||||||
ap = nv_arrayptr(np=nq);
|
{
|
||||||
|
Namval_t *nq;
|
||||||
|
if(nq = nv_opensub(np))
|
||||||
|
np = nq;
|
||||||
|
}
|
||||||
if(ap)
|
if(ap)
|
||||||
{
|
{
|
||||||
np = nv_putsub(np,v,ARRAY_SCAN);
|
np = nv_putsub(np,v,ARRAY_SCAN);
|
||||||
v = stkptr(stkp,mp->dotdot);
|
v = stkptr(stkp,mp->dotdot);
|
||||||
dolmax =1;
|
dolmax =1;
|
||||||
|
ap = nv_arrayptr(np_orig); /* update */
|
||||||
if(array_assoc(ap))
|
if(array_assoc(ap))
|
||||||
arrmax = sh_strdup(v);
|
arrmax = sh_strdup(v);
|
||||||
else if((dolmax = (int)sh_arith(v))<0)
|
else if((dolmax = (int)sh_arith(v))<0)
|
||||||
|
@ -1441,8 +1448,12 @@ retry1:
|
||||||
{
|
{
|
||||||
type = M_BRACE;
|
type = M_BRACE;
|
||||||
v = nv_name(np);
|
v = nv_name(np);
|
||||||
if(ap && !mp->dotdot && !(ap->nelem&ARRAY_UNDEF))
|
if(ap && !mp->dotdot)
|
||||||
addsub = 1;
|
{
|
||||||
|
ap = nv_arrayptr(np_orig); /* update */
|
||||||
|
if(!(ap->nelem&ARRAY_UNDEF))
|
||||||
|
addsub = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(type==M_TYPE)
|
else if(type==M_TYPE)
|
||||||
{
|
{
|
||||||
|
@ -1465,7 +1476,10 @@ retry1:
|
||||||
if(type && fcpeek(0)=='+')
|
if(type && fcpeek(0)=='+')
|
||||||
{
|
{
|
||||||
if(ap)
|
if(ap)
|
||||||
|
{
|
||||||
|
ap = nv_arrayptr(np_orig); /* update */
|
||||||
v = nv_arrayisset(np,ap)?(char*)"x":0;
|
v = nv_arrayisset(np,ap)?(char*)"x":0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
v = nv_isnull(np)?0:(char*)"x";
|
v = nv_isnull(np)?0:(char*)"x";
|
||||||
}
|
}
|
||||||
|
@ -1498,6 +1512,7 @@ retry1:
|
||||||
stkseek(stkp,offset);
|
stkseek(stkp,offset);
|
||||||
if(ap)
|
if(ap)
|
||||||
{
|
{
|
||||||
|
ap = nv_arrayptr(np_orig); /* update */
|
||||||
#if SHOPT_OPTIMIZE
|
#if SHOPT_OPTIMIZE
|
||||||
if(sh.argaddr)
|
if(sh.argaddr)
|
||||||
nv_optimize(np);
|
nv_optimize(np);
|
||||||
|
@ -1511,6 +1526,7 @@ retry1:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case S_EOF:
|
case S_EOF:
|
||||||
fcseek(-1);
|
fcseek(-1);
|
||||||
default:
|
default:
|
||||||
|
@ -1579,7 +1595,10 @@ retry1:
|
||||||
c = sh.st.dolc;
|
c = sh.st.dolc;
|
||||||
}
|
}
|
||||||
else if(dolg<0)
|
else if(dolg<0)
|
||||||
|
{
|
||||||
|
ap = nv_arrayptr(np); /* update */
|
||||||
c = array_elem(ap);
|
c = array_elem(ap);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
c = (v!=0);
|
c = (v!=0);
|
||||||
dolg = dolmax = 0;
|
dolg = dolmax = 0;
|
||||||
|
@ -1702,6 +1721,7 @@ retry1:
|
||||||
}
|
}
|
||||||
else if(ap)
|
else if(ap)
|
||||||
{
|
{
|
||||||
|
ap = nv_arrayptr(np); /* update */
|
||||||
if(type<0)
|
if(type<0)
|
||||||
{
|
{
|
||||||
if(array_assoc(ap))
|
if(array_assoc(ap))
|
||||||
|
@ -1902,6 +1922,7 @@ retry2:
|
||||||
v = nv_getsub(np);
|
v = nv_getsub(np);
|
||||||
else
|
else
|
||||||
v = nv_getval(np);
|
v = nv_getval(np);
|
||||||
|
ap = nv_arrayptr(np); /* update */
|
||||||
if(array_assoc(ap))
|
if(array_assoc(ap))
|
||||||
{
|
{
|
||||||
if(strcmp(bysub?v:nv_getsub(np),arrmax)>0)
|
if(strcmp(bysub?v:nv_getsub(np),arrmax)>0)
|
||||||
|
@ -1943,7 +1964,10 @@ retry2:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(ap)
|
if(ap)
|
||||||
|
{
|
||||||
|
ap = nv_arrayptr(np); /* update */
|
||||||
ap->nelem |= ARRAY_SCAN;
|
ap->nelem |= ARRAY_SCAN;
|
||||||
|
}
|
||||||
if(nv_nextsub(np) == 0)
|
if(nv_nextsub(np) == 0)
|
||||||
break;
|
break;
|
||||||
if(bysub)
|
if(bysub)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue