Subject: bin/1431: ftp coredumps if a command line has more than 20 arguments
To: None <gnats-bugs@gnats.netbsd.org>
From: John F. Woods <jfw@jfwhome.funhouse.com>
List: netbsd-bugs
Date: 09/01/1995 10:42:14
>Number: 1431
>Category: bin
>Synopsis: ftp coredumps if a command line has more than 20 arguments
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Sep 1 16:35:02 1995
>Last-Modified:
>Originator: John F. Woods
>Organization:
Misanthropes-R-Us
>Release: present in 9/1/95 sup
>Environment:
System: NetBSD jfwhome.funhouse.com 1.0A NetBSD 1.0A (JFW) #14: Wed Aug 9 21:35:57 EDT 1995 jfw@jfwhome.funhouse.com:/usr/src/sys/arch/i386/compile/JFW i386
>Description:
ftp can be made to coredump if given more than 20 arguments on a
command line. There is a fixed-length buffer of word pointers whose bounds
are not checked.
>How-To-Repeat:
From: Jukka Marin <jmarin@teeri.jmp.fi>
ftp in -current (950819 snapshot) does this:
jmarin@silakka ~ %(42)ftp teeri
Connected to teeri.jmp.fi.
220 teeri.jmp.fi FTP server (SunOS 4.1) ready.
Name (teeri:jmarin):
331 Password required for jmarin.
Password:
230 User jmarin logged in.
ftp> cd /tmp
250 CWD command successful.
ftp> lcd /tmp
Local directory now /var/tmp
ftp> mget a* b* c* d* e* f* g* h* i* j* k* l* m* n* o* p* q* r* s* t* u* v* w* x* y* z*
Segmentation fault
>Fix:
A nearly-arbitrary number of arguments can be accepted by the following:
*** ftp_var.h.orig Fri Sep 1 07:48:37 1995
--- ftp_var.h Fri Sep 1 07:49:21 1995
***************
*** 98,104 ****
char argbuf[200]; /* argument storage buffer */
char *argbase; /* current storage point in arg buffer */
int margc; /* count of arguments on input line */
! char *margv[20]; /* args parsed from input line */
int cpend; /* flag: if != 0, then pending server reply */
int mflag; /* flag: if != 0, then active multi command */
--- 98,105 ----
char argbuf[200]; /* argument storage buffer */
char *argbase; /* current storage point in arg buffer */
int margc; /* count of arguments on input line */
! char **margv; /* args parsed from input line */
! int maxmargc; /* how large margv is currently */
int cpend; /* flag: if != 0, then pending server reply */
int mflag; /* flag: if != 0, then active multi command */
*** main.c.orig Fri Sep 1 07:48:46 1995
--- main.c Fri Sep 1 08:00:56 1995
***************
*** 317,329 ****
{
char **argp;
margc = 0;
argp = margv;
stringbase = line; /* scan from first of buffer */
argbase = argbuf; /* store from first of buffer */
slrflag = 0;
! while (*argp++ = slurpstring())
margc++;
}
/*
--- 317,347 ----
{
char **argp;
+ if (margv == 0) {
+ if ((margv = malloc(20 * sizeof(char *))) == 0) {
+ perror("can't allocate argv array");
+ exit(1);
+ }
+ maxmargc = 20;
+ }
margc = 0;
argp = margv;
stringbase = line; /* scan from first of buffer */
argbase = argbuf; /* store from first of buffer */
slrflag = 0;
! while (*argp++ = slurpstring()) {
margc++;
+ if (margc == maxmargc) {
+ if ((margv = realloc(margv,
+ (maxmargc + 20)*sizeof(char *)))
+ == NULL) {
+ perror("can't reallocate argv array");
+ exit(1);
+ }
+ maxmargc += 20;
+ argp = margv + margc;
+ }
+ }
}
/*
>Audit-Trail:
>Unformatted: