2014-11-19 08:37 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* contrib/hbnetio/netiosrv.c
* small simplification
* src/rtl/hbznet.c
! fixed possible data stream corruption which could be exploited in
systems which can accept only one byte in socket write operation
when internal TCP output buffers are full. Rather seldom situation
but theoretically possible, i.e. in VPN.
This commit is contained in:
@@ -75,7 +75,7 @@ typedef struct _HB_ZNETSTREAM
|
||||
}
|
||||
HB_ZNETSTREAM;
|
||||
|
||||
#define HB_ZNET_BUFSIZE 16384
|
||||
#define HB_ZNET_BUFSIZE 0x4000
|
||||
|
||||
#if MAX_MEM_LEVEL >= 8
|
||||
# define HB_ZNET_MEM_LEVEL 8
|
||||
@@ -292,47 +292,41 @@ long hb_znetRead( PHB_ZNETSTREAM pStream, HB_SOCKET sd, void * buffer, long len,
|
||||
|
||||
static long hb_znetStreamWrite( PHB_ZNETSTREAM pStream, HB_SOCKET sd, HB_MAXINT timeout )
|
||||
{
|
||||
long tosnd = HB_ZNET_BUFSIZE - pStream->wr.avail_out;
|
||||
long snd = 0, rest = 0;
|
||||
long snd = 0, rest = 0, tosnd;
|
||||
|
||||
if( pStream->crypt )
|
||||
{
|
||||
long size = ( long ) ( pStream->wr.next_out - pStream->crypt_out );
|
||||
|
||||
if( size > 2 )
|
||||
rest = ( long ) ( pStream->wr.next_out - pStream->crypt_out );
|
||||
if( rest > 2 )
|
||||
{
|
||||
HB_U16 uiLen = ( HB_U16 ) ( size - 2 );
|
||||
HB_U16 uiLen = ( HB_U16 ) ( rest - 2 );
|
||||
HB_PUT_BE_UINT16( pStream->crypt_out, uiLen );
|
||||
uiLen = ( HB_U16 ) ( ( ( size + 7 ) ^ 0x07 ) & 0x07 );
|
||||
if( ( uInt ) uiLen > pStream->wr.avail_out )
|
||||
{
|
||||
/* it may happen only if encryption was enabled in non empty
|
||||
* buffer and the unencrypted part has not been flushed yet.
|
||||
*/
|
||||
rest = size;
|
||||
}
|
||||
else
|
||||
uiLen = ( HB_U16 ) ( ( ( rest + 0x07 ) ^ 0x07 ) & 0x07 );
|
||||
if( ( uInt ) uiLen <= pStream->wr.avail_out )
|
||||
{
|
||||
while( uiLen-- )
|
||||
{
|
||||
*pStream->wr.next_out++ = ( Byte ) 0; /* TODO: use better hashing data */
|
||||
pStream->wr.avail_out--;
|
||||
size++;
|
||||
rest++;
|
||||
}
|
||||
/* encrypt the buffer */
|
||||
for( tosnd = 0; tosnd < size; tosnd += 8 )
|
||||
for( tosnd = 0; tosnd < rest; tosnd += 8 )
|
||||
hb_znetEncrypt( pStream, pStream->crypt_out + tosnd );
|
||||
rest = 0;
|
||||
pStream->crypt_out = pStream->wr.next_out;
|
||||
pStream->wr.next_out += 2;
|
||||
if( pStream->wr.avail_out < 2 )
|
||||
pStream->skip_out = 2 - pStream->wr.avail_out;
|
||||
pStream->wr.avail_out -= 2 - pStream->skip_out;
|
||||
}
|
||||
tosnd = ( long ) ( pStream->crypt_out - pStream->outbuf );
|
||||
}
|
||||
else
|
||||
tosnd -= 2;
|
||||
rest = 0;
|
||||
tosnd = ( long ) ( pStream->crypt_out - pStream->outbuf );
|
||||
}
|
||||
else
|
||||
tosnd = HB_ZNET_BUFSIZE - pStream->wr.avail_out;
|
||||
|
||||
if( tosnd > 0 )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user