ዹPVS-ስቱዲዮ ተንታኝ በመጠቀም FreeRDPን በመፈተሜ ላይ

ዹPVS-ስቱዲዮ ተንታኝ በመጠቀም FreeRDPን በመፈተሜ ላይ
ፍሪአርዲፒ (FreeRDP) ዚሩቅ ዎስክቶፕ ፕሮቶኮል (RDP) ክፍት ምንጭ ትግበራ ሲሆን ይህም በማይክሮሶፍት ዹተዘጋጀ ዚርቀት ኮምፒውተር ቁጥጥር ፕሮቶኮል ነው። ፕሮጀክቱ በርካታ መድሚኮቜን ይደግፋል፣ ኚእነዚህም ውስጥ Windows, Linux, macOS እና iOS እንኳን ኹ ጋር Androidይህ ፕሮጀክት ዹ PVS-ስቱዲዮ ስታቲክ አናሊዘርን በመጠቀም ዹ RDP ደንበኞቜን ለመፈተሜ ኚተዘጋጁት ተኚታታይ መጣጥፎቜ ውስጥ ዚመጀመሪያው ሆኖ ተመርጧል።

ትንሜ ታሪክ

ፕሮጀክቱ FreeRDP ማይክሮሶፍት ዚባለቀትነት መብቱን ዹRDP ፕሮቶኮሉን ዝርዝር መግለጫዎቜ ኹኹፈተ በኋላ ብቅ አለ። በዚያን ጊዜ ዹrdesktop ደንበኛ ዹነበሹ ሲሆን አተገባበሩም በተገላቢጊሜ ኢንጂነሪንግ ውጀቶቜ ላይ ዹተመሠሹተ ነበር።

ፕሮቶኮሉ እዚተተገበሚ እያለ፣ በፕሮጀክቱ ነባር አርክቮክቾር ምክንያት አዲስ ተግባር መጹመር አስ቞ጋሪ ሆነ። በዚህ አርክቮክቾር ላይ ዹተደሹጉ ለውጊቜ በገንቢዎቜ መካኚል ግጭት ፈጥሚዋል፣ ይህም ዹrdesktop—FreeRDP ሹካ እንዲፈጠር ምክንያት ሆኗል። ዚምርቱ ተጚማሪ ስርጭት በGPLv2 ፈቃድ ዹተገደበ ሲሆን ይህም ወደ Apache License v2 እንደገና ፈቃድ እንዲሰጥ ውሳኔ አስተላለፈ። ሆኖም ግን፣ ሁሉም ሰው ለኮዳ቞ው ፈቃዱን ለመቀዹር አልተስማማም፣ ስለዚህ ገንቢዎቹ ፕሮጀክቱን እንደገና ለመጻፍ ወሰኑ፣ ይህም ዹአሁኑን ዚኮድ መሰሚት አስኚትሏል።

ስለ ፕሮጀክቱ ታሪክ ተጚማሪ ዝርዝሮቜን በኩፊሮላዊው ዚብሎግ ልጥፍ ውስጥ ማግኘት ይቻላል፡ "ዹFreeRDP ፕሮጀክት ታሪክ"።

በኮዱ ውስጥ ስህተቶቜን እና ሊሆኑ ዚሚቜሉ ተጋላጭነቶቜን ለመለዚት እንደ መሳሪያ፣ ጥቅም ላይ ውሏል PVS- ስቱዲዮለC፣ C++፣ C# እና Java ዚማይንቀሳቀስ ዚኮድ ተንታኝ ሲሆን በፕላትፎርሞቜ ላይ ይገኛል Windows, Linux О macOS.

ጜሑፉ ዚሚያቀርበው በጣም አስደሳቜ ሆነው ያገኘኋ቞ውን ስህተቶቜ ብቻ ነው።

ዹማህደሹ ትውስታ መፍሰስ

V773 ዹ'cwd' ጠቋሚውን ሳይለቅ ተግባሩ ወጥቷል። ዹማህደሹ ትውስታ መፍሰስ ይቻላል። environment.c 84

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;
  ....
}

ይህ ቁራጭ ዹተወሰደው ኹዊንፐር ንዑስ ስርዓት ሲሆን፣ ይህም ለ- ያልሆኑ ዹWINAPI መጠቅለያዎቜን ዚሚያስተገብር ነው።Windows ስርዓቶቜ፣ ማለትም፣ ቀላል ክብደት ያለው ዹወይን አናሎግ ነው። እዚህ ላይ መፍሰስን ማዚት ይቜላሉ፡ በተግባሩ ዹተመደበ ማህደሹ ትውስታ getcwd, ዹሚለቀቀው ልዩ ጉዳዮቜን ሲያስተናግድ ብቻ ነው። ስህተቱን ለማስተካኚል ጥሪ ማኹል ያስፈልግዎታል። ፍርይ пПсле ትውስታ.

