dash.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] trap: fix memory leak in exitshell()
@ 2016-11-21 21:40 Andreas Bofjall
  2016-11-22 21:51 ` Jilles Tjoelker
  0 siblings, 1 reply; 3+ messages in thread
From: Andreas Bofjall @ 2016-11-21 21:40 UTC (permalink / raw)
  To: dash; +Cc: Andreas Bofjall

After dash had executed the exit trap handler, the trap was reset but
the pointer was never freed. This leak can be demonstrated by running
dash through valgrind and executing the following shell script:

	foo() {
	    true
	}
	trap foo EXIT

Fix by properly freeing the trap pointer in exitshell().

Signed-off-by: Andreas Bofjall <andreas@gazonk.org>
---
 src/trap.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/trap.c b/src/trap.c
index edb9938..5418b07 100644
--- a/src/trap.c
+++ b/src/trap.c
@@ -389,6 +389,7 @@ exitshell(void)
 		trap[0] = NULL;
 		evalskip = 0;
 		evalstring(p, 0);
+		ckfree(p);
 	}
 out:
 	/*
-- 
2.10.2


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] trap: fix memory leak in exitshell()
  2016-11-21 21:40 [PATCH] trap: fix memory leak in exitshell() Andreas Bofjall
@ 2016-11-22 21:51 ` Jilles Tjoelker
  2016-11-22 22:47   ` Andreas Bofjäll
  0 siblings, 1 reply; 3+ messages in thread
From: Jilles Tjoelker @ 2016-11-22 21:51 UTC (permalink / raw)
  To: Andreas Bofjall; +Cc: dash

On Mon, Nov 21, 2016 at 10:40:52PM +0100, Andreas Bofjall wrote:
> After dash had executed the exit trap handler, the trap was reset but
> the pointer was never freed. This leak can be demonstrated by running
> dash through valgrind and executing the following shell script:

> 	foo() {
> 	    true
> 	}
> 	trap foo EXIT

> Fix by properly freeing the trap pointer in exitshell().

> Signed-off-by: Andreas Bofjall <andreas@gazonk.org>
> ---
>  src/trap.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/src/trap.c b/src/trap.c
> index edb9938..5418b07 100644
> --- a/src/trap.c
> +++ b/src/trap.c
> @@ -389,6 +389,7 @@ exitshell(void)
>  		trap[0] = NULL;
>  		evalskip = 0;
>  		evalstring(p, 0);
> +		ckfree(p);
>  	}
>  out:
>  	/*

This patch will shut up valgrind in the common case, but does not handle
the general case. The command string may contain an error or invoke the
exit builtin and in either case the command string will be leaked
(SIGINT might be expected to have a similar effect, but behaves
strangely from an EXIT trap in dash).

You can probably use the exception handling already present in the
function to fix this. Note that ckfree() should only be used while
INTOFF is in effect, both to avoid longjmp'ing out of free() and to
ensure exactly one free in the presence of interruptions and errors.

-- 
Jilles Tjoelker

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] trap: fix memory leak in exitshell()
  2016-11-22 21:51 ` Jilles Tjoelker
@ 2016-11-22 22:47   ` Andreas Bofjäll
  0 siblings, 0 replies; 3+ messages in thread
From: Andreas Bofjäll @ 2016-11-22 22:47 UTC (permalink / raw)
  To: Jilles Tjoelker; +Cc: dash

On Tue, 22 Nov 2016, Jilles Tjoelker wrote:

> On Mon, Nov 21, 2016 at 10:40:52PM +0100, Andreas Bofjall wrote:
>> diff --git a/src/trap.c b/src/trap.c
>> index edb9938..5418b07 100644
>> --- a/src/trap.c
>> +++ b/src/trap.c
>> @@ -389,6 +389,7 @@ exitshell(void)
>>  		trap[0] = NULL;
>>  		evalskip = 0;
>>  		evalstring(p, 0);
>> +		ckfree(p);
>>  	}
>>  out:
>>  	/*
>
> This patch will shut up valgrind in the common case, but does not handle
> the general case. The command string may contain an error or invoke the
> exit builtin and in either case the command string will be leaked
> (SIGINT might be expected to have a similar effect, but behaves
> strangely from an EXIT trap in dash).
>
> You can probably use the exception handling already present in the
> function to fix this. Note that ckfree() should only be used while
> INTOFF is in effect, both to avoid longjmp'ing out of free() and to
> ensure exactly one free in the presence of interruptions and errors.

Thanks for the feedback! Would something simple like moving the call to 
ckfree() to after the out: label and wrapping it in INTOFF/INTON (thereby 
catching both the normal return path and the exception) be ok, or do you 
mean something more elaborate?

/Andreas

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-11-22 22:47 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-21 21:40 [PATCH] trap: fix memory leak in exitshell() Andreas Bofjall
2016-11-22 21:51 ` Jilles Tjoelker
2016-11-22 22:47   ` Andreas Bofjäll

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).