use stream to take apart untrusted message safely

add new stream getters that return false if reach EOS and use them to
exit early and safely if incoming SMS msg is misformatted. I'm getting
random garbage meant for other apps perhaps.
This commit is contained in:
Eric House 2018-07-13 22:41:52 -07:00
parent 019cc628e4
commit 352d87a327
3 changed files with 67 additions and 30 deletions

View file

@ -226,39 +226,53 @@ smsproto_prepInbound( SMSProto* state, const XP_UCHAR* fromPhone,
XP_LOGF( "%s(): len=%d, fromPhone=%s", __func__, len, fromPhone );
checkThread( state );
XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(state->mpool)
dutil_getVTManager(state->dutil) );
stream_putBytes( stream, data, len );
SMSMsgArray* result = NULL;
int offset = 0;
int proto = data[offset++];
XP_U8 proto;
if ( stream_gotU8( stream, &proto ) ) {
switch ( proto ) {
case SMS_PROTO_VERSION: {
int msgID = data[offset++];
int indx = data[offset++];
int count = data[offset++];
/* XP_LOGF( "%s(len=%d, fromPhone=%s)): proto=%d, id=%d, indx=%d of %d)", */
/* __func__, len, fromPhone, proto, msgID, indx, count ); */
addMessage( state, fromPhone, msgID, indx, count, data + offset, len - offset );
XP_U8 msgID, indx, count;
if ( stream_gotU8( stream, &msgID )
&& stream_gotU8( stream, &indx )
&& stream_gotU8( stream, &count )
&& indx < count ) {
XP_U16 len = stream_getSize( stream );
XP_U8 buf[len];
stream_getBytes( stream, buf, len );
addMessage( state, fromPhone, msgID, indx, count, buf, len );
result = completeMsgs( state, result, fromPhone, msgID );
savePartials( state );
}
}
break;
case SMS_PROTO_VERSION_COMBO:
while ( offset < len ) {
int oneLen = data[offset++];
int msgID = data[offset++];
case SMS_PROTO_VERSION_COMBO: {
XP_U8 oneLen, msgID;
while ( stream_gotU8( stream, &oneLen )
&& stream_gotU8( stream, &msgID ) ) {
XP_U8 buf[oneLen];
if ( stream_gotBytes( stream, buf, oneLen ) ) {
SMSMsg msg = { .len = oneLen,
.msgID = msgID,
.data = XP_MALLOC( state->mpool, oneLen ),
};
XP_MEMCPY( msg.data, &data[offset], oneLen );
offset += oneLen;
XP_MEMCPY( msg.data, buf, oneLen );
result = appendMsg( state, result, &msg );
}
}
}
break;
default:
XP_LOGF( "%s(): unexpected proto %d", __func__, proto );
break;
}
}
stream_destroy( stream );
XP_LOGF( "%s() => %p (len=%d)", __func__, result, (!!result) ? result->nMsgs : 0 );
return result;
}

View file

@ -179,6 +179,26 @@ stringToStream( XWStreamCtxt* stream, const XP_UCHAR* str )
stream_putBytes( stream, str, len );
} /* putStringToStream */
XP_Bool
stream_gotU8( XWStreamCtxt* stream, XP_U8* ptr )
{
XP_Bool success = sizeof(*ptr) <= stream_getSize( stream );
if ( success ) {
*ptr = stream_getU8( stream );
}
return success;
}
XP_Bool
stream_gotBytes( XWStreamCtxt* stream, void* ptr, XP_U16 len )
{
XP_Bool success = len <= stream_getSize( stream );
if ( success ) {
stream_getBytes( stream, ptr, len );
}
return success;
}
/*****************************************************************************
*
****************************************************************************/

View file

@ -56,6 +56,9 @@ XP_UCHAR* p_stringFromStream( MPFORMAL XWStreamCtxt* stream
XP_U16 stringFromStreamHere( XWStreamCtxt* stream, XP_UCHAR* buf, XP_U16 len );
void stringToStream( XWStreamCtxt* stream, const XP_UCHAR* str );
XP_Bool stream_gotU8( XWStreamCtxt* stream, XP_U8* ptr );
XP_Bool stream_gotBytes( XWStreamCtxt* stream, void* ptr, XP_U16 len );
XP_UCHAR* p_copyString( MPFORMAL const XP_UCHAR* instr
#ifdef MEM_DEBUG
, const char* file, const char* func, XP_U32 lineNo