[krbdev.mit.edu #6524] ftp and rcp behave oddly with large files on 32-bit systems

The RT System itself via RT rt-comment at krbdev.mit.edu
Tue Jul 7 10:06:02 EDT 2009


>From krb5-bugs-incoming-bounces at PCH.mit.edu  Tue Jul  7 14:06:01 2009
Return-Path: <krb5-bugs-incoming-bounces at PCH.mit.edu>
X-Original-To: krb5-send-pr-nospam1 at krbdev.mit.edu
Received: from pch.mit.edu (PCH.MIT.EDU [18.7.21.90])
	by krbdev.mit.edu (Postfix) with ESMTP id 73A80CC838;
	Tue,  7 Jul 2009 14:06:01 +0000 (UTC)
Received: from pch.mit.edu (pch.mit.edu [127.0.0.1])
	by pch.mit.edu (8.13.6/8.12.8) with ESMTP id n67E612a004515;
	Tue, 7 Jul 2009 10:06:01 -0400
Received: from pacific-carrier-annex.mit.edu (PACIFIC-CARRIER-ANNEX.MIT.EDU
	[18.7.21.83])
	by pch.mit.edu (8.13.6/8.12.8) with ESMTP id n66Mmagu004961
	for <krb5-bugs-incoming at PCH.mit.edu>; Mon, 6 Jul 2009 18:48:36 -0400
Received: from mit.edu (W92-130-BARRACUDA-3.MIT.EDU [18.7.21.224])
	by pacific-carrier-annex.mit.edu (8.13.6/8.9.2) with ESMTP id
	n66MmSKE021123
	for <krb5-bugs at mit.edu>; Mon, 6 Jul 2009 18:48:29 -0400 (EDT)
Received: from mx1.redhat.com (localhost [127.0.0.1])
	by mit.edu (Spam Firewall) with ESMTP id 1A8892263314
	for <krb5-bugs at mit.edu>; Mon,  6 Jul 2009 18:48:27 -0400 (EDT)
Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by mit.edu with
	ESMTP id RaQx1JmAOZfjSK0W for <krb5-bugs at mit.edu>;
	Mon, 06 Jul 2009 18:48:27 -0400 (EDT)
Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com
	[172.16.52.254])
	by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n66MmRgI011249
	for <krb5-bugs at mit.edu>; Mon, 6 Jul 2009 18:48:27 -0400
Received: from blade.bos.redhat.com (blade.bos.redhat.com [10.16.0.23])
	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n66MmQjS005981
	for <krb5-bugs at mit.edu>; Mon, 6 Jul 2009 18:48:27 -0400
Received: from blade.bos.redhat.com (localhost.localdomain [127.0.0.1])
	by blade.bos.redhat.com (8.14.3/8.14.2) with ESMTP id n66MmQVI020964
	for <krb5-bugs at mit.edu>; Mon, 6 Jul 2009 18:48:26 -0400
Received: (from nalin at localhost)
	by blade.bos.redhat.com (8.14.3/8.14.3/Submit) id n66MmQeM020962;
	Mon, 6 Jul 2009 18:48:26 -0400
Date: Mon, 6 Jul 2009 18:48:26 -0400
Message-Id: <200907062248.n66MmQeM020962 at blade.bos.redhat.com>
To: krb5-bugs at mit.edu
Subject: ftp and rcp behave oddly with large files on 32-bit systems
From: nalin at redhat.com
X-send-pr-version: 3.99
X-Scanned-By: MIMEDefang 2.42
X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254
X-Spam-Score: 3.507
X-Spam-Level: *** (3.507)
X-Spam-Flag: NO
X-Mailman-Approved-At: Tue, 07 Jul 2009 10:05:59 -0400
X-BeenThere: krb5-bugs-incoming at mailman.mit.edu
X-Mailman-Version: 2.1.6
Precedence: list
Reply-To: nalin at redhat.com
Sender: krb5-bugs-incoming-bounces at PCH.mit.edu
Errors-To: krb5-bugs-incoming-bounces at PCH.mit.edu


>Submitter-Id:	net
>Originator:	
>Organization:
>Confidential:	no
>Synopsis:	ftp and rcp behave oddly with large files on 32-bit systems
>Severity:	non-critical
>Priority:	low
>Category:	krb5-appl
>Class:		sw-bug
>Release:	1.7
>Environment:
	
System: Linux blade.bos.redhat.com 2.6.29.4-167.fc11.x86_64 #1 SMP Wed May 27 17:27:08 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
Architecture: x86_64

>Description:
	When I transfer a large (>4GB in size) file using gssftp, ftpd prints
	a negative file size when it initiates the transfer.  When I attempt
	to transfer the file using rcp, it fails.
>How-To-Repeat:
	Use dd to create a potentially-sparse file on a 32-bit server:
	  dd if=/dev/urandom bs=1M seek=6143 of=largefile count=1
	Use ftp to connect to ftpd and attempt to download the file, and
	ftpd will display a negative file size.
	Attempt to copy it using rcp, and you'll get a "protocol screwup:
	size not delimited" error when the sender sends a negative file
	size to the receiver.
>Fix:
	This patch adds calls to AC_SYS_LARGEFILE to the configure scripts
	for gssftp and the bsd applications.  Because off_t might now be
	larger than a long, it also checks for fseeko() and uses that if
	it's found.  Whenever an off_t needs to be displayed, if the system
	has a "long long" type, the off_t value is displayed as a "long
	long" rather than just as a "long".  This takes care of the problem
	on my i386 system, though it hasn't gotten any testing on other OSs.
Index: src/appl/gssftp/configure.in
===================================================================
--- src/appl/gssftp/configure.in	(revision 22425)
+++ src/appl/gssftp/configure.in	(working copy)
@@ -12,6 +12,9 @@
 AC_HEADER_STDARG
 AC_CHECK_HEADER(termios.h,[AC_CHECK_FUNC(cfsetispeed,AC_DEFINE(POSIX_TERMIOS,1,[Define if POSIX termios interface found]))])
 AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/select.h sys/sockio.h paths.h)
+AC_SYS_LARGEFILE
+AC_FUNC_FSEEKO
+AC_CHECK_TYPES([long long])
 CHECK_UTMP
 DECLARE_SYS_ERRLIST
 AC_REPLACE_FUNCS(getdtablesize)
Index: src/appl/gssftp/ftp/ftp_var.h
===================================================================
--- src/appl/gssftp/ftp/ftp_var.h	(revision 22425)
+++ src/appl/gssftp/ftp/ftp_var.h	(working copy)
@@ -46,12 +46,18 @@
 #define FDOPEN_SOCKET(s, mode) fdopen_socket(s, mode)
 #define SOCKETNO(fd) _get_osfhandle(fd)
 #define PERROR_SOCKET(str) do { errno = SOCKET_ERRNO; perror(str); } while(0)
+#define FSEEK(fd, offset, whence) fseek(fd, (long) offset, whence)
 #else
 #define FCLOSE_SOCKET(f) fclose(f)
 #define FDOPEN_SOCKET(s, mode) fdopen(s, mode)
 #define SOCKETNO(fd) (fd)
 #define PERROR_SOCKET(str) perror(str)
+#ifdef HAVE_FSEEKO
+#define FSEEK(fd, offset, whence) fseeko(fd, (off_t) offset, whence)
+#else
+#define FSEEK(fd, offset, whence) fseek(fd, (long) offset, whence)
 #endif
+#endif
 
 #ifdef _WIN32
 typedef void (*sig_t)(int);
Index: src/appl/gssftp/ftp/ftp.c
===================================================================
--- src/appl/gssftp/ftp/ftp.c	(revision 22425)
+++ src/appl/gssftp/ftp/ftp.c	(working copy)
@@ -150,7 +150,11 @@
 
 static void proxtrans (char *, char *, char *);
 static int initconn (void);
+#ifdef HAVE_LONG_LONG
+static void ptransfer (char *, long long, struct timeval *, struct timeval *);
+#else
 static void ptransfer (char *, long, struct timeval *, struct timeval *);
+#endif
 static void abort_remote (FILE *);
 static void tvsub (struct timeval *, struct timeval *, struct timeval *);
 static char *gunique (char *);
@@ -775,7 +779,11 @@
 	FILE *volatile fin, *volatile dout = 0;
 	int (*volatile closefunc)();
 	volatile sig_t oldintr, oldintp;
+#ifdef HAVE_LONG_LONG
+	volatile long long bytes = 0, hashbytes = HASHBYTES;
+#else
 	volatile long bytes = 0, hashbytes = HASHBYTES;
+#endif
 	char *volatile lmode;
 	unsigned char buf[FTP_BUFSIZ], *bufp;
 
@@ -872,7 +880,7 @@
 
 	if (restart_point &&
 	    (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
-		if (fseek(fin, (long) restart_point, 0) < 0) {
+		if (FSEEK(fin, restart_point, 0) < 0) {
 			fprintf(stderr, "local: %s: %s\n", local,
 				strerror(errno));
 			restart_point = 0;
@@ -1266,7 +1274,7 @@
 		if (restart_point) {
 			register int i, n, ch;
 
-			if (fseek(fout, 0L, L_SET) < 0)
+			if (FSEEK(fout, 0L, L_SET) < 0)
 				goto done;
 			n = restart_point;
 			for (i = 0; i++ < n;) {
@@ -1275,7 +1283,7 @@
 				if (ch == '\n')
 					i++;
 			}
-			if (fseek(fout, 0L, L_INCR) < 0) {
+			if (FSEEK(fout, 0L, L_INCR) < 0) {
 done:
 				fprintf(stderr, "local: %s: %s\n", local,
 					strerror(errno));
@@ -1538,8 +1546,13 @@
 	return (FDOPEN_SOCKET(data, lmode));
 }
 
+#ifdef HAVE_LONG_LONG
+static void ptransfer(char *direction, long long bytes,
+		      struct timeval *t0, struct timeval *t1)
+#else
 static void ptransfer(char *direction, long bytes,
 		      struct timeval *t0, struct timeval *t1)
+#endif
 {
 	struct timeval td;
 	float s, kbs;
@@ -1549,8 +1562,13 @@
 		s = td.tv_sec + (td.tv_usec / 1000000.);
 #define	nz(x)	((x) == 0 ? 1 : (x))
 		kbs = (bytes / nz(s))/1024.0;
+#ifdef HAVE_LONG_LONG
+		printf("%lld bytes %s in %.2g seconds (%.2g Kbytes/s)\n",
+		    bytes, direction, s, kbs);
+#else
 		printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)\n",
 		    bytes, direction, s, kbs);
+#endif
 	}
 }
 
Index: src/appl/gssftp/ftpd/ftpcmd.y
===================================================================
--- src/appl/gssftp/ftpd/ftpcmd.y	(revision 22425)
+++ src/appl/gssftp/ftpd/ftpcmd.y	(working copy)
@@ -1497,12 +1497,20 @@
 		    (stbuf.st_mode&S_IFMT) != S_IFREG)
 			reply(550, "%s: not a plain file.", filename);
 		else
+#ifdef HAVE_LONG_LONG
+			reply(213, "%llu", (long long) stbuf.st_size);
+#else
 			reply(213, "%lu", (long) stbuf.st_size);
+#endif
 		break;}
 	case TYPE_A: {
 		FILE *fin;
 		register int c;
+#ifdef HAVE_LONG_LONG
+		register long long count;
+#else
 		register long count;
+#endif
 		struct stat stbuf;
 		fin = fopen(filename, "r");
 		if (fin == NULL) {
@@ -1524,7 +1532,11 @@
 		}
 		(void) fclose(fin);
 
+#ifdef HAVE_LONG_LONG
+		reply(213, "%lld", count);
+#else
 		reply(213, "%ld", count);
+#endif
 		break;}
 	default:
 		reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
Index: src/appl/gssftp/ftpd/ftpd_var.h
===================================================================
--- src/appl/gssftp/ftpd/ftpd_var.h	(revision 22425)
+++ src/appl/gssftp/ftpd/ftpd_var.h	(working copy)
@@ -41,6 +41,12 @@
 char *radix_error (int);
 int radix_encode (unsigned char *, unsigned char *, int *, int);
 
+#ifdef HAVE_FSEEKO
+#define FSEEK(fd, offset, whence) fseeko(fd, (off_t) offset, whence)
+#else
+#define FSEEK(fd, offset, whence) fseek(fd, (long) offset, whence)
+#endif
+
 /* ftpd.c */
 void ack(char *);
 int auth_data(char *);
Index: src/appl/gssftp/ftpd/ftpd.c
===================================================================
--- src/appl/gssftp/ftpd/ftpd.c	(revision 22425)
+++ src/appl/gssftp/ftpd/ftpd.c	(working copy)
@@ -1146,7 +1146,11 @@
 done:
 	(*closefunc)(fin);
 	if (logging > 2 && !cmd)
-	        syslog(LOG_NOTICE, "get: %i bytes transferred", byte_count);
+#ifdef HAVE_LONG_LONG
+	        syslog(LOG_NOTICE, "get: %lld bytes transferred", (long long) byte_count);
+#else
+	        syslog(LOG_NOTICE, "get: %ld bytes transferred", (long) byte_count);
+#endif
 }
 
 void
