From nobody@FreeBSD.ORG  Sat Jan  8 01:51:31 2000
Return-Path: <nobody@FreeBSD.ORG>
Received: by hub.freebsd.org (Postfix, from userid 32767)
	id 12CCB15207; Sat,  8 Jan 2000 01:51:30 -0800 (PST)
Message-Id: <20000108095130.12CCB15207@hub.freebsd.org>
Date: Sat,  8 Jan 2000 01:51:30 -0800 (PST)
From: klh@netcom.com
Sender: nobody@FreeBSD.ORG
To: freebsd-gnats-submit@FreeBSD.org
Subject: rcp -p fails when times have high bit set
X-Send-Pr-Version: www-1.0

>Number:         15981
>Category:       bin
>Synopsis:       rcp -p fails when times have high bit set
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    sheldonh
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Jan  8 02:00:01 PST 2000
>Closed-Date:    Tue Aug 8 05:14:20 PDT 2000
>Last-Modified:  Tue Aug 08 05:15:20 PDT 2000
>Originator:     Ken Harrenstien
>Release:        3.3
>Organization:
>Environment:
n/a
>Description:
This code fragment should be using %ul instead of %ld for both fields.

	if (pflag) {
		(void)snprintf(path, sizeof(path), "T%ld 0 %ld 0\n",
		    (long)statp->st_mtimespec.tv_sec,
		    (long)statp->st_atimespec.tv_sec);
		(void)write(rem, path, strlen(path));


>How-To-Repeat:
Create a file with a st_mtime that has the high bit set.  Attempt
to copy it with "rcp -p foo target:."
where target is a 64-bit system such as an Alpha (running D/U in this
case).  Will fail with a "mtime.sec not delimited" screwup message
due to presence of a minus sign.

However, it should not be necessary to reproduce this to realize that
the given code fragment is a time bomb, so to speak...
>Fix:


>Release-Note:
>Audit-Trail:

From: Bruce Evans <bde@zeta.org.au>
To: klh@netcom.com
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: bin/15981: rcp -p fails when times have high bit set
Date: Sat, 8 Jan 2000 23:49:24 +1100 (EST)

 On Sat, 8 Jan 2000 klh@netcom.com wrote:
 
 > >Description:
 > This code fragment should be using %ul instead of %ld for both fields.
 > 
 > 	if (pflag) {
 > 		(void)snprintf(path, sizeof(path), "T%ld 0 %ld 0\n",
 > 		    (long)statp->st_mtimespec.tv_sec,
 > 		    (long)statp->st_atimespec.tv_sec);
 > 		(void)write(rem, path, strlen(path));
 
 Not under systems with signed time_t like FreeBSD.  Using %ul would
 break times before the epoch (about 1970).
 
 > >How-To-Repeat:
 > Create a file with a st_mtime that has the high bit set.  Attempt
 > to copy it with "rcp -p foo target:."
 > where target is a 64-bit system such as an Alpha (running D/U in this
 > case).  Will fail with a "mtime.sec not delimited" screwup message
 > due to presence of a minus sign.
 
 This seems to be a defect in D/U :-).  An st_mtime with the high bit set
 is negative.  Negative times give undefined behaviour in POSIX.1.  FreeBSD
 supports them, but actually using them gives interoperability problems like
 the one you noticed.
 
 > >Fix:
 
 Don't create files with an st_mtime that is before the epoch.
 
 Related bugs:
 
 FreeBSD's rcp.c lacks range checking of times sent by the target system.
 Large times are silently truncated to (time_t)LONG_MAX, i.e., to LONG_MAX
 on i386's and -1 on alphas.  Large negative times are silently truncated
 to (time_t)LONG_MIN, i.e., to LONG_MIN on i386's and 0 on alphas.
 
 Bruce
 
 

From: Ken Harrenstien <klh@netcom.com>
To: Bruce Evans <bde@zeta.org.au>
Cc: klh@netcom.com, freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: bin/15981: rcp -p fails when times have high bit set
Date: Sat, 8 Jan 100 11:59:38 PST

 > Not under systems with signed time_t like FreeBSD.  Using %ul would
 > break times before the epoch (about 1970).
 
 Sigh.  OK, I didn't realize this was a conscious decision in FreeBSD.
 
 I assume there are good reasons for this (to me) surprising choice.
 If there is anything that explains the rationale, I would like to read
 about it.  In particular, what's the plan for Jan 18, 2038?
 Thanks.
 
 > > >Fix:
 > 
 > Don't create files with an st_mtime that is before the epoch.
 
 Well, the files in question are created by FreeBSD's user-FTP when
 retrieving them from a SunOS system, which responds to MDTM with
 "213 191000107192503".  Looks like the old BSD ftp did something like
 printf("19%2d", t->tm_year).  Should we:
 	(a) do nothing and continue to get screwed,
 	(b) test for negatives and substitute current time,
 	(c) test for this case (eg by checking string length) and DWIM it,
 	(d) convince Sun to fix their code (hahahahaha)
 ?
 
 --Ken
 
State-Changed-From-To: open->suspended 
State-Changed-By: sheldonh 
State-Changed-When: Tue Jan 18 13:34:08 PST 2000 
State-Changed-Why:  
Fixed in CURRENT's rev 1.9 of util.c: 

http://www.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/ftp/util.c.diff?r1=1.8&r2=1.9 

Only _critical_ bugfixes are merged into the STABLE branch immediately, 
so I'll leave this to simmer for a few weeks. 


Responsible-Changed-From-To: freebsd-bugs->sheldonh 
Responsible-Changed-By: sheldonh 
Responsible-Changed-When: Tue Jan 18 13:34:08 PST 2000 
Responsible-Changed-Why:  
reminder for me to merge to STABLE. 
State-Changed-From-To: suspended->closed 
State-Changed-By: sheldonh 
State-Changed-When: Tue Aug 8 05:14:20 PDT 2000 
State-Changed-Why:  
Merged onto the then-stable RELENG_3 branch on 2000-03-27. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=15981 
>Unformatted:
