
FreeRDP áááş Microsoft ááž áĄááąá¸ááááşá¸áá˝ááşááťá°ááŹááááşá¸ááťáŻááşáážáŻáĄáá˝ááş ááŽáá˝ááşááŹá¸ááąáŹ protocol áá
áşááŻááźá
áşáááˇáş Remote Desktop Protocol (RDP) á open-source áĄááąáŹááşáĄáááşááąáŹáşáážáŻáá
áşááŻááźá
áşáááşá á¤áááąáŹááťááşáááş áĄááŤáĄáááş ááááşááąáŹááşá¸ááťáŹá¸á
á˝áŹááᯠááśáˇáááŻá¸ááąá¸áááşá Windows, Linux, macOS iOS áá˛áˇááąáŹááş Androidá¤áááąáŹááťááşááᯠPVS-Studio static analyzer ááᯠáĄááŻáśá¸ááźáŻá RDP client ááťáŹá¸ááᯠá
ááşá¸áááşáááş áááşá
á°á¸ááŹá¸ááąáŹ ááąáŹááşá¸ááŤá¸á
áŽá¸ááŽá¸áá˛ááž áááááŻáśá¸áĄááźá
áş áá˝áąá¸ááťááşáá˛áˇáááşá
áĄáááşá¸áááşááąáŹááááŻááşá¸
á áŽááśááááşá¸á Microsoft áááş áááşá¸ááá áşáŚá¸áááşá¸áááŻááş RDP ááááŻáááŻááąáŹáĄáá˝ááş áááşáážááşááťááşááťáŹá¸ááᯠáá˝ááˇáşááťááźáŽá¸ááąáŹááş áá˝ááşááąáŤáşááŹááźááşá¸ááźá áşáááşá áááŻáĄááťáááşáá˝ááşá Reverse Engineering áááááşááťáŹá¸áĄááąáŤáşáĄááźáąááśáááˇáşáĄááąáŹááşáĄáááşááąáŹáşáážáŻ rdesktop client áá áşááŻáážááááşá
ááááŻáááŻááąáŹááᯠáĄááąáŹááşáĄáááş ááąáŹáşááŹáááşáážááˇáşáĄááťážá ááááşáážáááźáŽá¸ááŹá¸ áááąáŹááťááşááááŻááŹáááşááŹááźáąáŹááˇáş ááŻááşááąáŹááşááťááşáĄáá áşááťáŹá¸ááᯠáááˇáşáá˝ááşá¸áááş áááŻáááŻáááşáá˛ááŹáááşá áááşá¸áá˝ááşááźáąáŹááşá¸áá˛áážáŻááťáŹá¸áááş rdesktop - FreeRDP ááááşá¸ááŻáśáá áşááŻáááşááŽá¸áážáŻáááŻááźá áşááąáŤáşá áąáááˇáş developer ááťáŹá¸áĄááźáŹá¸áááááášááá áşááŻááźá áşááąáŤáşá áąáá˛áˇáááşá Apache License v2 áááŻáˇ áááŻááşá ááşááŻááşááąá¸áááş ááŻáśá¸ááźááşááťááşááťáá˛áˇááąáŹ ááááşáĄááąááźááˇáş GPLv2 áááŻááşá ááşááźááˇáş ááŻááşááŻááşáááąáŹááşáááşááźááˇáşááźá°á¸áážáŻááᯠáááˇáşáááşááŹá¸áááşá áááŻáˇááąáŹáşá áá°áááŻááşá¸áááş áááşá¸áááŻáˇáááŻááşáááŻááşá ááşááᯠááźáąáŹááşá¸áá˛áááş áááąáŹáá°ááźáááşáááŻááşááąáŹááźáąáŹááˇáş developer ááťáŹá¸áááş áááąáŹááťááşááᯠááźááşáááşááąá¸ááŹá¸áááş ááŻáśá¸ááźááşáá˛áˇááźáŽá¸ ááąááşááŽááŻááşááąáˇá áşáá áşáᯠááźá áşááŹáá˛áˇáááşá
áááŹá¸áááşáááąáŹáˇááşáááŻáˇá áşáá˝ááş áááąáŹááťááşáááááŻááşá¸ááźáąáŹááşá¸ááᯠ"FreeRDP áááąáŹááťááşááááŻááşá¸" áá˝ááş áááşáááŻáááŻáááşáážáŻáááŻááşááŤáááşá
ááŻááşáážá áĄáážáŹá¸áĄáá˝ááşá¸ááťáŹá¸áážááˇáş ááźá áşáááŻááşááźáąáážáááąáŹ áĄáŹá¸áááşá¸ááťááşááťáŹá¸ááᯠáážáŹáá˝áąááąáŹáşááŻááşáááş ááááááŹáá áşááŻáĄááźá áş áĄááŻáśá¸ááźáŻáááşá áááşá¸áááş Cá C++á C# áážááˇáş Java ááááşááąáŹááşá¸ááťáŹá¸ááąáŤáşáá˝ááş ááážááááŻááşááąáŹ static code analyzer áá áşááŻááźá áşáááşá Windows, Linux и macOS.
ááąáŹááşá¸ááŤá¸áááş ááťá˝ááşáŻááşáĄáá˝ááş á áááşáááşá áŹá¸ááŻáśá¸áᯠáááşááááˇáş áĄáážáŹá¸ááťáŹá¸áááŻáᏠáááşááźááŤáááşá
Memory áááŻá áááˇáşááźááşá¸á
'cwd' áá˝ážááşááźááťááşááᯠáááŻááşáᲠááŻááşááąáŹááşááťááşáááş áá˝ááşáá˛áˇáááşá Memory áááŻá áááˇáşáážáŻááźá áşáááŻááşáááşá environment.c áá
DWORD GetCurrentDirectoryA(DWORD nBufferLength, LPSTR lpBuffer)
{
char* cwd;
....
cwd = getcwd(NULL, 0);
....
if (lpBuffer == NULL)
{
free(cwd);
return 0;
}
if ((length + 1) > nBufferLength)
{
free(cwd);
return (DWORD) (length + 1);
}
memcpy(lpBuffer, cwd, length + 1);
return length;
....
}á¤áĄáááŻááşá¸áĄá ááᯠwinpr subsystem ááž ááá°ááŹá¸ááźáŽá¸á áááşá¸áááş non- áĄáá˝ááş WINAPI wrapper ááᯠáĄááąáŹááşáĄáááşááąáŹáşáááşáWindows á áá áşááťáŹá¸á áááŻáááŻáááşáážáŹ áááşá¸áááş Wine á ááąáŤáˇááŤá¸ááąáŹ analogue áá áşááŻááźá áşáááşá á¤ááąááŹáá˝ááş leak áá áşááŻááᯠáááşáá˝áąáˇááźááşáááŻááşáááş- function ááž áá˝á˛ááąááŹá¸ááąáŹ memory getcwdáĄáá°á¸ááá ášá áááşááťáŹá¸ááᯠáááŻááşáá˝ááşáááˇáşáĄááŤáážáᏠááŻááşááźááşáááşá áĄáážáŹá¸áááŻááźááşáááş ááąáŤáşáááŻáážáŻáá áşááŻáááˇáşáááş áááŻáĄááşáááşá áĄááá˛áˇ пОŃНо áážááşáá.
áĄáááşá¸áĄááťááşá¸ááᯠá ááşá¸áááŹá¸ááŤá
Array overrun ááźá áşáááŻááşáááşá 'event->EventHandlerCount' áĄáá˝ážááşá¸ááááşá¸ááááşáááŻá¸áááş 32 áááŻáˇááąáŹááşáážááááŻááşáááşá PubSub.c 117
#define MAX_EVENT_HANDLERS 32
struct _wEventType
{
....
int EventHandlerCount;
pEventHandler EventHandlers[MAX_EVENT_HANDLERS];
};
int PubSub_Subscribe(wPubSub* pubSub, const char* EventName,
pEventHandler EventHandler)
{
....
if (event->EventHandlerCount <= MAX_EVENT_HANDLERS)
{
event->EventHandlers[event->EventHandlerCount] = EventHandler;
event->EventHandlerCount++;
}
....
}á¤áĽáááŹáááş ááźááşá ááşáĄááąáĄáá˝ááş áĄááťáŹá¸ááŻáśá¸áááŻáˇááąáŹááşáážááá˝áŹá¸ááťážááşáááş á áŹáááşá¸áá˛áááŻáˇ áĄá áááşáĄáááŻááşá¸áĄáá áşáá áşááŻááᯠááąáŤááşá¸áááˇáşáááşá á¤ááąááŹáá˝ááş áĄáąáŹáşáááąáᏠáĄá áŹá¸áááŻá¸áááş ááŻáśááąáŹááşááŤáááşá <= áĄááąáŤáş <áááşá¸ááťááşá¸ááŹá¸ááąáŹ áááşááááááşááťáŹá¸ááᯠááťáąáŹáşáá˝ááşááá˝áŹá¸á áąáááşá
á¤áĄááťááŻá¸áĄá áŹá¸á ááąáŹááşáááşáĄáážáŹá¸áá áşáᯠáá˝áąáˇáážááá˛áˇáááş-
- V557 Array áááş overrun ááźá áşáááŻááşáááşá 'iBitmapFormat' áĄáá˝ážááşá¸ááááşá¸ááááşáááŻá¸áááş 8. orders.c 2623 áááŻáˇááąáŹááşáážááááŻááşáááşá
á áŹááŻáśá¸ááąáŤááşá¸
áá áşáááŻááşá¸áá áşá á
á ááŹá¸áááş '!pipe->In' áááş áĄááźá˛áááşá¸ áá˝á˛áážáŹá¸ááąááŤáááşá MessagePipe.c áá
wMessagePipe* MessagePipe_New()
{
....
pipe->In = MessageQueue_New(NULL);
if (!pipe->In)
goto error_in;
pipe->Out = MessageQueue_New(NULL);
if (!pipe->In) // <=
goto error_out;
....
}á¤ááąááŹáá˝ááş ááŻáśá áŹá áŽá áŹááŻáśá¸áá áşááŻááᯠááťá˝ááşáŻááşáááŻáˇáá˝áąáˇááááş- ááŻááááĄááźáąáĄááąáááş ááááážááˇáşáá°ááŽááąáŹááááşá¸áážááşááᯠá á áşááąá¸áááşá ááźá áşáááŻááşáááşáážáŹá ááŻááşáá°á¸áá°ááźááşá¸ ááĄáąáŹááşááźááşááźááşá¸ááźáąáŹááˇáş áĄáážáŹá¸áĄáá˝ááşá¸ ááąáŤáşááŹáááşá
áá áşáááŻááşá¸áá áşá á
áá°ááŽááąáŹ á áŹááŹá¸ááŻáśá¸ áážá áşáá˝ááşááᯠáá˝áąáˇáážááá˛áˇáááşá ááŻááááááąáŹááşáááş á áŹááźáąáŹááşá¸ 771. tsg.c 770 ááž á áááşáááşá
typedef struct _TSG_PACKET_VERSIONCAPS
{
....
UINT16 majorVersion;
UINT16 minorVersion;
....
} TSG_PACKET_VERSIONCAPS, *PTSG_PACKET_VERSIONCAPS;
static BOOL TsProxyCreateTunnelReadResponse(....)
{
....
PTSG_PACKET_VERSIONCAPS versionCaps = NULL;
....
/* MajorVersion (2 bytes) */
Stream_Read_UINT16(pdu->s, versionCaps->majorVersion);
/* MinorVersion (2 bytes) */
Stream_Read_UINT16(pdu->s, versionCaps->majorVersion);
....
}ááąáŹááşáááşáĄáážáŹá¸áá áşááŻ- ááŻááşáážááşááťááşáááş á áŹáá˝á˛ááŤááŹáááˇáşáááşáᯠáááŻáááŻáááşá minorVersionáááŻáˇááąáŹáşá á áŹáááşááźááşá¸áááş áĄáááşááąá¸ááŹá¸ááąáŹ ááááşá¸áážááşáá áşááŻáĄááźá áş ááźá áşááąáŤáşáááşá majorVersion. áááŻáˇááąáŹáşá ááťá˝ááşáŻááşáááş ááááŻáááŻááąáŹáážááˇáş ááááşá¸áážáŽá¸ááŤá áááŻáˇááźáąáŹááˇáş ááŤá áááˇáşáážááşá¸ááťááşááťážáᏠááźá áşáááşá
áá áşáááŻááşá¸áá áşá á
'trio_index_last' ááŻááşááąáŹááşááťááşá áááŻááşáááşáááş 'trio_index' ááŻááşááąáŹááşááťááşáááŻááşáááşáážááˇáş áĄááźááˇáşáĄá ááŽááťážáááşáážáŹ áá°á¸áááşá¸ááŤáááşá triostr.c ááá
/**
Find first occurrence of a character in a string.
....
*/
TRIO_PUBLIC_STRING char *
trio_index
TRIO_ARGS2((string, character),
TRIO_CONST char *string,
int character)
{
assert(string);
return strchr(string, character);
}
/**
Find last occurrence of a character in a string.
....
*/
TRIO_PUBLIC_STRING char *
trio_index_last
TRIO_ARGS2((string, character),
TRIO_CONST char *string,
int character)
{
assert(string);
return strchr(string, character);
}ááŻááşááąáŹááşááťááşá áážááşááťááşááźááˇáş ááŻáśá¸áááşáááşá trio_index string áá áşááŻáá˝ááş áááááŻáśá¸ ááŹááşááąáŹááşááᯠáážáŹáá˝áąáˇáááˇáşáĄááŤá trio_index_ááąáŹááşááŻáśá¸ - ááąáŹááşááŻáśá¸áĄááťááşá ááŤááąáááˇáş ááŽááŻááşááąáŹááşááťááşáá˝áąáá˛áˇ áĄá áááşáĄáááŻááşá¸áá˝áąá áĄáá°áá°ááŤáá˛á áĄááťáŹá¸á áŻáážáŹ áááşá¸áááş typo áá áşááŻááźá áşááźáŽá¸ function áá˝ááş ááźá áşáááŻááşáááşá trio_index_ááąáŹááşááŻáśá¸ áĄááŻáśá¸ááźáŻáááş áááŻáĄááşáááşá strhrhr áĄá áŹá¸ Strchr. áĄá˛ááŽáĄááŤáážáŹ áĄááźáŻáĄáá°áá˝áą áážáááŹáááşá
áá áşáááŻááşá¸áá áşá á
á ááŹá¸áááşáážá 'ááąááŹ' áá˝ážááşááźááťááşáááş nullptr áážááˇáş ááŽááťážáááşá á¤áá˝ážááşááźááťááşááąáŤáşáážá ááááşá¸áááşášááťáŹááŻááşááąáŹááşááťááşááťáŹá¸á ááááşáááşáááŻá¸áááş áĄáááášááŤááşáá˛áˇááźáŽá¸ áááşá¸ááᯠáĄááŻáśá¸áááźáŻáááˇáşááŤá nsc_encode.c ááá
static BOOL nsc_encode_argb_to_aycocg(NSC_CONTEXT* context,
const BYTE* data,
UINT32 scanline)
{
....
if (!context || data || (scanline == 0))
return FALSE;
....
src = data + (context->height - 1 - y) * scanline;
....
}áá˝á˛áá˝ááşááąá¸áĄáąáŹáşáááąááŹáááş á¤ááąááŹáá˝ááş áááąáŹáşáá áá˝á˛áá˝áŹá¸ááŻáśááááşá ! áĄááŽá¸ ááąááŹ. ááŤááᯠááááááźáŻáááá˝áŹá¸áᏠáá°á¸áááşá¸áááşá
áá áşáááŻááşá¸áá áşá á
'if (A) {âŚ} else if (A) {âŚ}' ááŻáśá áśááᯠáá˝áąáˇáážááá˛áˇáááşá ááŻáášáááĄáážáŹá¸áážáááąááźááşá¸ ááźá áşáááŻááşááźáąáážáááŤáááşá áááŻááşá¸ááťáŹá¸ááᯠá á áşááąá¸ááŤ- 213, 222. rdpei_common.c 213
BOOL rdpei_write_4byte_unsigned(wStream* s, UINT32 value)
{
BYTE byte;
if (value <= 0x3F)
{
....
}
else if (value <= 0x3FFF)
{
....
}
else if (value <= 0x3FFFFF)
{
byte = (value >> 16) & 0x3F;
Stream_Write_UINT8(s, byte | 0x80);
byte = (value >> 8) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
else if (value <= 0x3FFFFF)
{
byte = (value >> 24) & 0x3F;
Stream_Write_UINT8(s, byte | 0xC0);
byte = (value >> 16) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value >> 8) & 0xFF;
Stream_Write_UINT8(s, byte);
byte = (value & 0xFF);
Stream_Write_UINT8(s, byte);
}
....
}ááąáŹááşááŻáśá¸áĄááźáąáĄááąáážá áşááŻáááş áá°ááŽáááş- áá áşá áŻáśáá áşáŚá¸áááş áá°á¸áá°ááźáŽá¸ááąáŹááş áááşá¸áááŻáˇáĄáŹá¸ á á áşááąá¸áááşááąáˇáá˝áŹá¸ááŻáśááááşá ááąáŹááşááŻáśá¸áĄáááŻááşá¸áááş ááąá¸áááŻááşáááşáááŻá¸ááťáŹá¸ááźááˇáş áĄááŻááşááŻááşááźáąáŹááşá¸ ááŻááşááž ááááŹáááşáážáŹá¸á á˝áŹ ááááŹááąáŹááźáąáŹááˇáş ááąáŹááşááŻáśá¸áĄááźáąáĄááąááźá áşáááˇáşáááşáᯠááťá˝ááşáŻááşáááŻáˇ áá°ááááŻááşááŤáááşá áááşáááŻá¸ <= 0x3FFFFFFFF.
á¤áĄááťááŻá¸áĄá áŹá¸á ááąáŹááşáááşáĄáážáŹá¸áá áşáᯠáá˝áąáˇáážááá˛áˇáááş-
- V517 'if (A) {âŚ} else if (A) {âŚ}' ááŻáśá áśááᯠáá˝áąáˇáážááá˛áˇáááşá ááŻáášáááĄáážáŹá¸áážáááąááźááşá¸ ááźá áşáááŻááşááźáąáážáááŤáááşá áááŻááşá¸ááťáŹá¸ááᯠá á áşááąá¸ááŤ- 169, 173. file.c 169
áááˇáşáá˝ááşá¸ááąááŹááᯠáĄáááşááźáŻááźááşá¸á
áá áşáááŻááşá¸áá áşá á
ááąáŹáşááźááťááş 'strcat(áá áşáážááşá áĄáááşá¸áĄááźá áş) != NULL' áááş áĄááźá˛áážááşáááşá triostr.c ááá
TRIO_PUBLIC_STRING int
trio_append
TRIO_ARGS2((target, source),
char *target,
TRIO_CONST char *source)
{
assert(target);
assert(source);
return (strcat(target, source) != NULL);
}á¤áĽáááŹáážá ááŻááşááąáŹááşááťááşá ááááşááᯠá á áşááąá¸ááźááşá¸áááş ááážááşáááşááŤá ááŻááşááąáŹááşááťááş strcat á áŹááźáąáŹááşá¸áááąáŹááşááŻáśá¸ááŹá¸áážááşá¸áááŻáˇ áá˝ážááşááźááťááşááᯠááźááşááąá¸áááşá áááŻáááŻáááşáážáŹá áááááąáŹááşááᯠááťáąáŹáşáá˝áŹá¸ááŤááźáŽá á¤ááá ášá áá˝ááşá áá áşáážááş. áááŻáˇááąáŹáş áááşá¸áá°ááźá áşááťážááş nullááŻááşááąáŹááşááťááşáážáááąáŹááźáąáŹááˇáş á á áşááąá¸áááş ááąáŹááşááťááąááźáŽááźá áşáááşá strcat áááŻá¸ááŹá¸ááŤáááşá
áá áşáááŻááşá¸áá áşá á
á ááŹá¸áááş 'cache' áááş áĄááźá˛áážááşáááşá glyph.c ááá
typedef struct rdp_glyph_cache rdpGlyphCache;
struct rdp_glyph_cache
{
....
GLYPH_CACHE glyphCache[10];
....
};
void glyph_cache_free(rdpGlyphCache* glyphCache)
{
....
GLYPH_CACHE* cache = glyphCache->glyphCache;
if (cache)
{
....
}
....
}á¤ááá ášá áá˝ááş variable ááᯠcache ááᯠstatic array áá áşááŻá ááááşá áŹááᯠáááşáážááşááąá¸ááŹá¸áááşá glyphCache->glyphCache. áááŻáˇááźáąáŹááˇáş á á áşááąá¸ááŤá áĄáááşá (cache) ááťááşáážááşáááŻááşáááşá
áĄáááşá¸áĄááźá áşá áŽááśáááˇáşáá˝á˛áážáŻ áĄáážáŹá¸
áááşá¸ááźá áşáááş 'CreateFileA' ááŻááşááąáŹááşááťááşááᯠáĄááŻáśá¸ááźáŻá ááá°áá˛áˇááąáŹáşáááşá¸ áá˝á˛áááşááŻáśá¸ááááąáŹ 'fclose' ááŻááşááąáŹááşááťááşááᯠáĄááŻáśá¸ááźáŻá ááŻááşááźááşáá˛áˇáááşá certificate.c ááá
BOOL certificate_data_replace(rdpCertificateStore* certificate_store,
rdpCertificateData* certificate_data)
{
HANDLE fp;
....
fp = CreateFileA(certificate_store->file, GENERIC_READ | GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
....
if (size < 1)
{
CloseHandle(fp);
return FALSE;
}
....
if (!data)
{
fclose(fp);
return FALSE;
}
....
}áááŻááşááąáŹáşááźááťááş fpááŻááşááąáŹááşááťááşááąáŤáşáááŻáážáŻááźááˇáş áááşááŽá¸ááŹá¸áááşá áááŻááşáááŻáááşááŽá¸ááŤá ááŻááşááąáŹááşááťááşáĄáŹá¸ááźááˇáş áážáŹá¸áá˝ááşá¸á ááááşááŹá¸áááşá fclose á áśá áŹááźááˇáşáááŻááşááž áááŻááşá፠CloseHandle.
áá°ááŽááąáŹáĄááźáąáĄááąááťáŹá¸
áá áşááŻáážááˇáşáá áşáᯠáážááşáá˝á˛áááşáážáááąáŹ 'if' ááźáąááŹááťááşááťáŹá¸á áĄááźáąáĄááąáĄá ááąáŹáşááźááťááşááťáŹá¸áááş áá°ááŽááŤáááşá áááŻááşá¸ááťáŹá¸ááᯠá á áşááąá¸ááŤ- 269, 283. ndr_structure.c 283
void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
unsigned char* pMemory, PFORMAT_STRING pFormat)
{
....
if (conformant_array_description)
{
ULONG size;
unsigned char array_type;
array_type = conformant_array_description[0];
size = NdrComplexStructMemberSize(pStubMsg, pFormat);
WLog_ERR(TAG, "warning: NdrComplexStructBufferSize array_type: "
"0x%02X unimplemented", array_type);
NdrpComputeConformance(pStubMsg, pMemory + size,
conformant_array_description);
NdrpComputeVariance(pStubMsg, pMemory + size,
conformant_array_description);
MaxCount = pStubMsg->MaxCount;
ActualCount = pStubMsg->ActualCount;
Offset = pStubMsg->Offset;
}
if (conformant_array_description)
{
unsigned char array_type;
array_type = conformant_array_description[0];
pStubMsg->MaxCount = MaxCount;
pStubMsg->ActualCount = ActualCount;
pStubMsg->Offset = Offset;
WLog_ERR(TAG, "warning: NdrComplexStructBufferSize array_type: "
"0x%02X unimplemented", array_type);
}
....
}á¤áĽáááŹáááş bug áááŻááşááŤá áááŻáˇááąáŹáşá áĄááźáąáĄááąáážá áşááŻá ááŻáśá¸áá˝ááş áá°ááŽááąáŹáááşááąáˇááťáşááťáŹá¸ááŤáážáááźáŽá¸ áááşá¸áááŻáˇáá˛ááž áá áşááŻááᯠáááşáážáŹá¸áá áşáááŻááşááźáąááťáŹá¸ááŤáááşá
null pointers ááťáŹá¸ááᯠáážááşá¸áááşá¸ááźááşá¸á
null pointer ááᯠ'free' function áááŻáˇ ááąá¸áááŻáˇáááşá ááááĄááźááşá¸áĄááŻáśáááŻá á áşááąá¸ááŤá smartcard_pcsc.c ááá
WINSCARDAPI LONG WINAPI PCSC_SCardListReadersW(
SCARDCONTEXT hContext,
LPCWSTR mszGroups,
LPWSTR mszReaders,
LPDWORD pcchReaders)
{
LPSTR mszGroupsA = NULL;
....
mszGroups = NULL; /* mszGroups is not supported by pcsc-lite */
if (mszGroups)
ConvertFromUnicode(CP_UTF8,0, mszGroups, -1,
(char**) &mszGroupsA, 0,
NULL, NULL);
status = PCSC_SCardListReaders_Internal(hContext, mszGroupsA,
(LPSTR) &mszReadersA,
pcchReaders);
if (status == SCARD_S_SUCCESS)
{
....
}
free(mszGroupsA);
....
}ááŻááşááąáŹááşáááş áĄááá˛áˇ áááşáááş null pointer áááŻááźááşáááŻááşááźáŽá¸ áááşá¸ááᯠáá˝á˛ááźááşá¸á áááşááźáŹáá°ááž ááááŤáááşá áááŻáˇááąáŹáş á¤áĄáááŻáĄáá˝áŹáá˝ááşáá˛áˇáááŻáˇ pointer ááᯠáĄááźá˛áááşá¸ null ááťáąáŹáşáá˝áŹá¸áááˇáş áĄááźáąáĄááąáá áşááŻááᯠáá˝áąáˇáážáááŤáá áááááąá¸ááťááşááᯠááŻááşááźááşááŤáááşá
pointer mszGroupsA áĄá áááąáŹáˇ áááşá¸áá°áá˛á null áĄááźáŹá¸áááşáááˇáşááąááŹáá˝ááşááž áĄá ááźáŻáááŹá¸ááŤá áá˝ážááşááźááťááşááᯠá áááşááŻááşááąáŹááşáááŻááşáááˇáş áá áşááŻáááşá¸ááąáŹ ááŻááşáĄáááŻááşá¸áĄáááşááᯠáááşáážááşá¸áááŽáááŻááşááŤá
áá˛áˇáááŻáˇááąáŹ áĄááźáŹá¸áááşááąáˇááťáşááťáŹá¸ áážááá˛áˇáááş-
- V575 null pointer ááᯠ'free' function áááŻáˇ ááąá¸áááŻáˇáááşá ááááĄááźááşá¸áĄááŻáśáááŻá á áşááąá¸ááŤá áááŻááşá ááş.c ááá
- V575 null pointer ááᯠ'free' function áááŻáˇ ááąá¸áááŻáˇáááşá ááááĄááźááşá¸áĄááŻáśáááŻá á áşááąá¸ááŤá rdpsnd_alsa.c á áá
ááźá áşáááŻááşááťáąáĄááťáŹá¸á áŻáážáŹá refactoring ááŻááşáááşá¸á ááşáĄáá˝ááşá¸ ááąáˇáá˝áŹá¸ááąáŹ ááááşá¸áážááşááťáŹá¸ ááąáŤáşááŹááźáŽá¸ áááŻá¸áážááşá¸á á˝áŹ áááşáážáŹá¸áááŻááşáááşá
áĄááťážáśáááşááźá áşáááŻááşáááşá
áĄááťážáśáááşááźá áşáááŻááşáááşá ááááşáááŻááşáᲠoperand ááťáŹá¸ááᯠááŹá áşááŻááşáááş á ááşá¸á áŹá¸ááŤá makecert.c áááá
// openssl/x509.h
ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj);
struct _MAKECERT_CONTEXT
{
....
int duration_years;
int duration_months;
};
typedef struct _MAKECERT_CONTEXT MAKECERT_CONTEXT;
int makecert_context_process(MAKECERT_CONTEXT* context, ....)
{
....
if (context->duration_months)
X509_gmtime_adj(after, (long)(60 * 60 * 24 * 31 *
context->duration_months));
else if (context->duration_years)
X509_gmtime_adj(after, (long)(60 * 60 * 24 * 365 *
context->duration_years));
....
}ááááşááᯠáá°ááąáŹááşááŹáááşá áážááşááťáŹá¸ááąáŹ áĄááťááŻá¸áĄá áŹá¸ááᯠáĄááŻáśá¸ááźáŻá áá˝ááşááťááşáážáŻáááŻááşáááŻááş ááźá áşááąáŤáşááąáŹááźáąáŹááˇáş áá˝ážááşá¸áááŻá¸ááŹáá˝ááşáážáŻ áááŻááşááŤá int.
áĄá ááźáŻááźááşá¸áá˝ááş áá˝ážááşááźáááˇáş áážáąáŹááˇáşáážáąá¸áážáŻ
nullptr ááᯠáá á áşááąá¸áᎠ'context' pointer ááᯠáĄááŻáśá¸ááźáŻáá˛áˇáááşá áááŻááşá¸ááťáŹá¸ááᯠá á áşááąá¸ááŤ- 746, 748. gfx.c 746
static UINT gdi_SurfaceCommand(RdpgfxClientContext* context,
const RDPGFX_SURFACE_COMMAND* cmd)
{
....
rdpGdi* gdi = (rdpGdi*) context->custom;
if (!context || !cmd)
return ERROR_INVALID_PARAMETER;
....
}á¤áá˝ááşáá˝ážááşááźááťááş á ááŹá¸á ááş á á áşááąá¸ááźááşá¸áááźáŻáᎠáááŚá¸áááşáážááşááźááşá¸áá˝ááş áááşáá˝ážááşá¸ááŹá¸áááşá
á¤áĄááťááŻá¸áĄá áŹá¸á áĄááźáŹá¸áĄáážáŹá¸ááťáŹá¸ááᯠáá˝áąáˇáážááá˛áˇáááş-
- V595 áááş nullptr ááᯠáá á áşááąá¸áᎠ'ntlm' pointer ááᯠáĄááŻáśá¸ááźáŻáá˛áˇáááşá áááŻááşá¸ááťáŹá¸ááᯠá á áşááąá¸ááŤ- 236, 255. ntlm.c 236
- V595 nullptr ááᯠáá á áşááąá¸áᎠ'context' pointer ááᯠáĄááŻáśá¸ááźáŻáá˛áˇáááşá áááŻááşá¸ááťáŹá¸ááᯠá á áşááąá¸ááŤ- 1003, 1007. rfx.c 1003
- V595 áááş nullptr ááᯠáá á áşááąá¸áᎠ'rdpei' pointer ááᯠáĄááŻáśá¸ááźáŻáá˛áˇáááşá áááŻááşá¸ááťáŹá¸ááᯠá á áşááąá¸ááŤ- 176, 180. rdpei_main.c 176
- V595 áááş nullptr ááᯠáá á áşááąá¸áᎠ'gdi' pointer ááᯠáĄááŻáśá¸ááźáŻáá˛áˇáááşá áááŻááşá¸ááťáŹá¸ááᯠá á áşááąá¸ááŤ- 121, 123. xf_gfx.c 121
áĄáááášááŤááşáá˛áˇ áĄááźáąáĄááą
á ááŹá¸áááş 'rdp->state >= CONNECTION_STATE_ACTIVE' áááş áĄááźá˛áááşá¸ áážááşááŤáááşá connection.c áááá
int rdp_server_transition_to_state(rdpRdp* rdp, int state)
{
....
switch (state)
{
....
case CONNECTION_STATE_ACTIVE:
rdp->state = CONNECTION_STATE_ACTIVE; // <=
....
if (rdp->state >= CONNECTION_STATE_ACTIVE) // <=
{
IFCALLRET(client->Activate, client->activated, client);
if (!client->activated)
return -1;
}
....
}
....
}áááşáááŻááşááŹáááşáááŻá¸ááᯠáĄá áąáŹáááŻááşá¸áá˝ááş áááşáážááşááąá¸ááźááşá¸ááźáąáŹááˇáş ááááĄááźáąáĄááąáááş áĄáááášááŤááşááážááááşááᯠááááźááşáááş áá˝ááşáá°áááşá
á áŹááźáąáŹááşá¸áá˝á˛ááźááşá¸á áááşááźáŹáážáŻ ááážááşáááşááŤá
ááąáŹáşáááşááážááşáááşááŤá 'scanf' ááŻááşááąáŹááşááťááşááááááĄáážááşááááşáĄááźááşá¸áĄááŻáśáááŻá á áşááąá¸áááşá ááşá¸á áŹá¸ááŤá áááşáážááşááááŻá¸ááŹá¸áááˇáş int áĄááťááŻá¸áĄá áŹá¸áĄáá˝ááş áá˝ážááşááźááťááşááᯠááťážáąáŹáşáááˇáşááŹá¸áááşá proxy.c ááá
conditional expression á áĄá áááşáĄáááŻááşá¸áá áşááŻáááş áĄááźá˛áážááşáááş- (rc >= 0)á proxy.c ááá
static BOOL check_no_proxy(....)
{
....
int sub;
int rc = sscanf(range, "%u", &sub);
if ((rc == 1) && (rc >= 0))
{
....
}
....
}áá˝á˛ááźááşá¸á áááşááźáŹáá°áááş á¤áĄáááŻááşá¸áĄá áĄáá˝ááş áááááąá¸ááťááş á ááŻááᯠááťááşááťááşá¸ááŻááşááąá¸áááşá áááşáážááşááťááş %u áĄááťááŻá¸áĄá áŹá¸áá˝á˛ááźáŹá¸áážáŻááᯠááťážáąáŹáşáááˇáşáááşá áááşáážááşááááŻá¸ intááŤááąáááˇáş ááźáąáŹááşá¸áá˛áááŻááşááŤáááşá áá˝á˛ááťáŹá¸ áĄááťááŻá¸áĄá áŹá¸ áážááááşá int. ááąáŹááşáá áşáᯠááťá˝ááşáŻááşáááŻáˇáááş ááśááááźá áşáá˝ááşá á áşááąá¸áážáŻáá áşááŻááᯠáá˝áąáˇááááş- ááŹáááşáážááĄááźáąáĄááąáááş áĄáááášááŹááşááážáááŤá áĄá áá˝ááşáá áşááŻáážááˇáş áážááŻááşá¸áážááşáážáŻáá áşááŻáážáááąáŹááźáąáŹááˇáşááźá áşáááşá á¤ááŻááşááąá¸ááŹá¸áá°áááş ááŹáááŻáááŻáááŻáááşááᯠááťá˝ááşáŻááşáááááąáŹáşáááşá¸ á¤ááąááŹáá˝ááş áá áşááŻááŻáážáŹá¸ááąááźáŽááźá áşáááşá
ááźááşáááž á á áşááąá¸áážáŻááťáŹá¸
ááąáŹáşááźááťááş 'áĄááźáąáĄááą == 0x00090314' áááş áĄááźá˛áááşá¸ áá˝á˛áážáŹá¸ááąááŤáááşá ntlm.c ááá
BOOL ntlm_authenticate(rdpNtlm* ntlm, BOOL* pbContinueNeeded)
{
....
if (status != SEC_E_OK)
{
....
return FALSE;
}
if (status == SEC_I_COMPLETE_NEEDED) // <=
status = SEC_E_OK;
else if (status == SEC_I_COMPLETE_AND_CONTINUE) // <=
status = SEC_I_CONTINUE_NEEDED;
....
}á á áşááąá¸ááŹá¸ááąáŹ áĄááźáąáĄááąááťáŹá¸áááş áĄááźá˛áááşá¸ áážáŹá¸áá˝ááşá¸ááąáááşááźá áşááźáŽá¸á ááŻááşááąáŹááşáážáŻáááş ááŻááááĄááźáąáĄááąáááŻáˇáᏠááąáŹááşáážááááşááźá áşááąáŹááźáąáŹááˇáşá áĄááźáąáĄááą == SEC_E_OK. áážááşáááşááąáŹááŻááşáááş á¤áá˛áˇáááŻáˇááźá áşáááŻááşáááş-
if (status == SEC_I_COMPLETE_NEEDED)
status = SEC_E_OK;
else if (status == SEC_I_COMPLETE_AND_CONTINUE)
status = SEC_I_CONTINUE_NEEDED;
else if (status != SEC_E_OK)
{
....
return FALSE;
}ááąáŹááşááťááş
áááŻáˇááźáąáŹááˇáş áááąáŹááťááşááᯠá á áşááąá¸ááźááşá¸ááźááˇáş ááźáżááŹááťáŹá¸á á˝áŹááᯠáááşáážáŹá¸á áąááąáŹáşáááşá¸ áááşá¸áááŻáˇáá˛ááž á áááşáááşá áŹá¸á ááŹáĄááąáŹááşá¸ááŻáśá¸áĄáááŻááşá¸áááŻáᏠááąáŹááşá¸ááŤá¸áá˝ááş ááąáŹáşááźááŹá¸ááŤáááşá áááąáŹááťááş developer ááťáŹá¸áááş áááşáááŻááşáážá ááŹááŽáááŻááşá ááşááŽá¸ááᯠááąáŹááşá¸áááŻááźááşá¸ááźááˇáş áááąáŹááťááşááᯠáááŻááşáááŻááşá á áşááąá¸áááŻááşáááşá . áá˝á˛ááźááşá¸á áááşááźáŹáá°ááᯠáááŻáááŻááąáŹááşá¸áá˝ááşáĄáąáŹááş ááŻááşááąáŹááşááąá¸áááˇáş áážáŹá¸áá˝ááşá¸ááąáŹ áĄááźáŻáááąáŹááąáŹááşáážáŻááťáŹá¸áááşá¸ áážááá˛áˇáááşá áááŻáˇááąáŹáşá áááşáááş áááşáááŻááşáĄáááşáĄáá˝áąá¸ááᯠáááŻá¸áááşá áąááŻáśááŹáá áĄáážáŹá¸áĄáá˝ááşá¸ááťáŹá¸áážáŹáá˝áąáááˇáşáĄááťáááşááᯠááťážáąáŹáˇááťáááŻááŤá static analysis áááş áĄááąá¸ááźáŽá¸ááźáŽá¸ áááşá¸ááᯠPVS-Studio ááž áá°ááŽááąá¸áááŻááşááŤáááşá
á¤ááąáŹááşá¸ááŤá¸ááᯠáĄááşášáááááşá ááŹá¸ááźáąáŹááááááşáážááˇáş ááťážááąáááŻááŤáá ááŹááŹááźááşáááˇáşááş- Sergey Larin ááᯠáĄááŻáśá¸ááźáŻááŤá
source: www.habr.com
