Subject: bin/18593: tar seg fault
To: None <gnats-bugs@gnats.netbsd.org>
From: None <nick@stupid.net>
List: netbsd-bugs
Date: 10/08/2002 22:55:41
>Number: 18593
>Category: bin
>Synopsis: tar can be tricked into a seg fault
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Oct 08 22:56:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Nicholas Maniscalco
>Release: NetBSD 1.6
>Organization:
>Environment:
System: NetBSD anomaly.stupid.net 1.6 NetBSD 1.6 (GENERIC) #0: Sun Sep 29 17:01:32 PDT 2002 fb@anomaly.stupid.net:/usr/src/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
tar overflows buffers using strcpy and sprintf.
>How-To-Repeat:
This may seem awkward, but if you compile and run this program
you'll probably see tar dump core. Be sure that /netbsd (or some other
reasonably large file) is readable, and that doh.tar can be created in
the cwd.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char **argv, char **envp)
{
int result = 0;
char *v[9] = {"tar", "-L", "1", "-cMf", "doh.tar", "-V", NULL, "/netbsd", NULL };
int len = 100000;
v[6] = (char*)malloc(sizeof(char) * len);
v[6][len-1] = '\0';
memset(v[6], 65, len-1);
result = execve("/usr/bin/tar", v, envp);
if(result<0)
perror("execve");
return -1;
}
This demonstrates one of the buffer problems.
Please let me know if I left anything out.
>Fix:
Here is a patch
Index: buffer.c
===================================================================
RCS file: /cvsroot/gnusrc/gnu/usr.bin/tar/buffer.c,v
retrieving revision 1.5
diff -r1.5 buffer.c
706c706,708
< sprintf (ar_block->header.arch_name, "%s Volume 1", f_volhdr);
---
> {
> snprintf (ar_block->header.arch_name, NAMSIZ, "%s Volume 1", f_volhdr);
> }
708c710,714
< strcpy (ar_block->header.arch_name, f_volhdr);
---
> {
> /* could use strlcpy instead */
> strncpy (ar_block->header.arch_name, f_volhdr, NAMSIZ-1);
> ar_block->header.arch_name[NAMSIZ-1] = '\0';
> }
791c797,799
< strcpy (real_s_name, save_name);
---
> strncpy (real_s_name, save_name, NAMSIZ-1);
> real_s_name[NAMSIZ-1] = '\0';
>
991c999,1000
< strcpy (real_s_name, save_name);
---
> strncpy (real_s_name, save_name, NAMSIZ-1);
> real_s_name[NAMSIZ-1] = '\0';
>Release-Note:
>Audit-Trail:
>Unformatted: