Fanamarinana rdesktop sy xrdp amin'ny fampiasana ny analyser PVS-Studio

Fanamarinana ny rdesktop sy xrdp amin'ny fampiasana ny analyser PVS-Studio
Ity no famerenana faharoa amin'ny andian-dahatsoratra momba ny fitsapana ny programa open source amin'ny fiaraha-miasa amin'ny protocol RDP. Ao anatin'izany isika dia hijery ny mpanjifa rdesktop sy ny mpizara xrdp.

Ampiasaina ho fitaovana hamantarana lesoka PVS StudioMpandinika kaody statika ho an'ny C, C++, C# ary Java izy io, azo alaina amin'ny sehatra maro. Windows, Linux и macOS.

Ireo fahadisoana izay toa nahaliana ahy ihany no asehon’ilay lahatsoratra. Na izany aza, kely ny tetikasa, ka vitsy ny lesoka :).

fanamarihana. Ny lahatsoratra teo aloha momba ny fanamarinana ny tetikasa FreeRDP dia azo jerena eto.

rdesktop

rdesktop — свободная реализация клиента RDP для UNIX-based систем. Его также можно использовать и под Windows, если собирать проект под Cygwin. Лицензирован под GPLv3.

Tena malaza ity mpanjifa ity - ampiasaina amin'ny alàlan'ny default ao amin'ny ReactOS izy io, ary azonao atao ihany koa ny mahita ireo endri-tsarimihetsika fahatelo ho azy. Efa antitra ihany anefa izy: tamin'ny 4 Aprily 2001 no navoakany voalohany - 17 taona izy tamin'ny fotoana nanoratana.

Araka ny nomarihiko teo aloha dia kely ny tetikasa. Misy tsipika 30 arivo eo ho eo izy io, izay somary hafahafa ihany raha jerena ny taonany. Raha ampitahaina dia misy andalana 320 arivo ny FreeRDP. Ity ny vokatry ny programa Cloc:

Fanamarinana ny rdesktop sy xrdp amin'ny fampiasana ny analyser PVS-Studio

Kaody tsy azo tratrarina

V779 Kaody tsy misy hita. Mety misy hadisoana. 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);
}

Ny fahadisoana dia mihaona amintsika avy hatrany ao amin'ny asa tena: hitantsika ny kaody manaraka ny opérateur hiverina - ity sombiny ity dia manao fanadiovana fahatsiarovana. Na izany aza, ny hadisoana dia tsy mampidi-doza: ny fitadidiana natokana rehetra dia hofafan'ny rafitra fiasana rehefa mivoaka ny programa.

Tsy misy fiatrehana fahadisoana

V557 Array underrun dia azo atao. Ny sandan'ny tondro 'n' dia mety hahatratra -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);
  }
  ....
}

Ny snippet kaody amin'ity tranga ity dia mamaky avy amin'ny rakitra ho buffer mandra-pahatapitry ny rakitra. Na izany aza, tsy misy ny fampandehanana ny fahadisoana eto: raha misy zavatra tsy mety, dia vakio ny dia hiverina -1, ary avy eo dia hihoatra ny array fivoahana.

Mampiasa EOF amin'ny karazana char

V739 Ny EOF dia tsy tokony ampitahaina amin'ny sandan'ny karazana 'char'. Ny '(c = fgetc(fp))' dia tokony ho karazana '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++;
  }
  ....
}

Hitantsika eto ny fikarakarana tsy mety amin'ny fahatongavana amin'ny faran'ny rakitra: if fgetc mamerina toetra iray misy kaody 0xFF, hadika ho toy ny faran'ny rakitra (EOF).

EOF tsy miova izy io, matetika no faritana ho -1. Ohatra, ao amin'ny CP1251 encoding, ny litera farany amin'ny abidy Rosiana dia manana ny fehezan-dalàna 0xFF, izay mifanitsy amin'ny isa -1 raha miresaka momba ny miovaova toy ny Char. Hita fa ny marika 0xFF, toy ny EOF (-1) dia adika ho fiafaran'ny rakitra. Mba hisorohana ny fahadisoana toy izany, ny vokatry ny asa dia fgetc dia tokony hotehirizina ao amin'ny miovaova toy ny int.

