mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-22 17:39:53 +03:00
Merge pull request #1422 from domosekai/timeout
Fix use-after-free timeout issue for L2TP and SSTP
This commit is contained in:
commit
bd501ba9bf
@ -2008,7 +2008,6 @@ UINT CalcL2TPMss(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_SESSION *s)
|
|||||||
// Start the L2TP thread
|
// Start the L2TP thread
|
||||||
void StartL2TPThread(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_SESSION *s)
|
void StartL2TPThread(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_SESSION *s)
|
||||||
{
|
{
|
||||||
PPP_SESSION* underlyingSession;
|
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (l2tp == NULL || t == NULL || s == NULL)
|
if (l2tp == NULL || t == NULL || s == NULL)
|
||||||
{
|
{
|
||||||
@ -2037,11 +2036,9 @@ void StartL2TPThread(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_SESSION *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a PPP thread
|
// Create a PPP thread
|
||||||
underlyingSession = NewPPPSession(l2tp->Cedar, &t->ClientIp, t->ClientPort, &t->ServerIp, t->ServerPort,
|
s->Thread = NewPPPSession(l2tp->Cedar, &t->ClientIp, t->ClientPort, &t->ServerIp, t->ServerPort,
|
||||||
s->TubeSend, s->TubeRecv, L2TP_IPC_POSTFIX, tmp, t->HostName, l2tp->CryptName,
|
s->TubeSend, s->TubeRecv, L2TP_IPC_POSTFIX, tmp, t->HostName, l2tp->CryptName,
|
||||||
CalcL2TPMss(l2tp, t, s));
|
CalcL2TPMss(l2tp, t, s));
|
||||||
s->Thread = underlyingSession->SessionThread;
|
|
||||||
s->PPPSession = underlyingSession;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2145,9 +2142,9 @@ void L2TPProcessInterrupts(L2TP_SERVER *l2tp)
|
|||||||
{
|
{
|
||||||
L2TP_SESSION* s = LIST_DATA(t->SessionList, i);
|
L2TP_SESSION* s = LIST_DATA(t->SessionList, i);
|
||||||
|
|
||||||
if (s->PPPSession != NULL && s->PPPSession->DataTimeout > l2tpTimeout)
|
if (s->TubeRecv != NULL && s->TubeRecv->DataTimeout > l2tpTimeout)
|
||||||
{
|
{
|
||||||
l2tpTimeout = s->PPPSession->DataTimeout;
|
l2tpTimeout = s->TubeRecv->DataTimeout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,6 @@ struct L2TP_SESSION
|
|||||||
UINT64 DisconnectTimeout; // Disconnection completion time-out
|
UINT64 DisconnectTimeout; // Disconnection completion time-out
|
||||||
bool HasThread; // Whether have a thread
|
bool HasThread; // Whether have a thread
|
||||||
THREAD *Thread; // Thread
|
THREAD *Thread; // Thread
|
||||||
PPP_SESSION* PPPSession; // Underlying PPP session
|
|
||||||
TUBE *TubeSend; // Tube of PPP to L2TP direction
|
TUBE *TubeSend; // Tube of PPP to L2TP direction
|
||||||
TUBE *TubeRecv; // Tube of L2TP to PPP direction
|
TUBE *TubeRecv; // Tube of L2TP to PPP direction
|
||||||
UINT PseudowireType; // Type of L2TPv3 virtual line
|
UINT PseudowireType; // Type of L2TPv3 virtual line
|
||||||
|
@ -552,7 +552,7 @@ void PPPThread(THREAD *thread, void *param)
|
|||||||
// Entry point
|
// Entry point
|
||||||
|
|
||||||
// Create a new PPP session
|
// Create a new PPP session
|
||||||
PPP_SESSION *NewPPPSession(CEDAR *cedar, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, TUBE *send_tube, TUBE *recv_tube, char *postfix, char *client_software_name, char *client_hostname, char *crypt_name, UINT adjust_mss)
|
THREAD *NewPPPSession(CEDAR *cedar, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, TUBE *send_tube, TUBE *recv_tube, char *postfix, char *client_software_name, char *client_hostname, char *crypt_name, UINT adjust_mss)
|
||||||
{
|
{
|
||||||
PPP_SESSION *p;
|
PPP_SESSION *p;
|
||||||
THREAD *t;
|
THREAD *t;
|
||||||
@ -622,9 +622,7 @@ PPP_SESSION *NewPPPSession(CEDAR *cedar, IP *client_ip, UINT client_port, IP *se
|
|||||||
// Thread creation
|
// Thread creation
|
||||||
t = NewThread(PPPThread, p);
|
t = NewThread(PPPThread, p);
|
||||||
|
|
||||||
p->SessionThread = t;
|
return t;
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PPP processing functions
|
// PPP processing functions
|
||||||
@ -1549,6 +1547,10 @@ bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
|
|||||||
// Setting user timeouts
|
// Setting user timeouts
|
||||||
p->PacketRecvTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000 * 3 / 4; // setting to 3/4 of the user timeout
|
p->PacketRecvTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000 * 3 / 4; // setting to 3/4 of the user timeout
|
||||||
p->DataTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000;
|
p->DataTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000;
|
||||||
|
if (p->TubeRecv != NULL)
|
||||||
|
{
|
||||||
|
p->TubeRecv->DataTimeout = p->DataTimeout;
|
||||||
|
}
|
||||||
p->UserConnectionTimeout = (UINT64)p->Ipc->Policy->AutoDisconnect * 1000;
|
p->UserConnectionTimeout = (UINT64)p->Ipc->Policy->AutoDisconnect * 1000;
|
||||||
p->UserConnectionTick = Tick64();
|
p->UserConnectionTick = Tick64();
|
||||||
|
|
||||||
@ -2874,6 +2876,10 @@ bool PPPParseMSCHAP2ResponsePacket(PPP_SESSION *p, PPP_PACKET *pp)
|
|||||||
// Setting user timeouts
|
// Setting user timeouts
|
||||||
p->PacketRecvTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000 * 3 / 4; // setting to 3/4 of the user timeout
|
p->PacketRecvTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000 * 3 / 4; // setting to 3/4 of the user timeout
|
||||||
p->DataTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000;
|
p->DataTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000;
|
||||||
|
if (p->TubeRecv != NULL)
|
||||||
|
{
|
||||||
|
p->TubeRecv->DataTimeout = p->DataTimeout;
|
||||||
|
}
|
||||||
p->UserConnectionTimeout = (UINT64)p->Ipc->Policy->AutoDisconnect * 1000;
|
p->UserConnectionTimeout = (UINT64)p->Ipc->Policy->AutoDisconnect * 1000;
|
||||||
p->UserConnectionTick = Tick64();
|
p->UserConnectionTick = Tick64();
|
||||||
|
|
||||||
@ -3285,6 +3291,16 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
|
|||||||
p->Ipc = ipc;
|
p->Ipc = ipc;
|
||||||
PPPSetStatus(p, PPP_STATUS_AUTH_SUCCESS);
|
PPPSetStatus(p, PPP_STATUS_AUTH_SUCCESS);
|
||||||
|
|
||||||
|
// Setting user timeouts
|
||||||
|
p->PacketRecvTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000 * 3 / 4; // setting to 3/4 of the user timeout
|
||||||
|
p->DataTimeout = (UINT64)p->Ipc->Policy->TimeOut * 1000;
|
||||||
|
if (p->TubeRecv != NULL)
|
||||||
|
{
|
||||||
|
p->TubeRecv->DataTimeout = p->DataTimeout;
|
||||||
|
}
|
||||||
|
p->UserConnectionTimeout = (UINT64)p->Ipc->Policy->AutoDisconnect * 1000;
|
||||||
|
p->UserConnectionTick = Tick64();
|
||||||
|
|
||||||
// Just send an EAP-Success
|
// Just send an EAP-Success
|
||||||
pack = ZeroMalloc(sizeof(PPP_PACKET));
|
pack = ZeroMalloc(sizeof(PPP_PACKET));
|
||||||
pack->IsControl = true;
|
pack->IsControl = true;
|
||||||
|
@ -313,8 +313,6 @@ struct PPP_SESSION
|
|||||||
UINT64 DataTimeout;
|
UINT64 DataTimeout;
|
||||||
UINT64 UserConnectionTimeout;
|
UINT64 UserConnectionTimeout;
|
||||||
UINT64 UserConnectionTick;
|
UINT64 UserConnectionTick;
|
||||||
|
|
||||||
THREAD *SessionThread; // Thread of the PPP session
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -325,7 +323,7 @@ struct PPP_SESSION
|
|||||||
void PPPThread(THREAD *thread, void *param);
|
void PPPThread(THREAD *thread, void *param);
|
||||||
|
|
||||||
// Entry point
|
// Entry point
|
||||||
PPP_SESSION *NewPPPSession(CEDAR *cedar, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, TUBE *send_tube, TUBE *recv_tube, char *postfix, char *client_software_name, char *client_hostname, char *crypt_name, UINT adjust_mss);
|
THREAD *NewPPPSession(CEDAR *cedar, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, TUBE *send_tube, TUBE *recv_tube, char *postfix, char *client_software_name, char *client_hostname, char *crypt_name, UINT adjust_mss);
|
||||||
|
|
||||||
// PPP processing functions
|
// PPP processing functions
|
||||||
bool PPPRejectUnsupportedPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
bool PPPRejectUnsupportedPacket(PPP_SESSION *p, PPP_PACKET *pp);
|
||||||
|
@ -275,8 +275,6 @@ void SstpProcessControlPacket(SSTP_SERVER *s, SSTP_PACKET *p)
|
|||||||
// Process the SSTP received data packet
|
// Process the SSTP received data packet
|
||||||
void SstpProcessDataPacket(SSTP_SERVER *s, SSTP_PACKET *p)
|
void SstpProcessDataPacket(SSTP_SERVER *s, SSTP_PACKET *p)
|
||||||
{
|
{
|
||||||
PPP_SESSION *underlyingSession;
|
|
||||||
|
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (s == NULL || p == NULL || p->IsControl)
|
if (s == NULL || p == NULL || p->IsControl)
|
||||||
{
|
{
|
||||||
@ -288,11 +286,9 @@ void SstpProcessDataPacket(SSTP_SERVER *s, SSTP_PACKET *p)
|
|||||||
if (s->PPPThread == NULL)
|
if (s->PPPThread == NULL)
|
||||||
{
|
{
|
||||||
// Create a thread to initialize the new PPP module
|
// Create a thread to initialize the new PPP module
|
||||||
underlyingSession = NewPPPSession(s->Cedar, &s->ClientIp, s->ClientPort, &s->ServerIp, s->ServerPort,
|
s->PPPThread = NewPPPSession(s->Cedar, &s->ClientIp, s->ClientPort, &s->ServerIp, s->ServerPort,
|
||||||
s->TubeSend, s->TubeRecv, SSTP_IPC_POSTFIX, SSTP_IPC_CLIENT_NAME,
|
s->TubeSend, s->TubeRecv, SSTP_IPC_POSTFIX, SSTP_IPC_CLIENT_NAME,
|
||||||
s->ClientHostName, s->ClientCipherName, 0);
|
s->ClientHostName, s->ClientCipherName, 0);
|
||||||
s->PPPSession = underlyingSession;
|
|
||||||
s->PPPThread = underlyingSession->SessionThread;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass the received data to the PPP module
|
// Pass the received data to the PPP module
|
||||||
@ -444,9 +440,9 @@ void SstpProcessInterrupt(SSTP_SERVER *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->PPPSession != NULL && s->PPPSession->DataTimeout > sstpTimeout)
|
if (s->TubeRecv != NULL && s->TubeRecv->DataTimeout > sstpTimeout)
|
||||||
{
|
{
|
||||||
sstpTimeout = s->PPPSession->DataTimeout;
|
sstpTimeout = s->TubeRecv->DataTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((s->LastRecvTick + sstpTimeout) <= s->Now)
|
if ((s->LastRecvTick + sstpTimeout) <= s->Now)
|
||||||
|
@ -119,7 +119,6 @@ struct SSTP_SERVER
|
|||||||
UINT64 LastRecvTick; // Tick when some data has received at the end
|
UINT64 LastRecvTick; // Tick when some data has received at the end
|
||||||
bool FlushRecvTube; // Flag whether to flush the reception tube
|
bool FlushRecvTube; // Flag whether to flush the reception tube
|
||||||
UINT EstablishedCount; // Number of session establishment
|
UINT EstablishedCount; // Number of session establishment
|
||||||
PPP_SESSION *PPPSession; // Underlying PPP Session
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -16899,6 +16899,7 @@ TUBE *NewTube(UINT size_of_header)
|
|||||||
t->SockEvent = NewSockEvent();
|
t->SockEvent = NewSockEvent();
|
||||||
|
|
||||||
t->SizeOfHeader = size_of_header;
|
t->SizeOfHeader = size_of_header;
|
||||||
|
t->DataTimeout = 0;
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -412,6 +412,7 @@ struct TUBE
|
|||||||
bool IsInFlushList; // Whether it is registered in the Tube Flush List
|
bool IsInFlushList; // Whether it is registered in the Tube Flush List
|
||||||
void *Param1, *Param2, *Param3;
|
void *Param1, *Param2, *Param3;
|
||||||
UINT IntParam1, IntParam2, IntParam3;
|
UINT IntParam1, IntParam2, IntParam3;
|
||||||
|
UINT64 DataTimeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Data that is to send and to receive in the tube
|
// Data that is to send and to receive in the tube
|
||||||
|
Loading…
Reference in New Issue
Block a user