diff options
author | Ori Bernstein <ori@eigenstate.org> | 2020-11-21 17:56:34 -0800 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2020-11-21 17:56:34 -0800 |
commit | ad9b1234c365919fa9d8cdb3008b4d42acf37c60 (patch) | |
tree | 73999d3d9f6b62ddc8395815fc660114a55d2cda | |
parent | 03f209427b97f100a55fb490f8bc0332eda2db95 (diff) | |
download | plan9front-ad9b1234c365919fa9d8cdb3008b4d42acf37c60.tar.xz |
dc: fix crashes with : operator (thanks istvan bak)
dc crashes because a Blk* sometimes ends getting double freed.
To make it crash, any of these lines will do:
(each line is a separate input to dc):
1 sa 2 :a le d sa v :a
1 sa 2 :a le d sa :a
1 sa 2 :a le d sa c
Fix by assigning p to sptr->val before EMTPY causes a jump.
Additionally, dcgetwd() can return 0. all other uses check for
0 ptr; Also fix a buffer overflow.
-rw-r--r-- | sys/src/cmd/dc.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/sys/src/cmd/dc.c b/sys/src/cmd/dc.c index 93926c9dc..492c746a0 100644 --- a/sys/src/cmd/dc.c +++ b/sys/src/cmd/dc.c @@ -638,8 +638,11 @@ commnds(void) p = sptr->val; if(c >= ARRAYST) { rewind(p); - while(sfeof(p) == 0) - release(dcgetwd(p)); + while(sfeof(p) == 0) { + q = dcgetwd(p); + if(q != 0) + release(q); + } } release(p); } else { @@ -711,6 +714,7 @@ commnds(void) p = q; } } + sptr->val = p; seekc(p,c*PTRSZ); q = lookwd(p); if(q!=0) @@ -718,7 +722,6 @@ commnds(void) s = pop(); EMPTY; salterwd(p, s); - sptr->val = p; continue; case ';': p = pop(); @@ -1921,7 +1924,8 @@ command(void) sl = line; *sl++ = c; while((c = readc()) != '\n') - *sl++ = c; + if(sl-line < sizeof(line)-1) + *sl++ = c; *sl = 0; if((pid = fork()) == 0) { execl("/bin/rc","rc","-c",line,nil); |