ኹወሰን ውጭ አደራደር

V557 ዚድርድር መሻር ይቻላል። ዹ'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 ድርድር መሻር ይቻላል። ዹ'iBitmapFormat' ኢንዎክስ እሎት 8 ሊደርስ ይቜላል። orders.c 2623

ታይፖስ

ክፍል 1

V547 '!pipe->In' ዹሚለው አገላለጜ ሁልጊዜ ሐሰት ነው። MessagePipe.c 63

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;
  ....
}

እዚህ ላይ ዹተለመደ ዹፊደል አጻጻፍ እናያለን፡ ሁለተኛው ሁኔታ ኚመጀመሪያው ጋር ተመሳሳይ ዹሆነ ተለዋዋጭ ይፈትሻል። ስህተቱ ዚመጣው ደካማ ዚኮድ ቅጂ-መለጠፍ ምክንያት ሊሆን ይቜላል።

ክፍል 2

V760 ሁለት ተመሳሳይ ጜሑፍ ያላ቞ው ብሎኮቜ ተገኝተዋል። ሁለተኛው ብሎክ ዹሚጀምሹው ኚመስመር 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);
  ....
}

ሌላ ዹፊደል አጻጻፍ፡ ዚኮድ አስተያዚት ዚሚያመለክተው ዥሚቱ ኚውጪ መምጣት እንዳለበት ነው አነስተኛ ስሪትሆኖም ግን፣ ንባቡ ወደተሰዹመ ተለዋዋጭ ይኚሰታል ዋና ስሪትሆኖም ግን፣ ስለ ፕሮቶኮሉ አላውቅም፣ ስለዚህ ይህ ግምታዊ ብቻ ነው።

ክፍል 3

V524 ዹ'trio_index_last' ተግባር አካል ኹ'trio_index' ተግባር አካል ጋር ሙሉ በሙሉ እኩል መሆኑ እንግዳ ነገር ነው። triostr.c 933

