sh: Fix possible memory leaks and double frees with unexpected SIGINT.
This commit is contained in:
parent
d592e78278
commit
1632bf1a88
@ -180,6 +180,7 @@ printaliases(void)
|
||||
int i, j;
|
||||
struct alias **sorted, *ap;
|
||||
|
||||
INTOFF;
|
||||
sorted = ckmalloc(aliases * sizeof(*sorted));
|
||||
j = 0;
|
||||
for (i = 0; i < ATABSIZE; i++)
|
||||
@ -187,9 +188,13 @@ printaliases(void)
|
||||
if (*ap->name != '\0')
|
||||
sorted[j++] = ap;
|
||||
qsort(sorted, aliases, sizeof(*sorted), comparealiases);
|
||||
for (i = 0; i < aliases; i++)
|
||||
for (i = 0; i < aliases; i++) {
|
||||
printalias(sorted[i]);
|
||||
if (int_pending())
|
||||
break;
|
||||
}
|
||||
ckfree(sorted);
|
||||
INTON;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -612,6 +612,7 @@ defun(const char *name, union node *func)
|
||||
|
||||
/*
|
||||
* Delete a function if it exists.
|
||||
* Called with interrupts off.
|
||||
*/
|
||||
|
||||
int
|
||||
|
@ -956,6 +956,7 @@ recordregion(int start, int end, int inquotes)
|
||||
{
|
||||
struct ifsregion *ifsp;
|
||||
|
||||
INTOFF;
|
||||
if (ifslastp == NULL) {
|
||||
ifsp = &ifsfirst;
|
||||
} else {
|
||||
@ -963,6 +964,7 @@ recordregion(int start, int end, int inquotes)
|
||||
&& ifslastp->inquotes == inquotes) {
|
||||
/* extend previous area */
|
||||
ifslastp->endoff = end;
|
||||
INTON;
|
||||
return;
|
||||
}
|
||||
ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion));
|
||||
@ -973,6 +975,7 @@ recordregion(int start, int end, int inquotes)
|
||||
ifslastp->begoff = start;
|
||||
ifslastp->endoff = end;
|
||||
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
|
||||
* standard output, and the standard error if it becomes a duplicate of
|
||||
* 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
|
||||
@ -103,6 +110,7 @@ redirect(union node *redir, int flags)
|
||||
int fd;
|
||||
char memory[10]; /* file descriptors to write to memory */
|
||||
|
||||
INTOFF;
|
||||
for (i = 10 ; --i >= 0 ; )
|
||||
memory[i] = 0;
|
||||
memory[1] = flags & REDIR_BACKQ;
|
||||
@ -139,11 +147,14 @@ redirect(union node *redir, int flags)
|
||||
INTON;
|
||||
}
|
||||
openredirect(n, memory);
|
||||
INTON;
|
||||
INTOFF;
|
||||
}
|
||||
if (memory[1])
|
||||
out1 = &memout;
|
||||
if (memory[2])
|
||||
out2 = &memout;
|
||||
INTON;
|
||||
}
|
||||
|
||||
|
||||
@ -156,15 +167,6 @@ openredirect(union node *redir, char memory[10])
|
||||
int f;
|
||||
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;
|
||||
switch (redir->nfile.type) {
|
||||
case NFROM:
|
||||
@ -237,7 +239,6 @@ openredirect(union node *redir, char memory[10])
|
||||
default:
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user