Hubinta rdesktop-ka iyo xrdp adigoo isticmaalaya PVS-Studio analyzer

Hubinta rdesktop-ka iyo xrdp adigoo isticmaalaya PVS-Studio analyzer
Tani waa dib-u-eegistii labaad ee maqaallo taxane ah oo ku saabsan tijaabinta barnaamijyada isha furan ee la shaqaynta borotokoolka RDP. Dhexdeeda waxaan ku eegi doonaa macmiilka rdesktop-ka iyo server-ka xrdp.

Loo isticmaalo sidii qalab lagu aqoonsado khaladaadka PVS-Studio. Waa falanqeeye koodhka taagan ee C, C++, C # iyo luqadaha Java, oo laga heli karo Windows, Linux iyo macOS.

Maqaalku wuxuu soo bandhigayaa oo kaliya khaladaadkaas oo ii muuqday kuwo xiiso leh. Si kastaba ha ahaatee, mashruucyadu way yar yihiin, markaa waxaa jiray khaladaad yar :).

tacliiq. Maqaal hore oo ku saabsan xaqiijinta mashruuca FreeRDP waa la heli karaa halkan.

rdsktop

rdsktop - hirgelinta bilaashka ah ee macmiilka RDP ee nidaamyada UNIX ku salaysan. Waxa kale oo lagu isticmaali karaa Windows-ka hoostiisa haddii aad dhisto mashruuca hoosta Cygwin. Shatiga ku haysta GPLv3.

Macmiilkani aad buu caan u yahay - waxaa si caadi ah loogu isticmaalaa ReactOS, oo sidoo kale waxaad ka heli kartaa geesaha hore ee garaafyada dhinac saddexaad. Si kastaba ha ahaatee, isagu aad buu u da' weyn yahay: siideyntiisii ​​ugu horreysay waxay dhacday Abriil 4, 2001 - waqtiga qorista, waa 17 sano jir.

Sidaan hore u sheegay, mashruucu aad buu u yar yahay. Waxay ka kooban tahay qiyaastii 30 kun oo xariiq oo kood ah, taas oo ah waxoogaa la yaab leh marka loo eego da'deeda. Marka la barbardhigo, FreeRDP waxay ka kooban tahay 320 kun oo xariiq. Waa kan wax soo saarka barnaamijka Cloc:

Hubinta rdesktop-ka iyo xrdp adigoo isticmaalaya PVS-Studio analyzer

Koodhka aan la gaadhi karin

V779 Koodhka aan la heli karin ayaa la ogaaday Waxaa suurtogal ah in qalad uu jiro. rdsktop.c 1502

int
main(int argc, char *argv[])
{
  ....
  return handle_disconnect_reason(deactivated, ext_disc_reason);

  if (g_redirect_username)
    xfree(g_redirect_username);

  xfree(g_username);
}

Khaladka ayaa isla markiiba nala kulmaya shaqada ugu weyn ee: waxaan aragnaa koodka ka dambeeya hawlwadeenka soo laabtay - jajabkani wuxuu sameeyaa nadiifinta xusuusta. Si kastaba ha noqotee, qaladku ma keeno khatar: dhammaan xusuusta loo qoondeeyay waxaa lagu nadiifin doonaa nidaamka hawlgalka ka dib marka barnaamijku baxo.

Ma jiro qalad la maarayn

V557 Array underrun waa suurtagal. Qiimaha 'n' index wuxuu gaari karaa -1. rdsktop.c 1872

RD_BOOL
subprocess(char *const argv[], str_handle_lines_t linehandler, void *data)
{
  int n = 1;
  char output[256];
  ....
  while (n > 0)
  {
    n = read(fd[0], output, 255);
    output[n] = ' '; // <=
    str_handle_lines(output, &rest, linehandler, data);
  }
  ....
}

Nuqulka koodka ee kiiskan wuxuu ka akhriyaa faylka oo geliyaa meel kaydinta ilaa faylka uu dhammaanayo. Si kastaba ha ahaatee, ma jiraan wax qalad ah oo lagu maamulayo halkan: haddii ay wax qaldamaan, markaa akhri soo laaban doona -1, ka dibna shaxdu waa la dhaafi doonaa wax soo saarka.