Typos

Sombiny 1

V547 Diso foana ny teny hoe 'write_time'. 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; // <=
  ....
}

Angamba diso ny mpanoratra an'ity code ity || и && en condition. Andeha hojerentsika ny safidy mety ho an'ny soatoavina manoratra_fotoana и change_time:

  • Samy mitovy amin'ny 0 ny variables roa: amin'ity tranga ity dia hiafara amin'ny sampana isika hafa: miovaova mod_time dia ho 0 foana na inona na inona toe-javatra manaraka.
  • Ny iray amin'ireo variables dia 0: mod_time dia hitovy amin'ny 0 (raha toa ka manana sanda tsy miiba ny fari-piainana hafa), satria MIN hifidy ny kely kokoa amin'ireo safidy roa.
  • Tsy mitovy amin'ny 0 ny fari-piainana roa: safidio ny sanda kely indrindra.

Rehefa soloina ny fepetra amin'ny write_time && change_time ny fitondran-tena dia ho hita ho marina:

  • Tsy mitovy amin'ny 0 ny variables iray na roa: misafidy sanda tsy aotra.
  • Tsy mitovy amin'ny 0 ny fari-piainana roa: safidio ny sanda kely indrindra.

Sombiny 2

V547 Marina foana ny fanehoan-kevitra. Angamba ny mpandraharaha '&&' no tokony hampiasaina eto. 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;
  ....
}

Hita fa mifangaroharo koa ny mpandraharaha eto || и &&, na == и !=: Tsy afaka manana sanda 20 sy 9 miaraka ny fari-piainana iray.

Fandikana tsipika tsy misy fetra

V512 Ny fiantsoana ny asa 'sprintf' dia hitarika ny fihoaran'ny 'fullpath' buffer. 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);
  ....
}

Rehefa mijery ny asa feno ianao dia ho hita fa tsy miteraka olana ity code ity. Na izany aza, mety hipoitra amin'ny ho avy izy ireo: fiovana iray tsy mitandrina ary hahazo fihoaram-pefy isika - sprint dia tsy voafetran'ny na inona na inona, ka rehefa mampifandray lalana dia afaka mihoatra ny sisin'ny array. Tsara ny manamarika ity antso ity snprintf(fullpath, PATH_MAX, ….).

Fepetra miverimberina

V560 Marina foana ny ampahany amin'ny fehezanteny misy fepetra: ampio > 0. scard.c 507

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

fanaraha-maso ampio > 0 tsy ilaina eto: ho lehibe noho ny aotra foana ny fari-piainana, satria mamaky % 4 dia hamerina ny ambiny amin'ny fizarana, fa tsy hitovy amin'ny 4 mihitsy.

xrdp

xrdp - fampiharana ny mpizara RDP misy kaody loharano misokatra. Mizara roa ny tetikasa:

  • xrdp - fampiharana protocol. Nozaraina teo ambanin'ny lisansa Apache 2.0.
  • xorgxrdp - Sehatra mpamily Xorg ampiasaina amin'ny xrdp. License - X11 (toa ny MIT, fa mandrara ny fampiasana amin'ny dokam-barotra)

Ny fampandrosoana ny tetikasa dia mifototra amin'ny vokatry ny rdesktop sy FreeRDP. Tamin'ny voalohany, mba hiasa amin'ny sary dia tsy maintsy mampiasa mpizara VNC misaraka ianao, na mpizara X11 manokana miaraka amin'ny fanohanan'ny RDP - X11rdp, saingy tamin'ny fahatongavan'ny xorgxrdp dia nanjavona ny filana azy ireo.

Amin'ity lahatsoratra ity dia tsy hiresaka momba ny xorgxrdp izahay.

