Duba rdesktop da xrdp ta amfani da PVS-Studio analyzer

Duba rdesktop da xrdp ta amfani da PVS-Studio analyzer
Wannan shi ne bita na biyu a cikin jerin labarai game da gwada shirye-shiryen buɗe tushen don aiki tare da yarjejeniyar RDP. A ciki za mu kalli abokin ciniki na rdesktop da uwar garken xrdp.

Ana amfani dashi azaman kayan aiki don gano kurakurai PVS-Studio. Yana da na'urar tantance lambar a tsaye don C, C++, C # da harsunan Java, ana samun su akan dandamali na Windows, Linux da macOS.

Labarin yana gabatar da kurakuran da suka yi kama da ban sha'awa kawai. Duk da haka, ayyukan suna da ƙananan, don haka akwai ƙananan kurakurai :).

Примечание. Ana iya samun labarin da ya gabata game da tabbacin aikin FreeRDP a nan.

rdsktop

rdsktop - aiwatar da kyauta na abokin ciniki na RDP don tsarin tushen UNIX. Hakanan ana iya amfani dashi a ƙarƙashin Windows idan kun gina aikin a ƙarƙashin Cygwin. An yi lasisi ƙarƙashin GPLv3.

Wannan abokin ciniki ya shahara sosai - ana amfani da shi ta tsohuwa a cikin ReactOS, kuma kuna iya nemo masa ƙarshen zane na ɓangare na uku. Duk da haka, ya tsufa sosai: sakinsa na farko ya faru a ranar 4 ga Afrilu, 2001 - a lokacin rubutawa, yana da shekaru 17.

Kamar yadda na fada a baya, aikin kadan ne. Ya ƙunshi kusan layukan lamba dubu 30, wanda baƙon abu ne idan aka yi la'akari da shekarunsa. Don kwatanta, FreeRDP ya ƙunshi layin 320 dubu. Ga fitar da shirin Cloc:

Duba rdesktop da xrdp ta amfani da PVS-Studio analyzer

Lambar da ba za a iya kaiwa ba

V779 An gano lambar da ba ta samuwa. Yana yiwuwa kuskure ya kasance. 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);
}

Kuskuren ya ci karo da mu nan da nan a cikin aikin main: muna ganin lambar tana zuwa bayan mai aiki samu - wannan guntu yana yin tsabtace ƙwaƙwalwar ajiya. Duk da haka, kuskuren ba ya haifar da barazana: duk ƙwaƙwalwar ajiyar da aka keɓe za a share ta tsarin aiki bayan shirin ya fita.

Babu kurakurai kula

V557 Array underrun yana yiwuwa. Darajar 'n' index na iya kaiwa -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);
  }
  ....
}

Snippet lambar a cikin wannan yanayin yana karantawa daga fayil ɗin zuwa cikin majigi har sai fayil ɗin ya ƙare. Duk da haka, babu kurakurai a nan: idan wani abu ya yi kuskure, to karanta zai dawo -1, sa'an nan kuma tsararru za ta yi nasara Fitarwa.

Amfani da EOF a cikin nau'in char

V739 Bai kamata a kwatanta EOF da ƙimar nau'in 'char' ba. Ya kamata '(c = fgetc(fp))' ya kasance na nau'in '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++;
  }
  ....
}

Anan muna ganin kulawar da ba daidai ba ta kai ƙarshen fayil ɗin: idan fgetc ya dawo da haruffa wanda lambar sa 0xFF, za a fassara shi azaman ƙarshen fayil ɗin (EOF).

EOF akai akai, yawanci ana siffanta shi da -1. Alal misali, a cikin rikodin CP1251, harafin ƙarshe na haruffan Rasha yana da lambar 0xFF, wanda ya dace da lambar -1 idan muna magana ne game da m kamar haka. char. Ya bayyana cewa alamar 0xFF, kamar EOF (-1) ana fassara shi azaman ƙarshen fayil ɗin. Don kauce wa irin waɗannan kurakurai, sakamakon aikin shine fgetc ya kamata a adana a cikin m kamar int.

Typos

Juzu'i 1

V547 Maganar 'write_time' koyaushe karya ce. faifai.c805

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

Wataƙila marubucin wannan lambar ya sami kuskure || и && cikin yanayi. Bari mu yi la'akari da yiwuwar zaɓuɓɓuka don ƙima rubuta_lokaci и canza_lokaci:

  • Dukansu masu canji suna daidai da 0: a wannan yanayin za mu ƙare a cikin reshe wani: m mod_lokaci koyaushe zai kasance 0 ba tare da la'akari da yanayin da ya biyo baya ba.
  • Ɗaya daga cikin masu canji shine 0: mod_lokaci zai kasance daidai da 0 (idan har sauran ma'auni yana da ƙimar mara kyau), saboda MIN zai zaɓi ƙaramin zaɓin biyun.
  • Dukansu masu canji ba su daidaita da 0: zaɓi mafi ƙarancin ƙima.

Lokacin maye gurbin yanayin da rubuta_lokaci && canza_lokaci halin zai yi kyau:

  • Daya ko duka biyu masu canji ba su daidaita da 0: zaɓi ƙimar da ba sifili ba.
  • Dukansu masu canji ba su daidaita da 0: zaɓi mafi ƙarancin ƙima.

Juzu'i 2

V547 Magana koyaushe gaskiya ce. Wataƙila yakamata a yi amfani da afaretan '&&' anan. faifai.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;
  ....
}