Isticmaalka EOF nooca char

V739 EOF waa in aan lala barbar dhigin qiimaha nooca 'char'. The '(c = fgetc(fp))' waa inuu noqdaa nooca 'int'. ctrl.c 500


int
ctrl_send_command(const char *cmd, const char *arg)
{
  char result[CTRL_RESULT_SIZE], c, *escaped;
  ....
  while ((c = fgetc(fp)) != EOF && index < CTRL_RESULT_SIZE && c != 'n')
  {
    result[index] = c;
    index++;
  }
  ....
}

Halkan waxaan ku aragnaa maaraynta khaldan ee gaaritaanka dhamaadka faylka: haddii fgetc soo celisa xaraf koodkiisu yahay 0xFF, waxaa loo fasiri doonaa dhamaadka faylka (EOF).

EOF waa joogto, inta badan waxaa lagu qeexaa sida -1. Tusaale ahaan, CP1251 codaynta, xarafka ugu dambeeya ee alifbeetada Ruushku wuxuu leeyahay koodka 0xFF, kaas oo u dhigma lambarka -1 haddii aan ka hadlayno doorsoome sida char. Waxaa soo baxday in calaamadda 0xFF, sida EOF (-1) waxaa loo fasirtay dhamaadka faylka. Si looga fogaado khaladaadka noocaas ah, natiijada shaqadu waa fgetc waa in lagu kaydiyaa doorsoome sida INT.

Typos

Jajab 1

V547 Odhaahda 'write_time' had iyo jeer waa been. disk.c 805

RD_NTSTATUS
disk_set_information(....)
{
  time_t write_time, change_time, access_time, mod_time;
  ....
  if (write_time || change_time)
    mod_time = MIN(write_time, change_time);
  else
    mod_time = write_time ? write_time : change_time; // <=
  ....
}

Waxaa laga yaabaa in qoraaga koodkan uu qalday || ΠΈ && xaalad. Aynu tixgelinno fursadaha suurtagalka ah ee qiyamka qor_time ΠΈ beddelka_waqtiga:

  • Labada doorsoome waxay le'eg yihiin 0: kiiskan waxaan ku dambayn doonaa laan kaledoorsoome mod_time had iyo jeer waxay noqon doontaa 0 iyadoon loo eegin xaaladda xigta.
  • Mid ka mid ah doorsoomayaasha waa 0: mod_time waxay la mid noqon doontaa 0 (waa haddii doorsoomaha kale uu leeyahay qiime aan xumaan lahayn), sababtoo ah Min ayaa dooran doona kan yar ee labada doorasho.
  • Labada doorsoome lama sina 0: dooro qiimaha ugu yar.

Marka lagu beddelayo xaaladda qor_time && bedesho_waqtiga dhaqanku wuxuu u ekaan doonaa mid sax ah:

  • Hal ama labadaba doorsoomayaal lama sina 0: dooro qiime aan eber ahayn.
  • Labada doorsoome lama sina 0: dooro qiimaha ugu yar.

Jajab 2

V547 Had iyo jeer waa run. Malaha hawlwadeenka '&&' waa in halkan lagu isticmaalo. disk.c 1419

static RD_NTSTATUS
disk_device_control(RD_NTHANDLE handle, uint32 request, STREAM in,
      STREAM out)
{
  ....
  if (((request >> 16) != 20) || ((request >> 16) != 9))
    return RD_STATUS_INVALID_PARAMETER;
  ....
}

Sida muuqata hawl-wadeennadu sidoo kale way isku qasmeen halkan || ΠΈ &&, ama == ΠΈ !=Doorsoomuhu isku mar ma wada yeelan karaan qiimaha 20 iyo 9.

koobiyeynta khadka aan xadidnayn

V512 Wicista shaqada 'sprintf' waxay u horseedi doontaa buuxdhaafka kaydka 'fullpath'. disk.c 1257

RD_NTSTATUS
disk_query_directory(....)
{
  ....
  char *dirname, fullpath[PATH_MAX];
  ....
  /* Get information for directory entry */
  sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);
  ....
}

