diff options
author | jilles <jilles@FreeBSD.org> | 2014-03-26 20:43:40 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2014-03-26 20:43:40 +0000 |
commit | 270892ce0aa34981474cedfa90e120b5971c6e13 (patch) | |
tree | fbddad8551c3a2e6b6992b43332553c88006070a /bin/sh/var.c | |
parent | 6ceec4444ddbcea29246cb67b83eff062485cdc3 (diff) | |
download | FreeBSD-src-270892ce0aa34981474cedfa90e120b5971c6e13.zip FreeBSD-src-270892ce0aa34981474cedfa90e120b5971c6e13.tar.gz |
sh: Fix possible memory leaks and double frees with unexpected SIGINT.
Diffstat (limited to 'bin/sh/var.c')
-rw-r--r-- | bin/sh/var.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/bin/sh/var.c b/bin/sh/var.c index 1fd8c77..6c0685f 100644 --- a/bin/sh/var.c +++ b/bin/sh/var.c @@ -249,6 +249,7 @@ setvar(const char *name, const char *val, int flags) vallen = strlen(val); len += vallen; } + INTOFF; nameeq = ckmalloc(len); memcpy(nameeq, name, namelen); nameeq[namelen] = '='; @@ -257,6 +258,7 @@ setvar(const char *name, const char *val, int flags) else nameeq[namelen + 1] = '\0'; setvareq(nameeq, flags); + INTON; } static int @@ -289,6 +291,7 @@ change_env(const char *s, int set) char *eqp; char *ss; + INTOFF; ss = savestr(s); if ((eqp = strchr(ss, '=')) != NULL) *eqp = '\0'; @@ -297,6 +300,7 @@ change_env(const char *s, int set) else (void) unsetenv(ss); ckfree(ss); + INTON; return; } @@ -359,13 +363,13 @@ setvareq(char *s, int flags) /* not found */ if (flags & VNOSET) return; + INTOFF; vp = ckmalloc(sizeof (*vp)); vp->flags = flags; vp->text = s; vp->name_len = nlen; vp->next = *vpp; vp->func = NULL; - INTOFF; *vpp = vp; if ((vp->flags & VEXPORT) && localevar(s)) { change_env(s, 1); @@ -773,6 +777,7 @@ poplocalvars(void) struct localvar *lvp; struct var *vp; + INTOFF; while ((lvp = localvars) != NULL) { localvars = lvp->next; vp = lvp->vp; @@ -790,6 +795,7 @@ poplocalvars(void) } ckfree(lvp); } + INTON; } @@ -828,18 +834,21 @@ unsetcmd(int argc __unused, char **argv __unused) if (flg_func == 0 && flg_var == 0) flg_var = 1; + INTOFF; for (ap = argptr; *ap ; ap++) { if (flg_func) ret |= unsetfunc(*ap); if (flg_var) ret |= unsetvar(*ap); } + INTON; return ret; } /* * Unset the specified variable. + * Called with interrupts off. */ int @@ -853,7 +862,6 @@ unsetvar(const char *s) return (0); if (vp->flags & VREADONLY) return (1); - INTOFF; if (vp->text[vp->name_len + 1] != '\0') setvar(s, nullstr, 0); if ((vp->flags & VEXPORT) && localevar(vp->text)) { @@ -869,7 +877,6 @@ unsetvar(const char *s) *vpp = vp->next; ckfree(vp); } - INTON; return (0); } |