Kini ang ikaduha nga pagrepaso sa serye sa mga artikulo bahin sa pagsulay sa mga open source nga programa alang sa pagtrabaho kauban ang RDP protocol. Diha niini atong tan-awon ang rdesktop client ug ang xrdp server.
Gigamit isip himan sa pag-ila sa mga sayop
Ang artikulo nagpresentar lamang sa mga sayop nga morag makapainteres kanako. Bisan pa, ang mga proyekto gamay ra, mao nga gamay ra ang mga sayup :).
Примечание. Ang miaging artikulo bahin sa pag-verify sa proyekto sa FreeRDP makit-an
rdesktop
Kini nga kliyente sikat kaayo - gigamit kini nga default sa ReactOS, ug mahimo ka usab nga makit-an ang mga third-party nga graphical front-end para niini. Bisan pa, medyo tigulang na siya: ang una niyang pagpagawas nahitabo kaniadtong Abril 4, 2001 - sa panahon sa pagsulat, siya 17 anyos.
Sama sa akong namatikdan sa sayo pa, ang proyekto gamay ra kaayo. Naglangkob kini sa gibana-bana nga 30 ka libo nga linya sa code, nga medyo katingad-an kung gikonsiderar ang edad niini. Alang sa pagtandi, ang FreeRDP adunay 320 ka libo nga linya. Ania ang output sa programa sa Cloc:
Dili maabot nga code
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);
}
Ang kasaypanan makit-an dayon kanamo sa function nag-unang: atong makita ang code nga moabut human sa operator pagbalik - kini nga tipik naghimo sa paglimpyo sa memorya. Bisan pa, ang sayup wala maghatag usa ka hulga: ang tanan nga gigahin nga panumduman malimpyohan sa operating system pagkahuman sa paggawas sa programa.
Walay sayop nga pagdumala
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);
}
....
}
Ang snippet sa code niini nga kaso mabasa gikan sa file ngadto sa usa ka buffer hangtod matapos ang file. Bisan pa, wala’y sayup nga pagdumala dinhi: kung adunay sayup, nan basaha mobalik -1, ug unya ang laray ma-overrun Output.
Gigamit ang EOF sa tipo sa 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++;
}
....
}
Dinhi atong makita ang sayop nga pagdumala sa pagkab-ot sa katapusan sa file: kung fgetc nagbalik sa usa ka karakter kansang code mao ang 0xFF, kini hubaron ingon nga katapusan sa file (EOF).
EOF kini usa ka makanunayon, kasagaran gihubit nga -1. Pananglitan, sa pag-encode sa CP1251, ang katapusan nga letra sa alpabetong Ruso adunay code 0xFF, nga katumbas sa numero -1 kung naghisgot kami bahin sa usa ka variable sama sa. char. Kini nahimo nga ang simbolo 0xFF, sama sa EOF (-1) gihubad ingon nga katapusan sa file. Aron malikayan ang ingon nga mga sayup, ang sangputanan sa function mao fgetc kinahanglan nga tipigan sa usa ka variable sama sa int.
Mga typo
Tipik 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; // <=
....
}
Tingali ang tagsulat niini nga code nasayop || и && sa kondisyon. Atong tagdon ang posible nga mga kapilian alang sa mga mithi pagsulat_panahon и kausaban_panahon:
- Ang duha nga mga variable parehas sa 0: sa kini nga kaso kita matapos sa usa ka sanga lain: variable mod_panahon kanunay nga 0 bisan unsa pa ang sunod nga kondisyon.
- Usa sa mga variable mao ang 0: mod_panahon mahimong katumbas sa 0 (basta ang lain nga variable adunay dili negatibo nga kantidad), tungod kay min mopili sa mas gamay sa duha ka mga kapilian.
- Ang duha ka mga variable dili parehas sa 0: pilia ang minimum nga kantidad.
Kung gipulihan ang kondisyon sa write_time && change_time ang pamatasan tan-awon nga husto:
- Ang usa o pareho nga mga variable dili katumbas sa 0: pagpili og dili zero nga kantidad.
- Ang duha ka mga variable dili parehas sa 0: pilia ang minimum nga kantidad.
Tipik 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;
....
}
Dayag nga ang mga operator nagsagol usab dinhi || и &&, o == и !=: Ang usa ka variable dili mahimong adunay kantidad nga 20 ug 9 sa parehas nga oras.
Walay kinutuban nga pagkopya sa linya
RD_NTSTATUS
disk_query_directory(....)
{
....
char *dirname, fullpath[PATH_MAX];
....
/* Get information for directory entry */
sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);
....
}
Kung imong tan-awon ang function sa bug-os, mahimong klaro nga kini nga code dili hinungdan sa mga problema. Bisan pa, mahimo silang motungha sa umaabot: usa ka walay pagtagad nga pagbag-o ug makakuha kami usa ka buffer overflow - sprint dili limitado sa bisan unsang butang, mao nga kung maghiusa ang mga agianan mahimo naton nga lapas sa mga utlanan sa laray. Kini girekomendar sa pagmatikod niini nga tawag sa snprintf(fullpath, PATH_MAX, ….).
Kabus nga kahimtang
static void
inRepos(STREAM in, unsigned int read)
{
SERVER_DWORD add = 4 - read % 4;
if (add < 4 && add > 0)
{
....
}
}
inspection idugang > 0 wala'y kinahanglan dinhi: ang variable kanunay nga labaw sa zero, tungod kay pagbasa% 4 ibalik ang nahabilin sa dibisyon, apan dili gyud kini katumbas sa 4.
xrdp
- xrdp - pagpatuman sa protocol. Giapod-apod ubos sa Apache 2.0 nga lisensya.
- xorgxrdp - Usa ka hugpong sa mga drayber sa Xorg nga gamiton sa xrdp. Lisensya - X11 (sama sa MIT, apan gidili ang paggamit sa advertising)
Ang pagpalambo sa proyekto gibase sa mga resulta sa rdesktop ug FreeRDP. Sa sinugdan, aron magtrabaho uban ang mga graphic, kinahanglan nimo nga gamiton ang usa ka bulag nga VNC server, o usa ka espesyal nga X11 server nga adunay suporta sa RDP - X11rdp, apan sa pag-abut sa xorgxrdp, ang panginahanglan alang kanila nawala.
Niini nga artikulo dili nato hisgotan ang xorgxrdp.
Ang proyekto sa xrdp, sama sa nauna, gamay kaayo ug adunay gibana-bana nga 80 ka libo nga linya.
Dugang 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++;
}
....
}
....
}
Kini nga code gikuha gikan sa librfxcodec library, nga nagpatuman sa jpeg2000 codec para sa RemoteFX. Dinhi, dayag, ang mga graphic data channel gisagol - imbes nga "asul" nga kolor, "pula" ang natala. Kini nga sayup lagmit nga nagpakita ingon usa ka sangputanan sa pagkopya-paste.
Ang parehas nga problema nahitabo sa parehas nga function rfx_encode_format_argb, nga gisulti usab kanamo sa analisador:
while (x < 64)
{
*la_buf++ = a;
*lr_buf++ = r;
*lg_buf++ = g;
*lb_buf++ = r;
x++;
}
Deklarasyon sa 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];
....
}
....
}
Ang deklarasyon ug kahulugan sa laray niining duha ka mga file dili magkauyon - ang gidak-on lahi sa 1. Apan, walay mga sayup nga mahitabo - ang husto nga gidak-on gipiho sa evdev-map.c file, mao nga walay out of bounds. Mao nga kini usa lamang ka bug nga dali ra masulbad.
Sayop nga pagtandi
// 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))
{
....
}
....
}
Ang function nagbasa sa usa ka variable nga tipo unsigned mubu ngadto sa usa ka variable sama sa int. Dili kinahanglan ang pagsusi dinhi tungod kay nagbasa kami usa ka wala gipirmahan nga variable ug gi-assign ang resulta sa usa ka mas dako nga variable, mao nga ang variable dili makakuha usa ka negatibo nga kantidad.
Wala kinahanglana nga mga pagsusi
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;
}
....
}
Ang mga pagsusi sa inequality dili makatarunganon dinhi tungod kay aduna na kitay pagtandi sa sinugdanan. Kini lagmit nga kini usa ka typo ug gusto sa developer nga gamiton ang operator || sa pagsala sa dili balido nga mga argumento.
konklusyon
Atol sa pag-audit, walay seryoso nga mga sayop nga naila, apan daghang mga kakulangan ang nakit-an. Bisan pa, kini nga mga disenyo gigamit sa daghang mga sistema, bisan kung gamay ang kasangkaran. Ang usa ka gamay nga proyekto dili kinahanglan nga adunay daghang mga sayup, mao nga dili nimo kinahanglan nga hukman ang pasundayag sa analisador sa gagmay nga mga proyekto. Mahimo nimong mabasa ang dugang bahin niini sa artikulo nga "
Mahimo nimong i-download ang usa ka pagsulay nga bersyon sa PVS-Studio gikan kanamo
Kung gusto nimong ipaambit kini nga artikulo sa usa ka tigpaminaw nga nagsultig English, palihug gamita ang link sa paghubad: Sergey Larin.
Source: www.habr.com