Ny tetikasa xrdp, toy ny teo aloha, dia tena kely ary misy andalana 80 arivo eo ho eo.

Fanamarinana ny rdesktop sy xrdp amin'ny fampiasana ny analyser PVS-Studio

Misy typos bebe kokoa

V525 Ny kaody dia misy fanangonana sakana mitovy. Jereo ny singa 'r', 'g', 'r' amin'ny andalana 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++;
      }
      ....
  }
  ....
}

Ity kaody ity dia nalaina tao amin'ny tranomboky librfxcodec, izay mametraka ny codec jpeg2000 ho an'ny RemoteFX. Eto, toa mifangaro ny fantsona angon-drakitra an-tsary - fa tsy ny loko "manga", "mena" no voarakitra. Ity hadisoana ity dia azo inoana fa vokatry ny kopia-mametaka.

Nitranga ny olana mitovy amin'izany rfx_encode_format_argb, izay nolazain'ilay mpanadihady taminay koa hoe:

V525 Ny kaody dia misy fanangonana sakana mitovy. Jereo ny singa 'a', 'r', 'g', 'r' amin'ny andalana 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++;
}

Fanambarana Array

V557 Ny fihoaran'ny array dia azo atao. Ny sandan'ny tondro 'i — 8' dia mety hahatratra 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];
    ....
  }
  ....
}

Ny fanambarana sy ny famaritana ny array ao amin'ireo rakitra roa ireo dia tsy mifanaraka - ny habeny dia tsy mitovy amin'ny 1. Na izany aza, tsy misy hadisoana mitranga - ny habe marina dia voafaritra ao amin'ny rakitra evdev-map.c, noho izany dia tsy misy fetra. Noho izany dia bug izay azo amboarina mora foana.

Fampitahana diso

V560 Diso foana ny ampahany amin'ny fehezanteny misy fepetra: (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))
  {
    ....
  }
  ....
}

Ny fiasa dia mamaky fari-pitsipika iray unsigned fohy amin'ny variable toy int. Tsy ilaina ny fanamarinana eto satria mamaky faribolana tsy misy sonia isika ary manendry ny valiny amin'ny fari-piainana lehibe kokoa, noho izany dia tsy afaka maka sanda miiba ny variable.

Fanamarinana tsy ilaina

V560 Marina foana ny ampahany amin'ny fehezanteny misy fepetra: (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;
  }
  ....
}

Tsy misy dikany ny fisavana ny tsy fitoviana eto satria efa misy fampitahana isika tany am-boalohany. Azo inoana fa diso izany ary naniry ny hampiasa ilay mpandraharaha ny mpamorona || hanivana hevitra tsy mety.

famaranana

Nandritra ny fanaraha-maso dia tsy nisy lesoka lehibe hita fa maro ny lesoka hita. Na izany aza, ireo endrika ireo dia ampiasaina amin'ny rafitra maro, na dia kely aza ny sehatra. Ny tetikasa kely dia tsy voatery manana hadisoana maro, noho izany dia tsy tokony hitsara ny fahombiazan'ny mpandinika afa-tsy amin'ny tetikasa kely ianao. Afaka mamaky bebe kokoa momba izany ianao ao amin'ny lahatsoratra "Ny fahatsapana izay nohamafisin'ny isa".

Azonao atao ny misintona dikan-teny fitsapana an'ny PVS-Studio avy aminay tranonkala.

Fanamarinana ny rdesktop sy xrdp amin'ny fampiasana ny analyser PVS-Studio

Raha te hizara ity lahatsoratra ity amin'ny mpihaino miteny anglisy ianao dia ampiasao ny rohy fandikana: Sergey Larin. Fanamarinana rdesktop sy xrdp amin'ny PVS-Studio

Source: www.habr.com

Mividiana fampiantranoana azo antoka ho an'ny tranokala misy fiarovana DDoS, mpizara VPS VDS 🔥 Mividiana fampiantranoana tranonkala azo antoka miaraka amin'ny fiarovana DDoS, mpizara VPS VDS | ProHoster