@@ -1191,7 +1195,7 @@
 			 * because we are changing from reading to
 			 * writing.
 			 */
-			if (fseek(fout, 0L, L_INCR) < 0) {
+			if (FSEEK(fout, 0L, L_INCR) < 0) {
 				perror_reply(550, name);
 				goto done;
 			}
@@ -1216,7 +1220,11 @@
 done:
 	(*closefunc)(fout);
 	if (logging > 2)
-	        syslog(LOG_NOTICE, "put: %i bytes transferred", byte_count);
+#ifdef HAVE_LONG_LONG
+	        syslog(LOG_NOTICE, "get: %lld bytes transferred", byte_count);
+#else
+	        syslog(LOG_NOTICE, "get: %ld bytes transferred", (long) byte_count);
+#endif
 }
 
 FILE *
@@ -1278,8 +1286,13 @@
 	byte_count = 0;
 	if (size != (off_t) -1)
 		/* cast size to long in case sizeof(off_t) > sizeof(long) */
+#ifdef HAVE_LONG_LONG
+		(void) snprintf (sizebuf, sizeof(sizebuf), " (%lld bytes)",
+				 (long long)size);
+#else
 		(void) snprintf (sizebuf, sizeof(sizebuf), " (%ld bytes)",
 				 (long)size);
+#endif
 	else
 		sizebuf[0] = '\0';
 	if (pdata >= 0) {
@@ -1991,13 +2004,23 @@
 		siglongjmp(urgcatch, 1);
 	}
 	if (strcmp(cp, "STAT") == 0) {
+#ifdef HAVE_LONG_LONG
 		if (file_size != (off_t) -1)
+			reply(213, "Status: %llu of %llu bytes transferred",
+			      (unsigned long long) byte_count, 
+			      (unsigned long long) file_size);
+		else
+			reply(213, "Status: %llu bytes transferred", 
+			      (unsigned long long) byte_count);
+#else
+		if (file_size != (off_t) -1)
 			reply(213, "Status: %lu of %lu bytes transferred",
 			      (unsigned long) byte_count, 
 			      (unsigned long) file_size);
 		else
 			reply(213, "Status: %lu bytes transferred", 
 			      (unsigned long) byte_count);
+#endif
 	}
 }
 
Index: src/appl/bsd/configure.in
===================================================================
--- src/appl/bsd/configure.in	(revision 22425)
+++ src/appl/bsd/configure.in	(working copy)
@@ -51,6 +51,9 @@
 AC_TYPE_MODE_T
 AC_CHECK_FUNCS(isatty inet_aton getenv gettosbyname killpg initgroups setpriority setreuid setresuid waitpid setsid ptsname setlogin tcgetpgrp tcsetpgrp setpgid strsave utimes rmufile rresvport_af)
 AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/filio.h sys/sockio.h sys/label.h sys/tty.h ttyent.h lastlog.h sys/select.h sys/ptyvar.h utmp.h sys/time.h sys/ioctl_compat.h paths.h arpa/nameser.h)
+AC_SYS_LARGEFILE
+AC_FUNC_FSEEKO
+AC_CHECK_TYPES([long long])
 AC_HEADER_STDARG
 AC_REPLACE_FUNCS(getdtablesize)
 dnl
Index: src/appl/bsd/krcp.c
===================================================================
--- src/appl/bsd/krcp.c	(revision 22425)
+++ src/appl/bsd/krcp.c	(working copy)
@@ -764,8 +764,13 @@
 		continue;
 	    }
 	}
+#ifdef HAVE_LONG_LONG
+	(void) snprintf(buf, sizeof(buf), "C%04o %lld %s\n",
+			(int) stb.st_mode&07777, (long long) stb.st_size, last);
+#else
 	(void) snprintf(buf, sizeof(buf), "C%04o %ld %s\n",
 			(int) stb.st_mode&07777, (long ) stb.st_size, last);
+#endif
 	(void) rcmd_stream_write(rem, buf, strlen(buf), 0);
 	if (response() < 0) {
 	    (void) close(f);




More information about the krb5-bugs mailing list