Re: Freebcp coredump

"Frediano Ziglio" <[email protected]>
Newsgroups gmane.comp.db.tds.freetds
Message-ID <[email protected]>
2008/12/9  <[email protected]>:
> Hello James:
>
> Here is aditional information that i get with gdb
>
> (gdb) backtrace
> #0  0x60000000c01d8e20:1 in strlen+0x41 () from /usr/lib/hpux32/libc.so.1
> #1  0x60000000c025efe0:0 in strdup+0x30 () from /usr/lib/hpux32/libc.so.1
> #2  0x60000000cabdd970:0 in bcp_init () at bcp.c:181
> #3  0x4002a40:0 in file_formatted (pdata=0x7fffeea4, dir=2) at
> freebcp.c:580
> #4  0x40050c0:0 in main (argc=9, argv=0x7ffff368) at freebcp.c:96
>
> (gdb) frame 4
> #4  0x40050c0:0 in main (argc=9, argv=0x7ffff368) at freebcp.c:96
> 96                      ok = file_formatted(&params, dbproc,
> params.direction);
>
> (gdb) info locals
> params = {dbobject = 0x400180e0 "VW_GETDATA",
>  dbdirection = "out\000\000\000\000\000\000", direction = 2,
>  hostfilename = "res_eact.txt\000\000", formatfile = "/home/mysystem/fmt
> ",
>  errorfile = 0x6d705f76 <Address 0x6d705f76 out of bounds>,
>  interfacesfile = "ig.fmt\000\000\000\000\000\000\000\000", firstrow = 0,
>  lastrow = 0, batchsize = 1000, maxerrors = 10, textsize = 4096,
>  fieldterm = 0x0, fieldtermlen = 0, rowterm = 0x0, rowtermlen = 0,
>  user = 0x400192f0 "user", pass = 0x40019310 "password",
>  server = 0x40018110 "MYSERVER", hint = 0x0, options = 0x0,
>  packetsize = 0, mflag = 0, fflag = 1, eflag = 1, Fflag = 0, Lflag = 0,
>  bflag = 0, nflag = 0, cflag = 0, tflag = 0, rflag = 0, Uflag = 1, Iflag
> = 0,
>  Sflag = 1, Pflag = 1, Tflag = 0, Aflag = 0, Eflag = 0}
>
> (gdb) frame 3
> #3  0x4002a40:0 in file_formatted (pdata=0x7fffeea4, dir=2) at
> freebcp.c:580
> 580             if (FAIL == bcp_init(dbproc, pdata->dbobject,
> pdata->hostfilename, pdata->errorfile, dir))
>
> (gdb) info locals
> li_rowsread = 1610612736
>
> (gdb) info args
> pdata = (struct pd *) 0x7fffeea4
> dir = 2
>
> (gdb) frame 2
> #2  0x60000000cabdd970:0 in bcp_init () at bcp.c:181
> 181                             if ((dbproc->hostfileinfo->errorfile =
> strdup(errfile)) == NULL)
>
> Thanks a lot
>
> Daymel
>
>

Bingo !!!
This is a buffer overflow due to FILENAME_MAX definition in HP-UX.
This define is quite short leading in a buffer overflow in freebcp
(the bug reside in freebcp.c). You got the corruption setting
formatfile. A strcpyn should be used to avoid overflow. The best
solution (IMHO) is to use char * in freebcp.c for hostfilename,
formatfile and interfacesfile requiring strdup instead of strcpy.

Please try attached patch and let me know.

freddy77

_______________________________________________
FreeTDS mailing list
[email protected]
http://lists.ibiblio.org/mailman/listinfo/freetds
bcp.diff (application/octet-stream, 2.4 KB)
--- src/apps/freebcp.c	28 May 2008 20:08:48 -0000	1.49
+++ src/apps/freebcp.c	9 Dec 2008 13:45:07 -0000
@@ -177,40 +177,42 @@
 	} else if (strcmp(pdata->dbdirection, "out") == 0) {
 		pdata->direction = DB_OUT;
 	} else if (strcmp(pdata->dbdirection, "queryout") == 0) {
 		pdata->direction = DB_QUERYOUT;
 	} else {
 		fprintf(stderr, "Copy direction must be either 'in', 'out' or 'queryout'.\n");
 		return (FALSE);
 	}
 
 	/* argument 3 - the datafile name */
-	strcpy(pdata->hostfilename, argv[3]);
+	free(pdata->hostfilename);
+	pdata->hostfilename = strdup(argv[3]);
 
 	/* 
 	 * Get the rest of the arguments 
 	 */
 	optind = 4; /* start processing options after table, direction, & filename */
 	while ((ch = getopt(argc, argv, "m:f:e:F:L:b:t:r:U:P:I:S:h:T:A:O:0:ncEdvV")) != -1) {
 		switch (ch) {
 		case 'v':
 		case 'V':
 			printf("freebcp version %s\n", software_version);
 			return FALSE;
 			break;
 		case 'm':
 			pdata->mflag++;
 			pdata->maxerrors = atoi(optarg);
 			break;
 		case 'f':
 			pdata->fflag++;
-			strcpy(pdata->formatfile, optarg);
+			free(pdata->formatfile);
+			pdata->formatfile = strdup(optarg);
 			break;
 		case 'e':
 			pdata->eflag++;
 			pdata->errorfile = strdup(optarg);
 			break;
 		case 'F':
 			pdata->Fflag++;
 			pdata->firstrow = atoi(optarg);
 			break;
 		case 'L':
@@ -255,21 +257,22 @@
 				fgets(pwd, 255, stdin);
 				nl = strchr(pwd, '\n');
 				if(nl) *nl = '\0';
 				pdata->pass = strdup(pwd);
 			} else {
 				pdata->pass = strdup(optarg);
 			}
 			break;
 		case 'I':
 			pdata->Iflag++;
-			strcpy(pdata->interfacesfile, optarg);
+			free(pdata->interfacesfile);
+			pdata->interfacesfile = strdup(optarg);
 			break;
 		case 'S':
 			pdata->Sflag++;
 			pdata->server = strdup(optarg);
 			break;
 		case 'h':
 			pdata->hint = strdup(optarg);
 			break;
 		case 'O':
 		case '0':
--- src/apps/freebcp.h	6 Oct 2006 21:28:20 -0000	1.12
+++ src/apps/freebcp.h	9 Dec 2008 13:45:07 -0000
@@ -26,24 +26,24 @@
 	GET_FROMLABEL,
 	GET_TOLABEL,
 	GET_HINT
 };
 
 typedef struct pd
 {
 	char *dbobject;
 	char dbdirection[10];
 	DBINT direction;
-	char hostfilename[FILENAME_MAX + 1];
-	char formatfile[FILENAME_MAX + 1];
+	char *hostfilename;
+	char *formatfile;
 	char *errorfile;
-	char interfacesfile[FILENAME_MAX + 1];
+	char *interfacesfile;
 	int firstrow;
 	int lastrow;
 	int batchsize;
 	int maxerrors;
 	int textsize;
 	char *fieldterm;
 	int fieldtermlen;
 	char *rowterm;
 	int rowtermlen;
 	char *user;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.