bin/143375: [patch] awk(1) trashes memory with regexp and ^ anchor

Mikolaj Golub at
Sat Jan 30 17:30:02 UTC 2010

>Number:         143375
>Category:       bin
>Synopsis:       [patch] awk(1) trashes memory with regexp and ^ anchor
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Jan 30 17:30:01 UTC 2010
>Originator:     Mikolaj Golub
>Release:        8.0-STABLE, 7.2-STABLE
FreeBSD zhuzha.ua1 8.0-STABLE FreeBSD 8.0-STABLE #6: Sun Jan 24 21:36:17 EET 2010     root at zhuzha.ua1:/usr/obj/usr/src/sys/GENERIC  i386
This problem with awk(1) regexp and ^ anchor trashing memory was reported to NetBSD by Nicolas Joly and it was fixed there.

This script trashes the memory:

awk '/^root:/' /etc/passwd
zhuzha:/usr/src/contrib/one-true-awk% CFLAGS=-g make

zhuzha:/usr/src/contrib/one-true-awk% gdb a.out
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-marcel-freebsd"...
(gdb) b b.c:927
Breakpoint 1 at 0x804e15b: file b.c, line 927.
(gdb) run '/^root:/' /etc/passwd
Starting program: /usr/src/contrib/one-true-awk/a.out '/^root:/' /etc/passwd

Breakpoint 1, cgoto (f=0x28239000, s=2, c=261) at b.c:927
927             f->gototab[s][c] = f->curstat;
(gdb) pt f->gototab
type = unsigned char [32][259]
(gdb) p c
$1 = 261
(gdb) list b.c:927
922             xfree(f->posns[f->curstat]);
923             if ((p = (int *) calloc(1, (setcnt+1)*sizeof(int))) == NULL)
924                     overflo("out of space in cgoto");
926             f->posns[f->curstat] = p;
927             f->gototab[s][c] = f->curstat;
928             for (i = 0; i <= setcnt; i++)
929                     p[i] = tmpset[i];
930             if (setvec[f->accept])
931                     f->out[f->curstat] = 1;

See the attached patch adopted from NetBSD (PR/40689: Nicolas Joly: awk(1) trashes memory with RE and ^ anchor. Another place to special-case HAT.).

Patch attached with submission follows:

--- contrib/one-true-awk.orig/b.c	2007-06-05 18:33:51.000000000 +0300
+++ contrib/one-true-awk/b.c	2010-01-30 19:19:22.000000000 +0200
@@ -924,7 +924,8 @@
 		overflo("out of space in cgoto");
 	f->posns[f->curstat] = p;
-	f->gototab[s][c] = f->curstat;
+	if (c != HAT)
+		f->gototab[s][c] = f->curstat;
 	for (i = 0; i <= setcnt; i++)
 		p[i] = tmpset[i];
 	if (setvec[f->accept])


More information about the freebsd-bugs mailing list