MFC r263777: sh: Fix possible memory leaks and double frees with unexpected
SIGINT.
This commit is contained in:
parent
35cde107ba
commit
813864aadb
@ -180,6 +180,7 @@ printaliases(void)
|
|||||||
int i, j;
|
int i, j;
|
||||||
struct alias **sorted, *ap;
|
struct alias **sorted, *ap;
|
||||||
|
|
||||||
|
INTOFF;
|
||||||
sorted = ckmalloc(aliases * sizeof(*sorted));
|
sorted = ckmalloc(aliases * sizeof(*sorted));
|
||||||
j = 0;
|
j = 0;
|
||||||
for (i = 0; i < ATABSIZE; i++)
|
for (i = 0; i < ATABSIZE; i++)
|
||||||
@ -187,9 +188,13 @@ printaliases(void)
|
|||||||
if (*ap->name != '\0')
|
if (*ap->name != '\0')
|
||||||
sorted[j++] = ap;
|
sorted[j++] = ap;
|
||||||
qsort(sorted, aliases, sizeof(*sorted), comparealiases);
|
qsort(sorted, aliases, sizeof(*sorted), comparealiases);
|
||||||
for (i = 0; i < aliases; i++)
|
for (i = 0; i < aliases; i++) {
|
||||||
printalias(sorted[i]);
|
printalias(sorted[i]);
|
||||||
|
if (int_pending())
|
||||||
|
break;
|
||||||
|
}
|
||||||
ckfree(sorted);
|
ckfree(sorted);
|
||||||
|
INTON;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -612,6 +612,7 @@ defun(const char *name, union node *func)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete a function if it exists.
|
* Delete a function if it exists.
|
||||||
|
* Called with interrupts off.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -956,6 +956,7 @@ recordregion(int start, int end, int inquotes)
|
|||||||
{
|
{
|
||||||
struct ifsregion *ifsp;
|
struct ifsregion *ifsp;
|
||||||
|
|
||||||
|
INTOFF;
|
||||||
if (ifslastp == NULL) {
|
if (ifslastp == NULL) {
|
||||||
ifsp = &ifsfirst;
|
ifsp = &ifsfirst;
|
||||||
} else {
|
} else {
|
||||||
@ -963,6 +964,7 @@ recordregion(int start, int end, int inquotes)
|
|||||||
&& ifslastp->inquotes == inquotes) {
|
&& ifslastp->inquotes == inquotes) {
|
||||||
/* extend previous area */
|
/* extend previous area */
|
||||||
ifslastp->endoff = end;
|
ifslastp->endoff = end;
|
||||||
|
INTON;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion));
|
ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion));
|
||||||
@ -973,6 +975,7 @@ recordregion(int start, int end, int inquotes)
|
|||||||
ifslastp->begoff = start;
|
ifslastp->begoff = start;
|
||||||
ifslastp->endoff = end;
|
ifslastp->endoff = end;
|
||||||
ifslastp->inquotes = inquotes;
|
ifslastp->inquotes = inquotes;
|
||||||
|
INTON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,6 +92,13 @@ static int openhere(union node *);
|
|||||||
* undone by calling popredir. If the REDIR_BACKQ flag is set, then the
|
* undone by calling popredir. If the REDIR_BACKQ flag is set, then the
|
||||||
* standard output, and the standard error if it becomes a duplicate of
|
* standard output, and the standard error if it becomes a duplicate of
|
||||||
* stdout, is saved in memory.
|
* stdout, is saved in memory.
|
||||||
|
*
|
||||||
|
* We suppress interrupts so that we won't leave open file
|
||||||
|
* descriptors around. Because the signal handler remains
|
||||||
|
* installed and we do not use system call restart, interrupts
|
||||||
|
* will still abort blocking opens such as fifos (they will fail
|
||||||
|
* with EINTR). There is, however, a race condition if an interrupt
|
||||||
|
* arrives after INTOFF and before open blocks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -103,6 +110,7 @@ redirect(union node *redir, int flags)
|
|||||||
int fd;
|
int fd;
|
||||||
char memory[10]; /* file descriptors to write to memory */
|
char memory[10]; /* file descriptors to write to memory */
|
||||||
|
|
||||||
|
INTOFF;
|
||||||
for (i = 10 ; --i >= 0 ; )
|
for (i = 10 ; --i >= 0 ; )
|
||||||
memory[i] = 0;
|
memory[i] = 0;
|
||||||
memory[1] = flags & REDIR_BACKQ;
|
memory[1] = flags & REDIR_BACKQ;
|
||||||
@ -139,11 +147,14 @@ redirect(union node *redir, int flags)
|
|||||||
INTON;
|
INTON;
|
||||||
}
|
}
|
||||||
openredirect(n, memory);
|
openredirect(n, memory);
|
||||||
|
INTON;
|
||||||
|
INTOFF;
|
||||||
}
|
}
|
||||||
if (memory[1])
|
if (memory[1])
|
||||||
out1 = &memout;
|
out1 = &memout;
|
||||||
if (memory[2])
|
if (memory[2])
|
||||||
out2 = &memout;
|
out2 = &memout;
|
||||||
|
INTON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -156,15 +167,6 @@ openredirect(union node *redir, char memory[10])
|
|||||||
int f;
|
int f;
|
||||||
int e;
|
int e;
|
||||||
|
|
||||||
/*
|
|
||||||
* We suppress interrupts so that we won't leave open file
|
|
||||||
* descriptors around. Because the signal handler remains
|
|
||||||
* installed and we do not use system call restart, interrupts
|
|
||||||
* will still abort blocking opens such as fifos (they will fail
|
|
||||||
* with EINTR). There is, however, a race condition if an interrupt
|
|
||||||
* arrives after INTOFF and before open blocks.
|
|
||||||
*/
|
|
||||||
INTOFF;
|
|
||||||
memory[fd] = 0;
|
memory[fd] = 0;
|
||||||
switch (redir->nfile.type) {
|
switch (redir->nfile.type) {
|
||||||
case NFROM:
|
case NFROM:
|
||||||
@ -237,7 +239,6 @@ movefd:
|
|||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
INTON;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
13
bin/sh/var.c
13
bin/sh/var.c
@ -249,6 +249,7 @@ setvar(const char *name, const char *val, int flags)
|
|||||||
vallen = strlen(val);
|
vallen = strlen(val);
|
||||||
len += vallen;
|
len += vallen;
|
||||||
}
|
}
|
||||||
|
INTOFF;
|
||||||
nameeq = ckmalloc(len);
|
nameeq = ckmalloc(len);
|
||||||
memcpy(nameeq, name, namelen);
|
memcpy(nameeq, name, namelen);
|
||||||
nameeq[namelen] = '=';
|
nameeq[namelen] = '=';
|
||||||
@ -257,6 +258,7 @@ setvar(const char *name, const char *val, int flags)
|
|||||||
else
|
else
|
||||||
nameeq[namelen + 1] = '\0';
|
nameeq[namelen + 1] = '\0';
|
||||||
setvareq(nameeq, flags);
|
setvareq(nameeq, flags);
|
||||||
|
INTON;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -289,6 +291,7 @@ change_env(const char *s, int set)
|
|||||||
char *eqp;
|
char *eqp;
|
||||||
char *ss;
|
char *ss;
|
||||||
|
|
||||||
|
INTOFF;
|
||||||
ss = savestr(s);
|
ss = savestr(s);
|
||||||
if ((eqp = strchr(ss, '=')) != NULL)
|
if ((eqp = strchr(ss, '=')) != NULL)
|
||||||
*eqp = '\0';
|
*eqp = '\0';
|
||||||
@ -297,6 +300,7 @@ change_env(const char *s, int set)
|
|||||||
else
|
else
|
||||||
(void) unsetenv(ss);
|
(void) unsetenv(ss);
|
||||||
ckfree(ss);
|
ckfree(ss);
|
||||||
|
INTON;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -359,13 +363,13 @@ setvareq(char *s, int flags)
|
|||||||
/* not found */
|
/* not found */
|
||||||
if (flags & VNOSET)
|
if (flags & VNOSET)
|
||||||
return;
|
return;
|
||||||
|
INTOFF;
|
||||||
vp = ckmalloc(sizeof (*vp));
|
vp = ckmalloc(sizeof (*vp));
|
||||||
vp->flags = flags;
|
vp->flags = flags;
|
||||||
vp->text = s;
|
vp->text = s;
|
||||||
vp->name_len = nlen;
|
vp->name_len = nlen;
|
||||||
vp->next = *vpp;
|
vp->next = *vpp;
|
||||||
vp->func = NULL;
|
vp->func = NULL;
|
||||||
INTOFF;
|
|
||||||
*vpp = vp;
|
*vpp = vp;
|
||||||
if ((vp->flags & VEXPORT) && localevar(s)) {
|
if ((vp->flags & VEXPORT) && localevar(s)) {
|
||||||
change_env(s, 1);
|
change_env(s, 1);
|
||||||
@ -773,6 +777,7 @@ poplocalvars(void)
|
|||||||
struct localvar *lvp;
|
struct localvar *lvp;
|
||||||
struct var *vp;
|
struct var *vp;
|
||||||
|
|
||||||
|
INTOFF;
|
||||||
while ((lvp = localvars) != NULL) {
|
while ((lvp = localvars) != NULL) {
|
||||||
localvars = lvp->next;
|
localvars = lvp->next;
|
||||||
vp = lvp->vp;
|
vp = lvp->vp;
|
||||||
@ -790,6 +795,7 @@ poplocalvars(void)
|
|||||||
}
|
}
|
||||||
ckfree(lvp);
|
ckfree(lvp);
|
||||||
}
|
}
|
||||||
|
INTON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -828,18 +834,21 @@ unsetcmd(int argc __unused, char **argv __unused)
|
|||||||
if (flg_func == 0 && flg_var == 0)
|
if (flg_func == 0 && flg_var == 0)
|
||||||
flg_var = 1;
|
flg_var = 1;
|
||||||
|
|
||||||
|
INTOFF;
|
||||||
for (ap = argptr; *ap ; ap++) {
|
for (ap = argptr; *ap ; ap++) {
|
||||||
if (flg_func)
|
if (flg_func)
|
||||||
ret |= unsetfunc(*ap);
|
ret |= unsetfunc(*ap);
|
||||||
if (flg_var)
|
if (flg_var)
|
||||||
ret |= unsetvar(*ap);
|
ret |= unsetvar(*ap);
|
||||||
}
|
}
|
||||||
|
INTON;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unset the specified variable.
|
* Unset the specified variable.
|
||||||
|
* Called with interrupts off.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -853,7 +862,6 @@ unsetvar(const char *s)
|
|||||||
return (0);
|
return (0);
|
||||||
if (vp->flags & VREADONLY)
|
if (vp->flags & VREADONLY)
|
||||||
return (1);
|
return (1);
|
||||||
INTOFF;
|
|
||||||
if (vp->text[vp->name_len + 1] != '\0')
|
if (vp->text[vp->name_len + 1] != '\0')
|
||||||
setvar(s, nullstr, 0);
|
setvar(s, nullstr, 0);
|
||||||
if ((vp->flags & VEXPORT) && localevar(vp->text)) {
|
if ((vp->flags & VEXPORT) && localevar(vp->text)) {
|
||||||
@ -869,7 +877,6 @@ unsetvar(const char *s)
|
|||||||
*vpp = vp->next;
|
*vpp = vp->next;
|
||||||
ckfree(vp);
|
ckfree(vp);
|
||||||
}
|
}
|
||||||
INTON;
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user