/**
   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);
}

በአስተያዚቱ መሰሚት፣ ተግባሩ ትራይዮ_ኢንዎክስ በአንድ ሕብሚቁምፊ ውስጥ ዚአንድ ቁምፊ ዚመጀመሪያ ተዛማጅ ሲያገኝ ትራይዮ_ኢንዎክስ_መጚሚሻ — ዚመጚሚሻው። ነገር ግን ዚእነዚህ ተግባራት አካላት ተመሳሳይ ናቾው! ምናልባትም ይህ ዹፊደል አጻጻፍ ስህተት ነው፣ እና በተግባሩ ውስጥ። ትራይዮ_ኢንዎክስ_መጚሚሻ መጠቀም ያስፈልጋል ስትርቜር በ ስትርክኚዚያም ባህሪው እንደተጠበቀው ይሆናል።

ክፍል 4

V769 በአገላለጹ ውስጥ ያለው 'ዳታ' ጠቋሚ ኹ nullptr ጋር እኩል ነው። በዚህ ጠቋሚ ላይ ዚሒሳብ ስራዎቜ ውጀት ዋጋ ትርጉም ዚለሜ ስለሆነ ጥቅም ላይ መዋል ዚለበትም። nsc_encode.c 124

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;
  ....
}

እዚህ ላይ በድንገት ዚኔጌሜን ኊፕሬተርን ያመለጡ ይመስላል። ! አቅራቢያ መሹጃይህ ሳይስተዋል መሄዱ እንግዳ ነገር ነው።

ክፍል 5

V517 ዹ'if (A) {
} አጠቃቀም አለበለዚያ (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) {
} አጠቃቀም አለበለዚያ (A) {
}' ንድፍ ተገኝቷል። ዹሎጂክ ስህተት ዹመኖር እድል አለ። መስመሮቜን ያሚጋግጡ፡ 169፣ 173። file.c 169

ዚግቀት ዚውሂብ ማሚጋገጫ

ክፍል 1

V547 'strcat(target, source) != NULL' ዹሚለው አገላለጜ ሁልጊዜ እውነት ነው። triostr.c 425

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);
}

በዚህ ምሳሌ ውስጥ ዚተግባር ውጀት ማሚጋገጫ ዚተሳሳተ ነው። ስትራካት ወደ ሕብሚቁምፊው ዚመጚሚሻ ስሪት ጠቋሚ ይመልሳል፣ ማለትም ዚመጀመሪያው መለኪያ አልፏል። በዚህ ሁኔታ፣ እሱ ነው ዒላማሆኖም ግን፣ እኩል ኹሆነ ባዶኚዚያ እሱን ለመፈተሜ በጣም ዘግይቷል፣ ምክንያቱም በተግባሩ ውስጥ ስለሆነ ስትራካት ይሰሚዛል።

ክፍል 2

V547 'መሞጎጫ' ዹሚለው አገላለጜ ሁልጊዜ እውነት ነው። glyph.c 730

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)
  {
    ....
  }
  ....
}

በዚህ ሁኔታ ተለዋዋጭው መሞጎጫ ዚስታቲክ ድርድር አድራሻ ተመድቧል ግሊፍካሌ -> ግሊፍካሌስለዚህ፣ ቌኩ ኹሆነ (መሞጎጫ) ሊወገድ ይቜላል።

ዚሀብት አስተዳደር ስህተት

V1005 ሀብቱ ዹተገኘው 'CreateFileA' ተግባርን በመጠቀም ነው፣ ነገር ግን ዚማይጣጣም 'fclose' ተግባርን በመጠቀም ተለቋል። certificate.c 447

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 ኹመደበኛው ቀተ-መጜሐፍት፣ አይደለም ዝጋ ሃንድል.

ተመሳሳይ ሁኔታዎቜ

V581 እርስ በእርስ ጎን ለጎን ዚሚገኙት ዹ'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);
  }
  ....
}

ይህ ምሳሌ ስህተት ላይሆን ይቜላል። ሆኖም፣ ሁለቱም ሁኔታዎቜ ተመሳሳይ መልዕክቶቜን ዚያዙ ሲሆን ኚእነዚህም ውስጥ አንዱ ሊወገድ ይቜላል።

ባዶ ጠቋሚዎቜን ማጜዳት

V575 ባዶ ጠቋሚው ወደ 'ነጻ' ተግባር ይተላለፋል። ዚመጀመሪያውን ክርክር ይመርምሩ። smartcard_pcsc.c 875

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);
  ....
}

ለመስራት ፍርይ ባዶ ጠቋሚን ማለፍ ይቜላሉ፣ እና ተንታኙ ስለሱ ያውቃል። ነገር ግን ጠቋሚው ሁልጊዜ ባዶ ሆኖ ዚሚተላለፍበት ሁኔታ ኚተገኘ፣ ልክ እንደዚሁ ክፍልፋይ፣ ማስጠንቀቂያ ይሰጣል።

ጠቋሚ mszGroupsA መጀመሪያ ላይ እኩል ባዶ እና በሌላ ቊታ አልተጀመሚም። ጠቋሚው ሊጀመርበት ዚሚቜልበት ብ቞ኛው ዚኮድ መንገድ ሊደሚስበት ዚማይቜል ነው።

እንደዚህ አይነት ሌሎቜ መልዕክቶቜም ነበሩ፡

  • V575 ባዶ ጠቋሚው ወደ 'ነጻ' ተግባር ይተላለፋል። ዚመጀመሪያውን ክርክር ይመርምሩ። license.c 790
  • V575 ባዶ ጠቋሚው ወደ 'ነጻ' ተግባር ይተላለፋል። ዚመጀመሪያውን ክርክር ይመርምሩ። rdpsnd_alsa.c 575

ምናልባትም እንደዚህ ያሉ ዚተሚሱ ተለዋዋጮቜ በመልሶ ማደስ ሂደት ወቅት ይነሳሉ እና በቀላሉ ሊወገዱ ይቜላሉ።

ሊኚሰት ዚሚቜል ኹመጠን በላይ መፍሰስ

V1028 ሊኚሰት ዚሚቜል ኹመጠን በላይ መፍሰስ። ዚኊፔራ ቀሚጻዎቜን ያስቡበት፣ ውጀቱን አይደለም። makecert.c 1087

// 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.

በማስጀመሪያ ጊዜ ዹጠቋሚ ማፈግፈግ

V595 ዹ'አውድ' ጠቋሚው ኹnullptr ጋር ኚመሚጋገጡ በፊት ጥቅም ላይ ውሏል። መስመሮቜን ያሚጋግጡ፡ 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 ዹ'ntlm' ጠቋሚው ኹnullptr ጋር ኚመሚጋገጡ በፊት ጥቅም ላይ ውሏል። መስመሮቜን ያሚጋግጡ፡ 236፣ 255። ntlm.c 236
  • V595 ዹ'አውድ' ጠቋሚው ኹnullptr ጋር ኚመሚጋገጡ በፊት ጥቅም ላይ ውሏል። መስመሮቜን ያሚጋግጡ፡ 1003፣ 1007። rfx.c 1003
  • V595 ዹ'rdpei' ጠቋሚ ኹnullptr ጋር ኚመሚጋገጡ በፊት ጥቅም ላይ ውሏል። መስመሮቜን ያሚጋግጡ፡ 176፣ 180። rdpei_main.c 176
  • V595 ዹ'gdi' ጠቋሚው ኹnullptr ጋር ኚመሚጋገጡ በፊት ጥቅም ላይ ውሏል። መስመሮቜን ያሚጋግጡ፡ 121፣ 123። xf_gfx.c 121

ትርጉም ዚለሜ ሁኔታ

V547 'rdp->state >= CONNECTION_STATE_ACTIVE' ዹሚለው አገላለጜ ሁልጊዜ እውነት ነው። connection.c 1489

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;
      }
    ....
  }
  ....
}

ቀደም ሲል ተጓዳኝ እሎት በመመደቡ ምክንያት ዚመጀመሪያው ሁኔታ ትርጉም እንደማይሰጥ ማዚት ቀላል ነው።

ዚተሳሳተ ዚሕብሚቁምፊ ትንተና

V576 ዚተሳሳተ ቅርጞት። ዹ'sscanf' ተግባርን ሶስተኛውን ትክክለኛ ክርክር መፈተሜ ያስቡበት። ወደ ያልተፈሚመ ዹ int አይነት ጠቋሚ ይጠበቃል። proxy.c 220

V560 ዚሁኔታዊ አገላለጜ ክፍል ሁልጊዜ እውነት ነው፡ (rc >= 0)። proxy.c 222

static BOOL check_no_proxy(....)
{
  ....
  int sub;
  int rc = sscanf(range, "%u", &sub);

  if ((rc == 1) && (rc >= 0))
  {
    ....
  }
  ....
}

ተንታኙ ለዚህ ክፍል ሁለት ማስጠንቀቂያዎቜን ይሰጣል። %u ዚአይነት ተለዋዋጭ ይጠብቃል ያልተፈሚመ ኢንቲግን ተለዋዋጭ ንዑስ አይነት አለው intቀጥሎ፣ አጠራጣሪ ፍተሻ እናያለን፡ በቀኝ በኩል ያለው ሁኔታ ምንም ትርጉም አይሰጥም፣ ምክንያቱም ኚአንዱ ጋር በማነፃፀር ይጀምራል። ዹዚህ ኮድ ደራሲ ምን እንዳሰበ አላውቅም፣ ግን እዚህ ላይ ዹሆነ ነገር በግልጜ ዚተሳሳተ ነው።

ያልተደሚደሩ ቌኮቜ

V547 'status == 0x00090314' ዹሚለው አገላለጜ ሁልጊዜ ዚተሳሳተ ነው። ntlm.c 299

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;
}

መደምደሚያ

ስለዚህ ዚፕሮጀክቱ ግምገማ በርካታ ጉዳዮቜን ይፋ አድርጓል፣ ነገር ግን በጣም አስደሳቜ ዚሆኑት ብቻ በጜሑፉ ውስጥ ተገልጞዋል። ዚፕሮጀክት ገንቢዎቜ በድሚ-ገጹ ላይ ጊዜያዊ ዚፈቃድ ቁልፍ በመጠዹቅ ፕሮጀክቱን እራሳ቞ው መገምገም ይቜላሉ። PVS- ስቱዲዮእንዲሁም አንዳንድ ዚተሳሳቱ አዎንታዊ ነገሮቜ ነበሩ፣ እነዚህም ኚተስተካኚሉ ተንታኙን ለማሻሻል ይሚዳሉ። ያም ሆኖ፣ ዚኮድ ጥራትን ማሻሻል ብቻ ሳይሆን ስህተቶቜን ለማግኘት ዚሚያጠፋውን ጊዜ መቀነስ ኹፈለጉ ዚማይንቀሳቀስ ትንተና አስፈላጊ ነው፣ እና PVS-ስቱዲዮ በዚህ ሚገድ ሊሚዳ ይቜላል።

ዹPVS-ስቱዲዮ ተንታኝ በመጠቀም FreeRDPን በመፈተሜ ላይ

ይህን ጜሑፍ ለእንግሊዝኛ ተናጋሪ ታዳሚዎቜ ማጋራት ኚፈለጉ፣ እባክዎ ዚትርጉም ማገናኛውን ይጠቀሙ፡ Sergey Larin። FreeRDPን በ PVS-ስቱዲዮ መፈተሜ

ምንጭ: hab.com

በDDoS ጥበቃ፣ VPS VDS አገልጋዮቜ ለጣቢያዎቜ አስተማማኝ ማስተናገጃ ይግዙ 🔥 አስተማማኝ ዚድር ጣቢያ ማስተናገጃ በዲዶኀስ ጥበቃ፣ በቪፒኀስ ቪዲኀስ አገልጋዮቜ ይግዙ | ProHoster