aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Greenman <dg@FreeBSD.org>1994-11-06 10:17:13 +0000
committerDavid Greenman <dg@FreeBSD.org>1994-11-06 10:17:13 +0000
commit1e8ee278b695410f524b9509c24939dcba53ae2d (patch)
tree87f8b2e77d8be1bfe4213da33400eaf6f78b328e
parenta83c285c7ef19dd6f495f82b7a11a4a686581b05 (diff)
downloadsrc-1e8ee278b695410f524b9509c24939dcba53ae2d.tar.gz
src-1e8ee278b695410f524b9509c24939dcba53ae2d.zip
From Johannes Stille:
When we get an EN8 response while we're already sending the file using the i protocol, this can happen: In send.c, flocal_send_await_reply() is called. This function calls flocal_send_fail() to process the aborted transfer. After this, we run into the branch that calls ffileseekend() to force the end of the actual transfer. Now flocal_send_fail() frees qtrans, but qtrans is still used later! I propose to fix this by moving the usfree_send(qtrans) out of flocal_send_fail(), as in the patch I append to this mail. ... I have found a race condition in the uucp 1.05 code. The typical result is that the connections mysteriously fails with "conversation failed", even while all files were transmitted. This is the problem: At least for the i protocol, the code to send a packet can receive and process packets after sending. In several places in the code, we send a command and then prepare to receive an answer. Now the answer might already arrive during the call that sends the command while we aren't ready to process it. The general solution is IMHO first to do all preparations and only as a last step to send out the command. Reviewed by: John Dyson Submitted by: Johannes Stille
Notes
Notes: svn path=/head/; revision=4208
-rw-r--r--gnu/libexec/uucp/uucico/rec.c35
-rw-r--r--gnu/libexec/uucp/uucico/send.c21
2 files changed, 32 insertions, 24 deletions
diff --git a/gnu/libexec/uucp/uucico/rec.c b/gnu/libexec/uucp/uucico/rec.c
index f2f9f09665f8..d9f907a95183 100644
--- a/gnu/libexec/uucp/uucico/rec.c
+++ b/gnu/libexec/uucp/uucico/rec.c
@@ -26,7 +26,7 @@
#include "uucp.h"
#if USE_RCS_ID
-const char rec_rcsid[] = "$Id: rec.c,v 1.34 1994/04/04 03:25:12 ian Rel $";
+const char rec_rcsid[] = "$Id: rec.c,v 1.2 1994/05/07 18:13:55 ache Exp $";
#endif
#include <errno.h>
@@ -793,15 +793,6 @@ fremote_send_reply (qtrans, qdaemon)
else
sprintf (ab + 2, " 0x%lx", (unsigned long) qtrans->ipos);
- if (! (*qdaemon->qproto->pfsendcmd) (qdaemon, ab, qtrans->ilocal,
- qtrans->iremote))
- {
- (void) ffileclose (qtrans->e);
- (void) remove (qinfo->ztemp);
- urrec_free (qtrans);
- return FALSE;
- }
-
qinfo->freplied = TRUE;
if (qdaemon->qproto->pffile != NULL)
@@ -818,6 +809,15 @@ fremote_send_reply (qtrans, qdaemon)
}
}
+ if (! (*qdaemon->qproto->pfsendcmd) (qdaemon, ab, qtrans->ilocal,
+ qtrans->iremote))
+ {
+ (void) ffileclose (qtrans->e);
+ (void) remove (qinfo->ztemp);
+ urrec_free (qtrans);
+ return FALSE;
+ }
+
return TRUE;
}
@@ -862,6 +862,8 @@ fremote_send_fail_send (qtrans, qdaemon)
struct srecfailinfo *qinfo = (struct srecfailinfo *) qtrans->pinfo;
char ab[4];
boolean fret;
+ int ilocal = qtrans->ilocal;
+ int iremote = qtrans->iremote;
/* Wait for the end of file marker if we haven't gotten it yet. */
if (! qinfo->freceived)
@@ -898,9 +900,6 @@ fremote_send_fail_send (qtrans, qdaemon)
ab[3] = '\0';
- fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, ab, qtrans->ilocal,
- qtrans->iremote);
-
qinfo->fsent = TRUE;
if (qinfo->freceived)
@@ -909,6 +908,8 @@ fremote_send_fail_send (qtrans, qdaemon)
utransfree (qtrans);
}
+ fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, ab, ilocal, iremote);
+
return fret;
}
@@ -1235,6 +1236,8 @@ frec_file_send_confirm (qtrans, qdaemon)
struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
const char *zsend;
boolean fret;
+ int ilocal = qtrans->ilocal;
+ int iremote = qtrans->iremote;
if (! qinfo->fmoved)
zsend = "CN5";
@@ -1252,9 +1255,6 @@ frec_file_send_confirm (qtrans, qdaemon)
zsend = "CYM";
}
- fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend,
- qtrans->ilocal, qtrans->iremote);
-
/* Now, if that was a remote command, then when the confirmation
message is acked we no longer have to remember that we received
that file. */
@@ -1262,6 +1262,9 @@ frec_file_send_confirm (qtrans, qdaemon)
usent_receive_ack (qdaemon, qtrans);
urrec_free (qtrans);
+
+ fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend, ilocal, iremote);
+
return fret;
}
diff --git a/gnu/libexec/uucp/uucico/send.c b/gnu/libexec/uucp/uucico/send.c
index 63c9df660a8f..cf8b5b1bc98c 100644
--- a/gnu/libexec/uucp/uucico/send.c
+++ b/gnu/libexec/uucp/uucico/send.c
@@ -26,7 +26,7 @@
#include "uucp.h"
#if USE_RCS_ID
-const char send_rcsid[] = "$Id: send.c,v 1.46 1994/04/10 23:13:29 ian Rel $";
+const char send_rcsid[] = "$Id: send.c,v 1.2 1994/05/07 18:13:57 ache Exp $";
#endif
#include <errno.h>
@@ -346,9 +346,6 @@ flocal_send_fail (qtrans, qcmd, qdaemon, zwhy)
(void) fsysdep_did_work (qcmd->pseq);
- if (qtrans != NULL)
- usfree_send (qtrans);
-
return TRUE;
}
@@ -371,8 +368,12 @@ flocal_send_request (qtrans, qdaemon)
/* Make sure the file meets any remote size restrictions. */
if (qdaemon->cmax_receive != -1
&& qdaemon->cmax_receive < qinfo->cbytes)
- return flocal_send_fail (qtrans, &qtrans->s, qdaemon,
+ {
+ fret = flocal_send_fail (qtrans, &qtrans->s, qdaemon,
"too large for receiver");
+ usfree_send (qtrans);
+ return fret;
+ }
/* Make sure the file still exists--it may have been removed between
the conversation startup and now. After we have sent over the S
@@ -595,7 +596,10 @@ flocal_send_await_reply (qtrans, qdaemon, zdata, cdata)
{
if (! flocal_send_fail ((struct stransfer *) NULL, &qtrans->s,
qdaemon, zerr))
- return FALSE;
+ {
+ usfree_send (qtrans);
+ return FALSE;
+ }
}
/* If the protocol does not support multiple channels, we can
@@ -1036,6 +1040,8 @@ fremote_rec_fail_send (qtrans, qdaemon)
enum tfailure *ptinfo = (enum tfailure *) qtrans->pinfo;
const char *z;
boolean fret;
+ int ilocal = qtrans->ilocal;
+ int iremote = qtrans->iremote;
switch (*ptinfo)
{
@@ -1051,10 +1057,9 @@ fremote_rec_fail_send (qtrans, qdaemon)
break;
}
- fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, z, qtrans->ilocal,
- qtrans->iremote);
xfree (qtrans->pinfo);
utransfree (qtrans);
+ fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, z, ilocal, iremote);
return fret;
}