Bug 15981

Summary: rcp -p fails when times have high bit set
Product: Base System Reporter: klh <klh>
Component: binAssignee: Sheldon Hearn <sheldonh>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   

Description klh 2000-01-08 10:00:01 UTC
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...
Comment 1 Bruce Evans 2000-01-08 12:49:24 UTC
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
Comment 2 Sheldon Hearn freebsd_committer freebsd_triage 2000-01-18 21:34:08 UTC
State Changed
From-To: open->suspended

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. 


Comment 3 Sheldon Hearn freebsd_committer freebsd_triage 2000-01-18 21:34:08 UTC
Responsible Changed
From-To: freebsd-bugs->sheldonh

reminder for me to merge to STABLE. 
Comment 4 Sheldon Hearn freebsd_committer freebsd_triage 2000-08-08 13:14:20 UTC
State Changed
From-To: suspended->closed

Merged onto the then-stable RELENG_3 branch on 2000-03-27.
Comment 5 klh 2014-01-08 19:59:38 UTC
> 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