Da alama masu aiki sun gauraya anan ma || и &&, ko == и !=: Mai canzawa ba zai iya samun darajar 20 da 9 a lokaci guda ba.

Kwafin layi mara iyaka

V512 Kiran aikin 'sprintf' zai haifar da cikar buffer 'fullpath'. faifai.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);
  ....
}

Lokacin da kuka kalli aikin gabaɗaya, zai bayyana cewa wannan lambar ba ta haifar da matsala ba. Koyaya, suna iya tashi a nan gaba: canjin rashin kulawa kuma za mu sami buffer ambaliya - gudu ba a iyakance shi da komai ba, don haka lokacin da ake haɗa hanyoyin za mu iya wuce iyakokin tsararru. Ana ba da shawarar a lura da wannan kiran snprintf (cikakken hanya, PATH_MAX,….).

M yanayi

V560 Wani ɓangare na maganganun sharadi koyaushe gaskiya ne: ƙara> 0. scard.c 507

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

dubawa add > 0 babu buƙata a nan: mai canzawa koyaushe zai kasance mafi girma fiye da sifili, saboda karatu% 4 zai dawo da ragowar rabon, amma ba zai taba zama 4 ba.

xrdp

xrdp - aiwatar da sabar RDP tare da buɗaɗɗen lambar tushe. Aikin ya kasu kashi 2:

  • xrdp - aiwatar da yarjejeniya. An rarraba ƙarƙashin lasisin Apache 2.0.
  • xorgxrdp - Saitin direbobin Xorg don amfani tare da xrdp. Lasisi - X11 (kamar MIT, amma ya hana amfani da talla)

Ci gaban aikin ya dogara ne akan sakamakon rdesktop da FreeRDP. Da farko, don yin aiki tare da zane-zane, dole ne ku yi amfani da uwar garken VNC daban, ko sabar X11 ta musamman tare da tallafin RDP - X11rdp, amma tare da zuwan xorgxrdp, buƙatar su ta ɓace.

A cikin wannan labarin ba za mu rufe xorgxrdp ba.

Aikin xrdp, kamar na baya, ƙanƙanta ne kuma ya ƙunshi kusan layuka dubu 80.

Duba rdesktop da xrdp ta amfani da PVS-Studio analyzer

Ƙarin typos

V525 Lambar tana ƙunshe da tarin tubalan iri ɗaya. Duba abubuwa 'r', 'g', 'r' a cikin layi 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++;
      }
      ....
  }
  ....
}

An ɗauki wannan lambar daga ɗakin karatu na librfxcodec, wanda ke aiwatar da codec jpeg2000 don RemoteFX. Anan, a fili, tashoshi bayanan hoto sun haɗu - maimakon "blue" launi, an rubuta "ja". Yiwuwar wannan kuskuren ya bayyana sakamakon kwafin-manna.

Matsalar iri ɗaya ta faru a cikin aiki iri ɗaya rfx_encode_format_argb, wanda mai sharhin kuma ya gaya mana:

V525 Lambar tana ƙunshe da tarin tubalan iri ɗaya. Duba abubuwa 'a', 'r', 'g', 'r' a cikin layi 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++;
}

Sanarwa Tsari

V557 Tsari overrun yana yiwuwa. Darajar 'i - 8' index na iya kaiwa 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];
    ....
  }
  ....
}

Bayanin da ma'anar tsararru a cikin waɗannan fayiloli guda biyu ba su dace ba - girman ya bambanta da 1. Duk da haka, babu kurakurai da ke faruwa - an ƙayyade girman daidai a cikin fayil ɗin evdev-map.c, don haka babu wata iyaka. Don haka wannan kwaro ne kawai wanda za'a iya gyarawa cikin sauƙi.

Kwatancen da ba daidai ba

V560 Wani ɓangare na maganganun sharadi koyaushe ƙarya ne: (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))
  {
    ....
  }
  ....
}

Aikin yana karanta nau'in m gajere mara sa hannu a cikin wani m kamar int. Ba a buƙatar dubawa a nan saboda muna karanta mabambantan da ba a sanya hannu ba kuma muna sanya sakamakon zuwa babban canji, don haka mai canjin ba zai iya ɗaukar ƙima mara kyau ba.

Binciken da ba dole ba

V560 Wani sashe na yanayin magana koyaushe gaskiya ne: (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;
  }
  ....
}

Binciken rashin daidaituwa ba shi da ma'ana a nan tunda mun riga mun sami kwatance a farkon. Wataƙila wannan typo ne kuma mai haɓakawa ya so ya yi amfani da afaretan || don tace gardama mara inganci.

ƙarshe

A lokacin tantancewar, ba a gano manyan kurakurai ba, amma an samu gazawa da yawa. Duk da haka, ana amfani da waɗannan zane-zane a cikin tsarin da yawa, ko da yake ƙananan iyaka. Ƙananan aikin ba lallai ba ne yana da kurakurai da yawa, don haka bai kamata ku yi la'akari da aikin mai nazari ba kawai akan ƙananan ayyuka. Kuna iya karanta ƙarin game da wannan a cikin labarin "Abubuwan da aka tabbatar da lambobi".

Kuna iya sauke nau'in gwaji na PVS-Studio daga gare mu shafin.

Duba rdesktop da xrdp ta amfani da PVS-Studio analyzer

Idan kuna son raba wannan labarin tare da masu sauraron Ingilishi, da fatan za a yi amfani da hanyar fassarar: Sergey Larin. Duba rdesktop da xrdp tare da PVS-Studio

source: www.habr.com

Add a comment