mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-29 12:44:53 +01:00
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
This commit is contained in:
parent
196a487259
commit
a8a06384b5
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user