summaryrefslogtreecommitdiffstats
path: root/bin/sh/var.c
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2014-03-26 20:43:40 +0000
committerjilles <jilles@FreeBSD.org>2014-03-26 20:43:40 +0000
commit270892ce0aa34981474cedfa90e120b5971c6e13 (patch)
treefbddad8551c3a2e6b6992b43332553c88006070a /bin/sh/var.c
parent6ceec4444ddbcea29246cb67b83eff062485cdc3 (diff)
downloadFreeBSD-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.c13
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);
}
OpenPOWER on IntegriCloud