onetrueawk/awk

delete ARGV

realchonk opened this issue · 6 comments

Example

$ awk 'BEGIN { delete ARGV; } { print; }' a b c
Segmentation fault (core dumped)

Environment

OS: OpenBSD/amd64 7.5
Version: both the current git and the one in base

I can take a look at this over the weekend.

This is a basic use-after-free bug, easy to reproduce under valgrind. The ARGV symbol table is freed by awkdelete() but the ARGVtab global still has the old (now freed) value. I would expect ENVIRON to have a similar issue. Adding checks for ARGVtab and ENVtab in awkdelete() would work around the issue but maybe there is a more elegant solution.

Actually, ENVtab is not an issue as it is only used in envinit() and doesn't actually need to be global.

thanks @riscygeek for the report. I'm amazed we never spotted this before.

Keeping a pointer to the Cell containing ARGV instead of the table itself avoids the problem.

thanks @riscygeek for the report. I'm amazed we never spotted this before.

I found this while trying to create something like this:

#!/bin/sh
# Can't do "#!/usr/bin/env awk -f", because POSIX doesn't specify what happens,
# if I have more than one argument in the shebang \
exec awk -f "$0" "$@"

BEGIN {
	for (i = 1; i < ARGC; ++i)
		print ARGV[i];
	delete ARGV;
}

Just out of curiosity, do you know if POSIX specifies what happens, if you delete ARGV?
GNU Awk just assumes, that no arguments were given.

todd's changes were pulled.