Skip to content

Commit

Permalink
Fix PVIO to return number of bytes read/written as "signed" integer
Browse files Browse the repository at this point in the history
since there is a lot of checks for return code being < 0 or -1.
  • Loading branch information
vaintroub committed Oct 13, 2016
1 parent 7cb8479 commit 629ec64
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 80 deletions.
2 changes: 1 addition & 1 deletion include/ma_global.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#endif

#include <ma_config.h>

#include <assert.h>
#ifndef __GNUC__
#define __attribute(A)
#endif
Expand Down
14 changes: 7 additions & 7 deletions include/ma_pvio.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ struct st_ma_pvio_methods
{
my_bool (*set_timeout)(MARIADB_PVIO *pvio, enum enum_pvio_timeout type, int timeout);
int (*get_timeout)(MARIADB_PVIO *pvio, enum enum_pvio_timeout type);
size_t (*read)(MARIADB_PVIO *pvio, uchar *buffer, size_t length);
size_t (*async_read)(MARIADB_PVIO *pvio, uchar *buffer, size_t length);
size_t (*write)(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
size_t (*async_write)(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
ssize_t (*read)(MARIADB_PVIO *pvio, uchar *buffer, size_t length);
ssize_t (*async_read)(MARIADB_PVIO *pvio, uchar *buffer, size_t length);
ssize_t (*write)(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
ssize_t (*async_write)(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
int (*wait_io_or_timeout)(MARIADB_PVIO *pvio, my_bool is_read, int timeout);
my_bool (*blocking)(MARIADB_PVIO *pvio, my_bool value, my_bool *old_value);
my_bool (*connect)(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo);
Expand All @@ -113,9 +113,9 @@ struct st_ma_pvio_methods
/* Function prototypes */
MARIADB_PVIO *ma_pvio_init(MA_PVIO_CINFO *cinfo);
void ma_pvio_close(MARIADB_PVIO *pvio);
size_t ma_pvio_cache_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length);
size_t ma_pvio_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length);
size_t ma_pvio_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
ssize_t ma_pvio_cache_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length);
ssize_t ma_pvio_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length);
ssize_t ma_pvio_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length);
int ma_pvio_get_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type);
my_bool ma_pvio_set_timeout(MARIADB_PVIO *pvio, enum enum_pvio_timeout type, int timeout);
int ma_pvio_fast_send(MARIADB_PVIO *pvio);
Expand Down
8 changes: 4 additions & 4 deletions include/ma_tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls);
0-n bytes read
-1 if an error occured
*/
size_t ma_tls_read(MARIADB_TLS *ctls, const uchar* buffer, size_t length);
ssize_t ma_tls_read(MARIADB_TLS *ctls, const uchar* buffer, size_t length);

/* ma_tls_write
write buffer to socket
Expand All @@ -85,7 +85,7 @@ size_t ma_tls_read(MARIADB_TLS *ctls, const uchar* buffer, size_t length);
0-n bytes written
-1 if an error occured
*/
size_t ma_tls_write(MARIADB_TLS *ctls, const uchar* buffer, size_t length);
ssize_t ma_tls_write(MARIADB_TLS *ctls, const uchar* buffer, size_t length);

