Mariksa rdesktop sareng xrdp nganggo analisa PVS-Studio

Mariksa rdesktop sareng xrdp nganggo analisa PVS-Studio
Ieu ulasan kadua dina runtuyan artikel ngeunaan nguji program open source pikeun gawé bareng protokol RDP. Di jerona urang bakal ningali klien rdesktop sareng server xrdp.

Dipaké salaku alat pikeun ngaidentipikasi kasalahan PVS Studio. Éta mangrupikeun analisa kode statik pikeun basa C, C ++, C # sareng Java, sayogi dina platform Windows, Linux sareng macOS.

Tulisan éta ngan ukur nunjukkeun kasalahan anu sigana pikaresepeun pikeun kuring. Sanajan kitu, proyék-proyék leutik, jadi aya sababaraha kasalahan :).

nyarios. Artikel saméméhna ngeunaan verifikasi proyék FreeRDP tiasa dipendakan di dieu.

rdesktop

rdesktop - palaksanaan gratis klien RDP pikeun sistem basis UNIX. Éta ogé tiasa dianggo dina Windows upami anjeun ngawangun proyék dina Cygwin. Dilisensikeun dina GPLv3.

Klién ieu kasohor pisan - dianggo sacara standar di ReactOS, sareng anjeun ogé tiasa mendakan tungtung hareup grafis pihak katilu pikeun éta. Sanajan kitu, anjeunna geus rada heubeul: release kahijina lumangsung April 4, 2001 - dina waktu tulisan, anjeunna 17 taun.

Salaku I nyatet saméméhna, proyék ieu rada leutik. Ieu ngandung kira 30 sarébu garis kode, nu rada aneh tempo umur na. Pikeun babandingan, FreeRDP ngandung 320 rébu garis. Ieu kaluaran program Cloc:

Mariksa rdesktop sareng xrdp nganggo analisa PVS-Studio

Kodeu teu bisa dihontal

V779 Kodeu teu sadia dideteksi. Ieu mungkin yen aya kasalahan. rdesktop.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);
}

Kasalahan encounters kami langsung dina fungsi utama: urang tingali kode datang sanggeus operator kasumpingan - sempalan ieu ngalakukeun beberesih memori. Nanging, kasalahan éta henteu janten ancaman: sadaya mémori anu dialokasikeun bakal dibersihkeun ku sistem operasi saatos program kaluar.

Taya penanganan kasalahan

V557 Array underrun mungkin. Nilai indéks 'n' bisa ngahontal -1. rdesktop.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);
  }
  ....
}

Snippet kode dina hal ieu maca tina file kana panyangga nepi ka file réngsé. Nanging, teu aya kasalahan anu nanganan di dieu: upami aya anu salah, teras maca bakal balik -1, lajeng Asép Sunandar Sunarya bakal overrun hasil.

Ngagunakeun EOF dina tipe char

V739 EOF henteu kedah dibandingkeun sareng nilai tina jinis 'char'. '(c = fgetc(fp))' kedah tina tipe '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++;
  }
  ....
}

Di dieu urang ningali penanganan anu salah pikeun ngahontal tungtung file: upami fgetc ngabalikeun karakter anu kodena 0xFF, éta bakal diinterpretasi salaku tungtung file (EOF).

EOF eta mangrupakeun konstanta, biasana dihartikeun salaku -1. Salaku conto, dina encoding CP1251, hurup terakhir tina alfabét Rusia ngagaduhan kode 0xFF, anu pakait sareng nomer -1 upami urang nyarioskeun variabel sapertos. char. Tétéla éta simbol 0xFF, siga EOF (-1) diinterpretasi salaku tungtung file. Pikeun ngahindarkeun kasalahan sapertos kitu, hasil tina fungsina nyaéta fgetc kudu disimpen dina variabel kawas int.

Typos

Bagéan 1

V547 Babasan 'write_time' sok palsu. 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; // <=
  ....
}

Panginten panulis kode ieu salah || и && dina kaayaan. Hayu urang nganggap pilihan mungkin pikeun nilai write_time и robah_waktu:

  • Duanana variabel sarua jeung 0: dina hal ieu urang bakal mungkas nepi di cabang lamun henteu: variabel mod_time bakal salawasna jadi 0 paduli kaayaan saterusna.
  • Salah sahiji variabel nyaéta 0: mod_time bakal sarua jeung 0 (disadiakeun yén variabel séjén boga nilai non-négatip), sabab mnt bakal milih nu leuwih leutik tina dua pilihan.
  • Duanana variabel henteu sarua jeung 0: milih nilai minimum.

Nalika ngaganti kaayaan kalawan write_time && change_time kabiasaan bakal kasampak bener:

  • Hiji atawa duanana variabel teu sarua jeung 0: milih hiji nilai non-enol.
  • Duanana variabel henteu sarua jeung 0: milih nilai minimum.

Bagéan 2

V547 Ekspresi salawasna leres. Panginten operator '&&' kedah dianggo di dieu. 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;
  ....
}

Tétéla operator ogé dicampur di dieu || и &&atawa == и !=: A variabel teu bisa boga nilai 20 jeung 9 dina waktos anu sareng.