Markaad si buuxda u eegto shaqada, waxay kuu muuqan doontaa in koodhkani aanu dhibaato keenin. Si kastaba ha ahaatee, waxa laga yaabaa inay soo baxaan mustaqbalka: hal isbedel oo taxadar la'aan ah waxaanan heli doonaa qulqulka qulqulka - orod Waxba ma xaddido, markaa marka la isku xidho wadooyinku waxaynu ka gudbi karnaa xudduudaha isku xidhka. Waxaa lagu talinayaa in la dareemo wacitaankan snprintf (dariiqa buuxa, PATH_MAX, ….).

Xaalad aan badnayn

V560 Qayb ka mid ah tibaaxaha shuruudaysan had iyo jeer waa run: ku dar> 0. scard.c 507

static void
inRepos(STREAM in, unsigned int read)
{
  SERVER_DWORD add = 4 - read % 4;
  if (add < 4 && add > 0)
  {
    ....
  }
}

kormeerka ku dar > 0 ma jirto baahi halkan: doorsoomuhu had iyo jeer wuu ka weynaan doonaa eber, sababtoo ah akhri %4 wuxuu soo celin doonaa inta ka hartay qaybta, laakiin weligeed ma noqon doonto 4.

x

x - hirgelinta server-ka RDP oo leh koodka isha furan. Mashruucu wuxuu u qaybsan yahay 2 qaybood:

  • xrdp - hirgelinta nidaamka. Lagu qaybiyay shatiga Apache 2.0
  • xorgxrdp - Qayb ka mid ah darawallada Xorg ee loo isticmaalo xrdp. Shatiga - X11 (sida MIT, laakiin waxay mamnuucday isticmaalka xayeysiiska)

Horumarinta mashruucu waxay ku salaysan tahay natiijooyinka rdesktop iyo FreeRDP. Markii hore, si aad ula shaqeyso garaafyada, waa inaad isticmaashaa server VNC gaar ah, ama server X11 gaar ah oo leh taageerada RDP - X11rdp, laakiin markii ay soo baxday xorgxrdp, baahida loo qabo iyaga ayaa meesha ka baxday.

Maqaalkan kuma dabooli doono xorgxrdp.

Mashruuca xrdp, sida kii hore, aad buu u yar yahay wuxuuna ka kooban yahay qiyaastii 80 kun oo xariiq.

Hubinta rdesktop-ka iyo xrdp adigoo isticmaalaya PVS-Studio analyzer

Qoraalo badan

V525 Koodhku wuxuu ka kooban yahay ururinta baloogyada la midka ah. Ku hubi shayada 'r', 'g', 'r' ee sadarrada 87, 88, 89. rfxencode_rgb_to_yuv.c 87

static int
rfx_encode_format_rgb(const char *rgb_data, int width, int height,
                      int stride_bytes, int pixel_format,
                      uint8 *r_buf, uint8 *g_buf, uint8 *b_buf)
{
  ....
  switch (pixel_format)
  {
    case RFX_FORMAT_BGRA:
      ....
      while (x < 64)
      {
          *lr_buf++ = r;
          *lg_buf++ = g;
          *lb_buf++ = r; // <=
          x++;
      }
      ....
  }
  ....
}

Koodhkan waxa laga soo qaatay maktabadda librfxcodec, kaas oo fuliya codec jpeg2000 ee RemoteFX. Halkan, sida muuqata, kanaalada xogta garaafyada ayaa isku dhafan - halkii midab "buluug", "casaan" ayaa la duubay. Khaladkani wuxuu u badan yahay inuu u muuqday natiijada koobi-ku dhejinta.

Dhibaato isku mid ah ayaa ku dhacday shaqo la mid ah rfx_encode_format_argb, oo uu lafaguruhu noo sheegay:

V525 Koodhku wuxuu ka kooban yahay ururinta baloogyada la midka ah. Ku calaamadee shayada 'a', 'r', 'g', 'r' ee sadarrada 260, 261, 262, 263. rfxencode_rgb_to_yuv.c 260