/* ma_tls_close
closes SSL connection and frees SSL structure which was previously
Expand Down Expand Up @@ -143,8 +143,8 @@ my_bool ma_tls_get_protocol_version(MARIADB_TLS *ctls, struct st_ssl_version *ve
/* Function prototypes */
MARIADB_TLS *ma_pvio_tls_init(MYSQL *mysql);
my_bool ma_pvio_tls_connect(MARIADB_TLS *ctls);
size_t ma_pvio_tls_read(MARIADB_TLS *ctls, const uchar *buffer, size_t length);
size_t ma_pvio_tls_write(MARIADB_TLS *ctls, const uchar *buffer, size_t length);
ssize_t ma_pvio_tls_read(MARIADB_TLS *ctls, const uchar *buffer, size_t length);
ssize_t ma_pvio_tls_write(MARIADB_TLS *ctls, const uchar *buffer, size_t length);
my_bool ma_pvio_tls_close(MARIADB_TLS *ctls);
int ma_pvio_tls_verify_server_cert(MARIADB_TLS *ctls);
const char *ma_pvio_tls_cipher(MARIADB_TLS *ctls);
Expand Down
8 changes: 4 additions & 4 deletions libmariadb/ma_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ int net_add_multi_command(NET *net, uchar command, const uchar *packet,
int
ma_net_real_write(NET *net,const char *packet,size_t len)
{
size_t length;
ssize_t length;
char *pos,*end;

if (net->error == 2)
Expand Down Expand Up @@ -399,7 +399,7 @@ ma_net_real_write(NET *net,const char *packet,size_t len)
pos=(char*) packet; end=pos+len;
while (pos != end)
{
if ((ssize_t) (length=ma_pvio_write(net->pvio,(uchar *)pos,(size_t) (end-pos))) <= 0)
if ((length=ma_pvio_write(net->pvio,(uchar *)pos,(size_t) (end-pos))) <= 0)
{
net->error=2; /* Close socket */
net->last_errno= ER_NET_ERROR_ON_WRITE;
Expand All @@ -423,7 +423,7 @@ static ulong
ma_real_read(NET *net, size_t *complen)
{
uchar *pos;
size_t length;
ssize_t length;
uint i;
ulong len=packet_error;
size_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
Expand All @@ -438,7 +438,7 @@ ma_real_read(NET *net, size_t *complen)
while (remain > 0)
{
/* First read is done with non blocking mode */
if ((ssize_t) (length=ma_pvio_cache_read(net->pvio, pos,remain)) <= 0L)
if ((length=ma_pvio_cache_read(net->pvio, pos,remain)) <= 0L)
{
len= packet_error;
net->error=2; /* Close socket */
Expand Down
22 changes: 12 additions & 10 deletions libmariadb/ma_pvio.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,9 @@ static size_t ma_pvio_read_async(MARIADB_PVIO *pvio, uchar *buffer, size_t lengt
/* }}} */

/* {{{ size_t ma_pvio_read */
size_t ma_pvio_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length)
ssize_t ma_pvio_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length)
{
size_t r= -1;
ssize_t r= -1;
if (!pvio)
return -1;
if (IS_PVIO_ASYNC_ACTIVE(pvio))
Expand Down Expand Up @@ -266,9 +266,9 @@ size_t ma_pvio_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length)
/* }}} */

/* {{{ size_t ma_pvio_cache_read */
size_t ma_pvio_cache_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length)
ssize_t ma_pvio_cache_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length)
{
size_t r;
ssize_t r;

if (!pvio)
return -1;
Expand All @@ -278,7 +278,9 @@ size_t ma_pvio_cache_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length)

if (pvio->cache + pvio->cache_size > pvio->cache_pos)
{
r= MIN(length, (size_t)(pvio->cache + pvio->cache_size - pvio->cache_pos));
ssize_t remaining = pvio->cache + pvio->cache_size - pvio->cache_pos;
assert(remaining > 0);
r= MIN((ssize_t)length, remaining);
memcpy(buffer, pvio->cache_pos, r);
pvio->cache_pos+= r;
}
Expand All @@ -289,9 +291,9 @@ size_t ma_pvio_cache_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length)
else
{
r= ma_pvio_read(pvio, pvio->cache, PVIO_READ_AHEAD_CACHE_SIZE);
if ((ssize_t)r > 0)
if (r > 0)
{
if (length < r)
if (length < (size_t)r)
{
pvio->cache_size= r;
pvio->cache_pos= pvio->cache + length;
Expand All @@ -305,7 +307,7 @@ size_t ma_pvio_cache_read(MARIADB_PVIO *pvio, uchar *buffer, size_t length)
/* }}} */

/* {{{ size_t ma_pvio_write_async */
static size_t ma_pvio_write_async(MARIADB_PVIO *pvio, const uchar *buffer, size_t length)
static ssize_t ma_pvio_write_async(MARIADB_PVIO *pvio, const uchar *buffer, size_t length)
{
ssize_t res;
struct mysql_async_context *b= pvio->mysql->options.extension->async_context;
Expand Down Expand Up @@ -334,9 +336,9 @@ static size_t ma_pvio_write_async(MARIADB_PVIO *pvio, const uchar *buffer, size_
/* }}} */

/* {{{ size_t ma_pvio_write */
size_t ma_pvio_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length)
ssize_t ma_pvio_write(MARIADB_PVIO *pvio, const uchar *buffer, size_t length)
{
size_t r;
ssize_t r;

if (!pvio)
return -1;
Expand Down
4 changes: 2 additions & 2 deletions libmariadb/ma_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,12 @@ my_bool ma_pvio_tls_connect(MARIADB_TLS *ctls)
return rc;
}

size_t ma_pvio_tls_read(MARIADB_TLS *ctls, const uchar* buffer, size_t length)
ssize_t ma_pvio_tls_read(MARIADB_TLS *ctls, const uchar* buffer, size_t length)
{
return ma_tls_read(ctls, buffer, length);
}

size_t ma_pvio_tls_write(MARIADB_TLS *ctls, const uchar* buffer, size_t length)
ssize_t ma_pvio_tls_write(MARIADB_TLS *ctls, const uchar* buffer, size_t length)
{
return ma_tls_write(ctls, buffer, length);
}
Expand Down
37 changes: 20 additions & 17 deletions libmariadb/secure/ma_schannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,12 +445,13 @@ SECURITY_STATUS ma_schannel_handshake_loop(MARIADB_PVIO *pvio, my_bool InitialRe
{
if(fDoRead)
{
cbData = (DWORD)pvio->methods->read(pvio, IoBuffer + cbIoBuffer, (size_t)(SC_IO_BUFFER_SIZE - cbIoBuffer));
if (cbData == SOCKET_ERROR || cbData == 0)
ssize_t nbytes = pvio->methods->read(pvio, IoBuffer + cbIoBuffer, (size_t)(SC_IO_BUFFER_SIZE - cbIoBuffer));
if (nbytes <= 0)
{
rc = SEC_E_INTERNAL_ERROR;
break;
}
cbData = (DWORD)nbytes;
cbIoBuffer += cbData;
}
else
Expand Down Expand Up @@ -504,14 +505,14 @@ SECURITY_STATUS ma_schannel_handshake_loop(MARIADB_PVIO *pvio, my_bool InitialRe
{
if(OutBuffers.cbBuffer && OutBuffers.pvBuffer)
{
cbData= (DWORD)pvio->methods->write(pvio, (uchar *)OutBuffers.pvBuffer, (size_t)OutBuffers.cbBuffer);
if(cbData == SOCKET_ERROR || cbData == 0)
ssize_t nbytes = pvio->methods->write(pvio, (uchar *)OutBuffers.pvBuffer, (size_t)OutBuffers.cbBuffer);
if(nbytes <= 0)
{
FreeContextBuffer(OutBuffers.pvBuffer);
DeleteSecurityContext(&sctx->ctxt);
return SEC_E_INTERNAL_ERROR;
}

cbData= (DWORD)nbytes;
/* Free output context buffer */
FreeContextBuffer(OutBuffers.pvBuffer);
OutBuffers.pvBuffer = NULL;
Expand Down Expand Up @@ -648,12 +649,13 @@ SECURITY_STATUS ma_schannel_client_handshake(MARIADB_TLS *ctls)
/* send client hello packaet */
if(BuffersOut.cbBuffer != 0 && BuffersOut.pvBuffer != NULL)
{
r= (DWORD)pvio->methods->write(pvio, (uchar *)BuffersOut.pvBuffer, (size_t)BuffersOut.cbBuffer);
if (r <= 0)
ssize_t nbytes = (DWORD)pvio->methods->write(pvio, (uchar *)BuffersOut.pvBuffer, (size_t)BuffersOut.cbBuffer);
if (nbytes <= 0)
{
sRet= SEC_E_INTERNAL_ERROR;
goto end;
}
r = (DWORD)nbytes;
}
sRet= ma_schannel_handshake_loop(pvio, TRUE, &ExtraData);

Expand Down Expand Up @@ -708,7 +710,7 @@ SECURITY_STATUS ma_schannel_read_decrypt(MARIADB_PVIO *pvio,
uchar *ReadBuffer,
DWORD ReadBufferSize)
{
DWORD dwBytesRead= 0;
ssize_t nbytes= 0;
DWORD dwOffset= 0;
SC_CTX *sctx;
SECURITY_STATUS sRet= 0;
Expand All @@ -725,22 +727,22 @@ SECURITY_STATUS ma_schannel_read_decrypt(MARIADB_PVIO *pvio,

while (1)
{
if (!dwBytesRead || sRet == SEC_E_INCOMPLETE_MESSAGE)
if (nbytes > 0 || sRet == SEC_E_INCOMPLETE_MESSAGE)
{
dwBytesRead= (DWORD)pvio->methods->read(pvio, sctx->IoBuffer + dwOffset, (size_t)(sctx->IoBufferSize - dwOffset));
if (dwBytesRead == 0)
nbytes= pvio->methods->read(pvio, sctx->IoBuffer + dwOffset, (size_t)(sctx->IoBufferSize - dwOffset));
if (nbytes == 0)
{
/* server closed connection */
// todo: error
return SEC_E_INVALID_HANDLE;
}
if (dwBytesRead < 0)
if (nbytes < 0)
{
/* socket error */
// todo: error
return SEC_E_INVALID_HANDLE;
}
dwOffset+= dwBytesRead;
dwOffset+= (DWORD)nbytes;
}
ZeroMemory(Buffers, sizeof(SecBuffer) * 4);
Buffers[0].pvBuffer= sctx->IoBuffer;
Expand Down Expand Up @@ -779,6 +781,7 @@ SECURITY_STATUS ma_schannel_read_decrypt(MARIADB_PVIO *pvio,

if (pData && pData->cbBuffer)
{
assert(*DecryptLength + pData->cbBuffer <= ReadBufferSize);
memcpy(ReadBuffer + *DecryptLength, pData->pvBuffer, pData->cbBuffer);
*DecryptLength+= pData->cbBuffer;
return sRet;
Expand Down Expand Up @@ -893,7 +896,7 @@ my_bool ma_schannel_verify_certs(SC_CTX *sctx)
SEC_E_OK on success
SEC_E_* if an error occured
*/
size_t ma_schannel_write_encrypt(MARIADB_PVIO *pvio,
ssize_t ma_schannel_write_encrypt(MARIADB_PVIO *pvio,
uchar *WriteBuffer,
size_t WriteBufferSize)
{
Expand All @@ -904,6 +907,7 @@ size_t ma_schannel_write_encrypt(MARIADB_PVIO *pvio,
PBYTE pbMessage;
SC_CTX *sctx= (SC_CTX *)pvio->ctls->ssl;
size_t payload;
ssize_t nbytes;

payload= MIN(WriteBufferSize, sctx->IoBufferSize);

Expand Down Expand Up @@ -934,9 +938,8 @@ size_t ma_schannel_write_encrypt(MARIADB_PVIO *pvio,
if ((scRet = EncryptMessage(&sctx->ctxt, 0, &Message, 0))!= SEC_E_OK)
return -1;

if (pvio->methods->write(pvio, sctx->IoBuffer, Buffers[0].cbBuffer + Buffers[1].cbBuffer + Buffers[2].cbBuffer))
return payload;
return 0;
nbytes = pvio->methods->write(pvio, sctx->IoBuffer, Buffers[0].cbBuffer + Buffers[1].cbBuffer + Buffers[2].cbBuffer);
return nbytes;
}
/* }}} */

Expand Down
2 changes: 1 addition & 1 deletion libmariadb/secure/ma_schannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ SECURITY_STATUS ma_schannel_handshake_loop(MARIADB_PVIO *pvio, my_bool InitialRe
my_bool ma_schannel_load_private_key(MARIADB_PVIO *pvio, CERT_CONTEXT *ctx, char *key_file);
PCCRL_CONTEXT ma_schannel_create_crl_context(MARIADB_PVIO *pvio, const char *pem_file);
my_bool ma_schannel_verify_certs(SC_CTX *sctx);
size_t ma_schannel_write_encrypt(MARIADB_PVIO *pvio,
ssize_t ma_schannel_write_encrypt(MARIADB_PVIO *pvio,
uchar *WriteBuffer,
size_t WriteBufferSize);
SECURITY_STATUS ma_schannel_read_decrypt(MARIADB_PVIO *pvio,
Expand Down
17 changes: 8 additions & 9 deletions libmariadb/secure/schannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,24 +301,23 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
return 1;
}

size_t ma_tls_read(MARIADB_TLS *ctls, const uchar* buffer, size_t length)
ssize_t ma_tls_read(MARIADB_TLS *ctls, const uchar* buffer, size_t length)
{
SC_CTX *sctx= (SC_CTX *)ctls->ssl;
MARIADB_PVIO *pvio= sctx->mysql->net.pvio;
DWORD dlength= -1;

ma_schannel_read_decrypt(pvio, &sctx->CredHdl, &sctx->ctxt, &dlength, (uchar *)buffer, (DWORD)length);
return dlength;
DWORD dlength= 0;
SECURITY_STATUS status = ma_schannel_read_decrypt(pvio, &sctx->CredHdl, &sctx->ctxt, &dlength, (uchar *)buffer, (DWORD)length);
return (status == SEC_E_OK)? (ssize_t)dlength : -1;
}

size_t ma_tls_write(MARIADB_TLS *ctls, const uchar* buffer, size_t length)
ssize_t ma_tls_write(MARIADB_TLS *ctls, const uchar* buffer, size_t length)
{
SC_CTX *sctx= (SC_CTX *)ctls->ssl;
MARIADB_PVIO *pvio= sctx->mysql->net.pvio;
size_t rc, wlength= 0;
size_t remain= length;
ssize_t rc, wlength= 0;
ssize_t remain= length;

while (remain)
while (remain > 0)
{
if ((rc= ma_schannel_write_encrypt(pvio, (uchar *)buffer + wlength, remain)) <= 0)
return rc;
Expand Down

0 comments on commit 629ec64

Please sign in to comment.