[net.bugs.uucp] BUG in System III UUCP

stan@teltone.UUCP () (01/04/84)

We discovered that bug a couple months ago.  Here's what I did to fix it.

The bad part of the code is in gio.c/grddata(), at the fwrite() call.
The return value of the fwrite() isn't checked.  Here's the appropriate
code section and changes in grddata():
	for (;;) {
		int len2;
		.
	  	.
		.
old line>>	/* fwrite(bufr, sizeof (char), len, fp2); */
		len2 = fwrite(bufr, sizeof (char), len, fp2);
		    /* need to check if the fwrite was successful.
		    /* if the filesystem is too full then the write will
		    /* fail.  'if' statement below is new.
		    /* (FAIL-1) = -2 will indicate a write failure; cntrl()
		    /* in cntrl.c will now unlink the temp file if the return
		    /* code is (FAIL-1) --StanT 10/27/83 */
		if (ferror(fp2) || (len2 != len))
			return(FAIL - 1);
		.
		.
		.

In cntrl.c/cntrl(), about midway through the file, is the code:

		WMESG(SNDFILE, YES);
		ret = (*Rddata)(Ifn, fp);
		fclose(fp);
		if (ret != 0) {
			(*Turnoff)();
			return(FAIL);
		}
		/* copy to user directory */

which could be changed to:

		WMESG(SNDFILE, YES);
		ret = (*Rddata)(Ifn, fp);
		fclose(fp);
		if (ret != 0) {
			(*Turnoff)();
			    /* If return is (FAIL-1) then there was a failure
			    /* writing to the TM. file; maybe the disk was full
			    /* so the TM. file should then be removed.
			    /* if(..) statement below does the trick; grddata()
			    /* in gio.c was modified to return FAIL-1
			    /*	--StanT--10/27/83  */
only change>>		if (ret == (FAIL-1)) unlink(Dfile);
			return(FAIL);
		}
		/* copy to user directory */

fair@dual.UUCP (Erik E. Fair) (01/04/84)

<FLAME ON, AFTERBURNERS FULL>

	Tonight, thanks to two idiots, we lost an unknown amount of mail
and news. The first idiot is the one who filled up our /usr/spool
filesystem. The second idiot is the one who wrote uucp in such a fashion
that it can receive a file into a full filesystem, and NOT NOTICE IT!
IDIOT! IDIOT! (shouted at the top of my lungs).

<FLAME OFF, BUG REPORT ON>

	UUCICO can and will receive and acknowledge receipt of files
all the while it is writing to a full filesystem (which has no effect,
other than to lose the incoming data). The catch is that since it
doesn't notice that everything is going down /dev/rathole, it will
acknowledge and the other end will duly destroy its copy of the data
that was transferred. I have not looked at the code yet, but I can
guess what I will find. Whomever wrote the stuff for shoving incoming
data into TM* files probably forgot to check for negative returns from
`write(2)' (`Gee, I didn't know write could fail...').

	For those of you who know what it is, the old BerkNet handles this
error quite gracefully, with no loss of data. It may not be a fast network,
but it is as cheap as UUCP, MUCH more flexible, and MUCH more reliable.
In the three years that I have used the BerkNet software (first at Berkeley,
and now I maintain it at DUAL) I have NEVER lost a file. I can't say the
same for uucp. Eric Schmidt, where ever you are, take a bow.

<BUG REPORT OFF, REQUEST ON>

	Anyone who sent mail to the `dual' system in the last two days
(arguably not many people, but the primary purpose of this is to report
the bug...) should resend. 

<REQUEST OFF, IRRITATION LINGERS>

	Erik E. Fair	{ucbvax,amd70,zehntel,unisoft,onyx,its}!dual!fair
			Dual Systems Corporation, Berkeley, California