Re: [PATCH] awk: fix use-after-free in awk_sub()

Dmitry Klochkov via busybox <[email protected]> Mon, 27 Jul 2026 01:00:21 +0300
Newsgroups gmane.linux.busybox
Message-ID <iuxb372ycnshcoz3x33yw43hawslhk7jx74zpabqp62fmbgyab@ryy3ti6x3ukv>
Hi Sanghyun,

On Sun, Jul 26, 2026 at 01:29:52AM +0900, Sanghyun Park wrote:
> Hi Dmitry,
> 
> For a non-literal regexp, as_regex() does this:
> 
>   s = getvar_s(evaluate(op, TMPVAR));
> 
> evaluate() can run awk code before awk_sub() uses the replacement pointer
> which exec_builtin() saved earlier.
> 
> For example:
> 
>   function re() {
>       $10 = $NF
>       return "x"
>   }
> 
>   BEGIN {
>       NF = 1
>       sub(re(), NF, $1)
>   }
> 
> The sequence is:
> 
> 1. awk converts NF to the replacement string "1" and keeps a pointer to
>    that cached string.
> 2. awk_sub() calls as_regex(), and evaluate() runs re().
> 3. Assigning to $10 updates NF from 1 to 10 and frees NF's cached string
>    "1".
> 4. awk_sub() then calls strlen(repl), but repl still points to the freed
>    string.
> 
> While checking this path, I found that v1 is too narrow. The same
> earlier-operand/later-evaluation lifetime issue also affects match(),
> split(), other multi-argument builtins, and evaluator operators. I am
> fixing those instances of the same root cause together and will send v2
> as a new thread soon.
> 
> Thanks,
> Sanghyun

Thanks a lot for the clarification!

Dmitry