Nyalin garis Unlimited

V512 Sauran fungsi 'sprintf' bakal nyababkeun limpahan panyangga '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);
  ....
}

Lamun anjeun nempo fungsi dina pinuh, eta bakal jadi jelas yén kode ieu teu ngabalukarkeun masalah. Nanging, aranjeunna tiasa timbul di hareup: hiji parobihan anu teu sopan sareng urang bakal nampi panyangga - ngutruk teu diwatesan ku nanaon, jadi lamun concatenating jalur urang bisa balik saluareun wates of Asép Sunandar Sunarya dina. Disarankeun perhatikeun panggero ieu dina snprintf(fullpath, PATH_MAX, ….).

kaayaan kaleuleuwihan

V560 Bagian tina ekspresi kondisional salawasna leres: tambahkeun > 0. scard.c 507

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

pamariksaan tambahkeun > 0 aya teu kudu dieu: variabel bakal salawasna leuwih gede ti enol, sabab maca% 4 bakal ngabalikeun sésa divisi, tapi moal pernah sami sareng 4.

xrdp

xrdp - palaksanaan hiji server RDP kalawan kode open source. Proyék dibagi jadi 2 bagian:

  • xrdp - palaksanaan protokol. Disebarkeun dina lisénsi Apache 2.0.
  • xorgxrdp - Sakumpulan supir Xorg pikeun dianggo sareng xrdp. Lisensi - X11 (sapertos MIT, tapi ngalarang dianggo dina pariwara)

Ngembangkeun proyék dumasar kana hasil rdesktop sareng FreeRDP. Mimitina, pikeun digawe sareng grafik, anjeun kedah nganggo server VNC anu misah, atanapi server X11 khusus kalayan dukungan RDP - X11rdp, tapi ku ayana xorgxrdp, kabutuhan pikeun aranjeunna ngaleungit.

Dina artikel ieu kami moal nutupan xorgxrdp.

Proyék xrdp, sapertos anu sateuacana, alit pisan sareng ngandung kirang langkung 80 rébu garis.

Mariksa rdesktop sareng xrdp nganggo analisa PVS-Studio

Langkung typo

V525 Kode ngandung kumpulan blok sarupa. Pariksa item 'r', 'g', 'r' dina baris 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++;
      }
      ....
  }
  ....
}

Kode ieu dicandak tina perpustakaan librfxcodec, anu ngalaksanakeun codec jpeg2000 pikeun RemoteFX. Di dieu, katingalina, saluran data grafis dicampurkeun - tibatan warna "biru", "beureum" dirékam. Kasalahan ieu paling dipikaresep muncul salaku hasil tina salinan-témpél.

Masalah anu sami lumangsung dina fungsi anu sami rfx_encode_format_argb, anu ceuk analis ogé ka kami:

V525 Kode ngandung kumpulan blok sarupa. Pariksa item 'a', 'r', 'g', 'r' dina baris 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++;
}

Déklarasi Array

V557 Array overrun mungkin. Nilai indéks 'i — 8' bisa ngahontal 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];
    ....
  }
  ....
}

Deklarasi jeung harti Asép Sunandar Sunarya dina dua file ieu sauyunan - ukuranana béda 1. Sanajan kitu, euweuh kasalahan lumangsung - ukuran bener dieusian dina file evdev-map.c, jadi euweuh kaluar wates. Janten ieu ngan ukur kutu anu gampang dibenerkeun.

Bandingan anu salah

V560 Bagian tina éksprési kondisional sok palsu: (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))
  {
    ....
  }
  ....
}

Fungsi maca variabel tipe unsigned pondok kana variabel kawas int. Mariksa henteu diperlukeun di dieu sabab urang maca variabel unsigned sarta assigning hasilna ka variabel nu leuwih gede, jadi variabel teu bisa nyandak hiji nilai négatip.

cék nu teu perlu

V560 Bagian tina éksprési kondisional salawasna leres: (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;
  }
  ....
}

Cék kateusaruaan henteu asup akal di dieu sabab urang parantos gaduh perbandingan ti mimiti. Éta kamungkinan yén ieu mangrupikeun typo sareng pamekar hoyong nganggo operator || pikeun nyaring argumen anu teu valid.

kacindekan

Salila Inok, euweuh kasalahan serius anu dicirikeun, tapi loba shortcomings kapanggih. Sanajan kitu, desain ieu dipaké dina loba sistem, sanajan leutik dina lingkup. Proyék leutik teu kudu loba kasalahan, jadi Anjeun teu kudu nangtoskeun kinerja analis ukur dina proyék leutik. Anjeun tiasa maca langkung seueur ngeunaan ieu dina tulisan "Rarasaan anu dikonfirmasi ku angka".

Anjeun tiasa ngundeur versi percobaan tina PVS-Studio ti kami website.

Mariksa rdesktop sareng xrdp nganggo analisa PVS-Studio

Upami anjeun hoyong ngabagikeun tulisan ieu ka pamiarsa anu nyarios basa Inggris, mangga nganggo tautan tarjamahan: Sergey Larin. Mariksa rdesktop na xrdp kalawan PVS-Studio

sumber: www.habr.com

Tambahkeun komentar