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
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
rdesktop
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:
Kodeu teu bisa dihontal
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
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
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
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
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
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
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 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.
Langkung typo
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:
while (x < 64)
{
*la_buf++ = a;
*lr_buf++ = r;
*lg_buf++ = g;
*lb_buf++ = r;
x++;
}
Déklarasi Array
// 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
// 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
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 "
Anjeun tiasa ngundeur versi percobaan tina PVS-Studio ti kami
Upami anjeun hoyong ngabagikeun tulisan ieu ka pamiarsa anu nyarios basa Inggris, mangga nganggo tautan tarjamahan: Sergey Larin.
sumber: www.habr.com