summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2013-05-11 20:51:00 +0000
committerjilles <jilles@FreeBSD.org>2013-05-11 20:51:00 +0000
commite0dffd814f1f48f0b8357b4219a29a93556985bd (patch)
treebe11628c178535fe7fd9957134f7f49cfd4252a5 /bin
parent960e7e9fd4f902c33ef15129c7fe48d67014ca2c (diff)
downloadFreeBSD-src-e0dffd814f1f48f0b8357b4219a29a93556985bd.zip
FreeBSD-src-e0dffd814f1f48f0b8357b4219a29a93556985bd.tar.gz
sh: Remove linked list of stack marks.
The linked list of stack marks may cause problems if the allocation stack is used between an exception and a higher-level popstackmark(), as it may then touch a stack mark that is local to a function which has returned. Also, the adjustment compares to a pointer passed to realloc(), which is undefined behaviour. Instead of adjusting stack marks when reallocating stack blocks, ensure that such an adjustment is never necessary by fixing a small piece of memory in place at a stack mark. This also simplifies the code. To avoid the problems reported in bin/175922, it remains necessary to call setstackmark() after popstackmark() if the stack mark remains in use.
Diffstat (limited to 'bin')
-rw-r--r--bin/sh/memalloc.c20
-rw-r--r--bin/sh/memalloc.h1
2 files changed, 3 insertions, 18 deletions
diff --git a/bin/sh/memalloc.c b/bin/sh/memalloc.c
index f33a15c..cb330d0 100644
--- a/bin/sh/memalloc.c
+++ b/bin/sh/memalloc.c
@@ -124,7 +124,6 @@ struct stack_block {
#define SPACE(sp) ((char*)(sp) + ALIGN(sizeof(struct stack_block)))
static struct stack_block *stackp;
-static struct stackmark *markp;
char *stacknxt;
int stacknleft;
char *sstrend;
@@ -186,8 +185,9 @@ setstackmark(struct stackmark *mark)
mark->stackp = stackp;
mark->stacknxt = stacknxt;
mark->stacknleft = stacknleft;
- mark->marknext = markp;
- markp = mark;
+ /* Ensure this block stays in place. */
+ if (stackp != NULL && stacknxt == SPACE(stackp))
+ stalloc(1);
}
@@ -197,7 +197,6 @@ popstackmark(struct stackmark *mark)
struct stack_block *sp;
INTOFF;
- markp = mark->marknext;
while (stackp != mark->stackp) {
sp = stackp;
stackp = sp->prev;
@@ -229,7 +228,6 @@ growstackblock(int min)
int oldlen;
struct stack_block *sp;
struct stack_block *oldstackp;
- struct stackmark *xmark;
if (min < stacknleft)
min = stacknleft;
@@ -254,18 +252,6 @@ growstackblock(int min)
stacknxt = SPACE(sp);
stacknleft = newlen - (stacknxt - (char*)sp);
sstrend = stacknxt + stacknleft;
-
- /*
- * Stack marks pointing to the start of the old block
- * must be relocated to point to the new block
- */
- xmark = markp;
- while (xmark != NULL && xmark->stackp == oldstackp) {
- xmark->stackp = stackp;
- xmark->stacknxt = stacknxt;
- xmark->stacknleft = stacknleft;
- xmark = xmark->marknext;
- }
INTON;
} else {
newlen -= ALIGN(sizeof(struct stack_block));
diff --git a/bin/sh/memalloc.h b/bin/sh/memalloc.h
index 95a6594..a22fa39 100644
--- a/bin/sh/memalloc.h
+++ b/bin/sh/memalloc.h
@@ -39,7 +39,6 @@ struct stackmark {
struct stack_block *stackp;
char *stacknxt;
int stacknleft;
- struct stackmark *marknext;
};
OpenPOWER on IntegriCloud