while (x < 64)
{
    *la_buf++ = a;
    *lr_buf++ = r;
    *lg_buf++ = g;
    *lb_buf++ = r;
    x++;
}

Baaqa Array

V557 Array xad dhaaf ah waa suurtagal. Qiimaha 'i β€” 8' index wuxuu gaari karaa 129. genkeymap.c 142

// evdev-map.c
int xfree86_to_evdev[137-8+1] = {
  ....
};

// genkeymap.c
extern int xfree86_to_evdev[137-8];

int main(int argc, char **argv)
{
  ....
  for (i = 8; i <= 137; i++) /* Keycodes */
  {
    if (is_evdev)
        e.keycode = xfree86_to_evdev[i-8];
    ....
  }
  ....
}

Ku dhawaaqida iyo qeexida shaxanka labadan faylal waa kuwo aan isqaban karin - cabbirku wuxuu ku kala duwan yahay 1. Si kastaba ha ahaatee, wax qalad ah ma dhacaan - cabbirka saxda ah ayaa lagu qeexay faylka evdev-map.c, markaa ma jiro wax ka baxsan xadka. Markaa kani waa uun bug si fudud loo hagaajin karo.

Isbarbardhigga khaldan

V560 Qayb ka mid ah odhaah shuruudaysan had iyo jeer waa been: (cap_len <0). xrdp_caps.c 616

// common/parse.h
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define in_uint16_le(s, v) do 
....
#else
#define in_uint16_le(s, v) do 
{ 
    (v) = *((unsigned short*)((s)->p)); 
    (s)->p += 2; 
} while (0)
#endif

int
xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
{
  int cap_len;
  ....
  in_uint16_le(s, cap_len);
  ....
  if ((cap_len < 0) || (cap_len > 1024 * 1024))
  {
    ....
  }
  ....
}

Shaqadu waxay akhridaa doorsoome nooc ah saxeexan gaaban doorsoome sida INT. Hubinta halkan loogama baahna sababtoo ah waxaan akhrineynaa doorsoome aan saxiixin oo ku wareejineynaa natiijada doorsoome weyn, sidaas darteed doorsoomuhu ma qaadan karo qiime taban.

Jeegaga aan loo baahnayn

V560 Qayb ka mid ah tibaaxaha shuruudaysan had iyo jeer waa run: (bpp!= 16). libxrdp.c 704

int EXPORT_CC
libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
                     char *data, char *mask, int x, int y, int bpp)
{
  ....
  if ((bpp == 15) && (bpp != 16) && (bpp != 24) && (bpp != 32))
  {
      g_writeln("libxrdp_send_pointer: error");
      return 1;
  }
  ....
}

Jeegaga sinnaan la'aanta halkan macno ma samaynayso maadaama aan horeba u haysanay isbarbardhig bilowgii. Waxay u badan tahay in tani ay tahay wax qoris oo horumariyahu uu rabay inuu isticmaalo hawlwadeenka || si loo shaandheeyo doodaha aan sax ahayn.

gunaanad

Intii lagu guda jiray hanti-dhawrka, ma jiraan khaladaad halis ah oo la aqoonsaday, laakiin cillado badan ayaa la helay. Si kastaba ha ahaatee, naqshadahan waxaa loo isticmaalaa habab badan, inkastoo ay yar yihiin baaxadda. Mashruuc yar maaha in uu leeyahay khaladaad badan, markaa waa inaadan xukumin waxqabadka falanqeeyayaasha oo kaliya mashaariicda yaryar. Waxaad wax badan oo arrintan ku saabsan ka akhriyi kartaa maqaalka "Dareen lagu xaqiijiyay tirooyinΒ«.

Waxaad naga soo dejisan kartaa nooca tijaabada ah ee PVS-Studio goobta.

Hubinta rdesktop-ka iyo xrdp adigoo isticmaalaya PVS-Studio analyzer

Haddii aad rabto inaad maqaalkan la wadaagto dhagaystayaasha ku hadla Ingiriisiga, fadlan isticmaal xidhiidhka tarjumaadda: Sergey Larin. Ku hubinta rdesktop iyo xrdp PVS-Studio

Source: www.habr.com

Add a comment