acme: fix leaking memory allocated by getenv("font")

If the font chosen for acme is retrieved via `getenv("font")` its
memory is leaked:

<snip>
	if(fontnames[0] == nil)
		fontnames[0] = getenv("font");
		^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> getenv(…) mallocs memory

	if(fontnames[0] == nil)
		fontnames[0] = "/lib/font/bit/vga/unicode.font";
	if(access(fontnames[0], 0) < 0){
		fprint(2, "acme: can't access %s: %r\n", fontnames[0]);
		exits("font open");
	}
	if(fontnames[1] == nil)
		fontnames[1] = fontnames[0];
	fontnames[0] = estrdup(fontnames[0]);
	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> if the `getenv("font")` path was taken above, this assignment
> will leak its memory.
</snap>

The following leak/acid session demonstrates the issue:

<snip>
cpu% leak -s 212252
src(0x002000cb); // 1
cpu% acid 212252
/proc/212252/text:amd64 plan 9 executable
/sys/lib/acid/port
/sys/lib/acid/amd64
acid: src(0x002000cb)
/sys/src/cmd/acme/acme.c:107
 102			fprint(2, "usage: acme [-aib] [-c ncol] [-f font] [-F fixedfont] [-l loadfile | file...]\n");
 103			exits("usage");
 104		}ARGEND
 105
 106		if(fontnames[0] == nil)
>107			fontnames[0] = getenv("font");
 108		if(fontnames[0] == nil)
 109			fontnames[0] = "/lib/font/bit/vga/unicode.font";
 110		if(access(fontnames[0], 0) < 0){
 111			fprint(2, "acme: can't access %s: %r\n", fontnames[0]);
 112			exits("font open");
acid:
</snap>

The fix tries to first check if a font has been set via
command line options in which case the font string is
malloced via estrdup(…).

If no font has been selected on the command line getenv("font")
is used. If no getenv("font") var is found we malloc a default
font via estrdup(…).

<snip>
	if(fontnames[0] != nil)
		fontnames[0] = estrdup(fontnames[0]);
	else
		if((fontnames[0] = getenv("font")) == nil)
			fontnames[0] = estrdup("/lib/font/bit/vga/unicode.font");
	if(access(fontnames[0], 0) < 0){
		fprint(2, "acme: can't access %s: %r\n", fontnames[0]);
		exits("font open");
	}
	if(fontnames[1] == nil)
		fontnames[1] = fontnames[0];
	fontnames[1] = estrdup(fontnames[1]);
</snap>

This resolves the memory leak reported by leak(1).
This commit is contained in:
Igor Böhm 2021-11-05 23:51:55 +00:00
parent cd7480f68f
commit efa6937460

View file

@ -103,17 +103,17 @@ threadmain(int argc, char *argv[])
exits("usage"); exits("usage");
}ARGEND }ARGEND
if(fontnames[0] == nil) if(fontnames[0] != nil)
fontnames[0] = getenv("font"); fontnames[0] = estrdup(fontnames[0]);
if(fontnames[0] == nil) else
fontnames[0] = "/lib/font/bit/vga/unicode.font"; if((fontnames[0] = getenv("font")) == nil)
fontnames[0] = estrdup("/lib/font/bit/vga/unicode.font");
if(access(fontnames[0], 0) < 0){ if(access(fontnames[0], 0) < 0){
fprint(2, "acme: can't access %s: %r\n", fontnames[0]); fprint(2, "acme: can't access %s: %r\n", fontnames[0]);
exits("font open"); exits("font open");
} }
if(fontnames[1] == nil) if(fontnames[1] == nil)
fontnames[1] = fontnames[0]; fontnames[1] = fontnames[0];
fontnames[0] = estrdup(fontnames[0]);
fontnames[1] = estrdup(fontnames[1]); fontnames[1] = estrdup(fontnames[1]);
quotefmtinstall(); quotefmtinstall();