ä»æ¥ã®èšäºã®ãªã³ã¯ã¯éåžžãšã¯ç°ãªããŸãã ããã¯ããœãŒã¹ã³ãŒããåæããã1ã€ã®ãããžã§ã¯ãã§ã¯ãªããããã€ãã®ç°ãªããããžã§ã¯ãã§ã®åã蚺æã«ãŒã«ã®äžé£ã®å¿çã§ãã ããã§äœã«èå³ããããŸããïŒ å®éã«ã¯ãèæ ®ãããã³ãŒããã©ã°ã¡ã³ãã®äžéšã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã§ã®äœæ¥æã«åçŸå¯èœãªãšã©ãŒãå«ãŸããŠããŸããããã®ä»ã«ã¯å®å šã«è匱æ§ïŒCVEïŒãå«ãŸããŠããŸãã ããã«ãèšäºã®æåŸã§ãã»ãã¥ãªãã£ã®æ¬ é¥ã®ãããã¯ã«ã€ããŠå°ã説æããŸãã
åºæ
ä»æ¥èšäºã§æ€èšããããã¹ãŠã®ãšã©ãŒã¯ãåæ§ã®ãã¿ãŒã³ãæã£ãŠããŸãã
- ããã°ã©ã ã¯ã stdinã¹ããªãŒã ããããŒã¿ãåãåããŸãã
- ããŒã¿ã®èªã¿åããæåãããã©ããã®ãã§ãã¯ãè¡ãããŸãã
- ããŒã¿ãæ£åžžã«èªã¿åãããå Žåããã£ãªãŒæåã¯è¡ããåé€ãããŸãã
ãã ããèæ ®ããããã¹ãŠã®ãã©ã°ã¡ã³ãã«ã¯ãšã©ãŒãå«ãŸããŠãããäžæ£ãªå ¥åã«å¯ŸããŠè匱ã§ãã ã¢ããªã±ãŒã·ã§ã³ã®å®è¡ããžãã¯ã«éåããå¯èœæ§ã®ãããŠãŒã¶ãŒããããŒã¿ãåä¿¡ãããããäœããå£ãããšãã倧ããªèªæããããŸããã ç§ããã£ãã
以äžã®åé¡ã¯ãã¹ãŠãCãC ++ã ãã§ãªããCïŒãJavaã®ã³ãŒãã®ãšã©ãŒãæ€çŽ¢ããPVS-Studioéçã¢ãã©ã€ã¶ãŒã«ãã£ãŠçºèŠãããŸããã
ãã¡ãããéçã¢ãã©ã€ã¶ãŒã§åé¡ãèŠã€ããã®ã¯è¯ãããšã§ãããèŠã€ããŠåçŸããããšã¯ãŸã£ããå¥ã®åã³ã§ãã :)
ããªãŒã¹ã€ãã
æåã®çãããã³ãŒããã©ã°ã¡ã³ãã¯ãFreeSWITCHé åžãããã®äžéšã§ããfs_cli.exeã¢ãžã¥ãŒã«ã®ã³ãŒãã§èŠã€ãããŸããã
static const char *basic_gets(int *cnt) { .... int c = getchar(); if (c < 0) { if (fgets(command_buf, sizeof(command_buf) - 1, stdin) != command_buf) { break; } command_buf[strlen(command_buf)-1] = '\0'; /* remove endline */ break; } .... }
PVS-StudioèŠå ïŒ V1010 CWE-20æªãã§ãã¯ã®æ±æããŒã¿ãã€ã³ããã¯ã¹ã§äœ¿çšãããŠããŸãïŒ 'strlenïŒcommand_bufïŒ'ã
ã¢ãã©ã€ã¶ãŒã¯ã command_bufé åãžã®ã€ã³ããã¯ã¹ã«ããçãããã¢ã¯ã»ã¹ã«ã€ããŠèŠåããŸãã æªæ€èšŒã®å€éšããŒã¿ãã€ã³ããã¯ã¹ãšããŠäœ¿çšããããããçããããšèŠãªãããŸãã å€éš-ãããã¯ã stdinã¹ããªãŒã ããfgetsé¢æ°ãä»ããŠååŸãããããã§ãã æªæ€èšŒ-䜿çšåã«æ€èšŒãè¡ãããªãã£ãããã åŒfgetsïŒcommand_bufã....ïŒïŒ= Command_bufã¯ããã®æ¹æ³ã§ã¯ããŒã¿ã®åä¿¡ã®äºå®ã®ã¿ããã§ãã¯ãããã®å 容ã¯ãã§ãã¯ããªããããã«ãŠã³ããããŸããã
ãã®ã³ãŒãã®åé¡ã¯ãç¹å®ã®æ¡ä»¶äžã§ãã\ 0ããé åã®å€åŽã«æžã蟌ãŸããæªå®çŸ©ã®åäœãçºçããããšã§ãã ãããè¡ãã«ã¯ãé·ããŒãã®æååïŒCèšèªã®èŠ³ç¹ããé·ããŒãã®æååãã€ãŸãæåã®æåãã\ 0ãã«ãªãæååïŒãå ¥åããã ãã§ååã§ãã
å ¥åã«é·ããŒãã®æååãæž¡ããšã©ããªãããæšå®ããŠã¿ãŸãããã
- fgetsïŒcommand_bufã....ïŒ -> command_buf ;
- fgetsïŒ....ïŒïŒ= command_buf- > false ïŒ ãã®åŸ ã ifã¹ããŒãã¡ã³ãã®ãã©ã³ãã¯ç¡èŠãããŸãïŒ;
- strlenïŒcommand_bufïŒ -> 0 ;
- command_buf [strlenïŒcommand_bufïŒ -1] -> command_buf [-1] ã
ãã£ãšïŒ
ããã§èå³æ·±ãã®ã¯ããã®ã¢ãã©ã€ã¶ãŒã®èŠåããæã§æãããããããšã§ãã åé¡ãç¹°ãè¿ãã«ã¯ã次ã®ãã®ãå¿ èŠã§ãã
- ããã°ã©ã ããã®æ©èœã«æã¡èŸŒã¿ãŸãã
- getcharïŒïŒåŒã³åºããè² ã®å€ãè¿ãããã«å ¥åã埮調æŽããŸãã
- fgetsé¢æ°ã«ãå é ã«çµç«¯ããŒãã®è¡ãæž¡ããšãæ£åžžã«èªã¿åããã¯ãã§ãã
ãœãŒã¹ãå°ã調ã¹ãŠãåé¡ãåçŸããããã®ç¹å®ã®ã·ãŒã±ã³ã¹ãäœæããŸããã
- fs_cli.exeããããã¢ãŒãã§å®è¡ããŸãïŒ fs_cli.exe -b ïŒã ããã«æé ãå®è¡ããã«ã¯ã fs_cli.exeããµãŒããŒã«æ¥ç¶ããå¿ èŠããããŸãã ãã®ããã«ã¯ãããšãã°ã FreeSwitchConsole.exeã管çè ãšããŠããŒã«ã«ã§å®è¡ããã ãã§ååã§ãã
- getcharïŒïŒåŒã³åºããè² ã®å€ãè¿ãããã«å ¥åããŸãã
- å é ã«çµç«¯ãŒããå«ãè¡ãå ¥åããŸãïŒããšãã°ãã\ 0OooopsãïŒã
- ....
- å©çïŒ
以äžã¯ãåé¡ã®ãããªåçã§ãã
Ncftp
åæ§ã®åé¡ãNcFTPãããžã§ã¯ãã§çºèŠãããŸãããã2ã€ã®å Žæã§æ¢ã«ééããŸããã ã³ãŒãã¯äŒŒãŠãããããåé¡ã®ããå Žæã1ã€ã ãèããŠãã ããã
static int NcFTPConfirmResumeDownloadProc(....) { .... if (fgets(newname, sizeof(newname) - 1, stdin) == NULL) newname[0] = '\0'; newname[strlen(newname) - 1] = '\0'; .... }
PVS-StudioèŠå ïŒ V1010 CWE-20æªãã§ãã¯ã®æ±æããŒã¿ãã€ã³ããã¯ã¹ã§äœ¿çšãããŠããŸãïŒ 'strlenïŒnewnameïŒ'ã
ããã§ã¯ãFreeSWITCHã®äŸãšã¯ç°ãªããã³ãŒãã¯ããæªããåé¡ãçºçãããããªã£ãŠããŸãã ããšãã°ãèªã¿åããfgetsã䜿çšããŠæåãããã©ããã«é¢ä¿ãªããã\ 0ãã®æžã蟌ã¿ãçºçããŸãã ã€ãŸããéåžžã®å®è¡ããžãã¯ãç Žãæ¹æ³ã«ã¯ããã«å€ãã®å¯èœæ§ããããŸãã å®èšŒæžã¿ã®æ¹æ³ã§è¡ãã-é·ããŒãã®ã©ã€ã³ãéããŸãããã
åçŸãããåé¡ã¯ãFreeSWITCHã®å Žåãããå°ãè€éã§ãã æé ã®ã·ãŒã±ã³ã¹ã以äžã«èª¬æããŸãã
- ãã¡ã€ã«ãããŠã³ããŒãã§ãããµãŒããŒã®èµ·åãšæ¥ç¶ã ããšãã°ã speedtest.tele2.netã䜿çšããŸãã ïŒæçµçã«ãã¢ããªã±ãŒã·ã§ã³ã®èµ·åã³ãã³ãã¯æ¬¡ã®ããã«ãªããŸãïŒ ncftp.exe speedtest.tele2.net ïŒã
- ãµãŒããŒãããã¡ã€ã«ãããŠã³ããŒãããŸãã ããŒã«ã«ã§ã¯ãåãååã§ç°ãªãããããã£ãæã€ãã¡ã€ã«ãæ¢ã«ååšããŠããã¯ãã§ãã ããšãã°ããµãŒããŒãããã¡ã€ã«ãããŠã³ããŒãããŠå€æŽããããäžåºŠããŠã³ããŒãã³ãã³ããå®è¡ããããšãã§ããŸãïŒããšãã°ã 512KB.zipãååŸããŸã ïŒã
- æåãNãã§å§ãŸãè¡ã§ã¢ã¯ã·ã§ã³ãéžæããããšã«é¢ãã質åã«çããŠãã ããïŒããšãã°ã ããã楜ãã¿ãŸããã ïŒã
- ã\ 0ãïŒãŸãã¯ãã£ãšèå³æ·±ããã®ïŒãå ¥åããŠãã ããã
- ....
- å©çïŒ
åé¡ã®åçŸããããªã«èšé²ãããŸãã
Openldap
OpenLDAPãããžã§ã¯ãïŒããæ£ç¢ºã«ã¯ãä»éãããŠãŒãã£ãªãã£ã®1ã€ïŒã§ã¯ãFreeSWITCHãšåãã¬ãŒããèžãã ã æ¹è¡æåã®åé€ã¯ãè¡ãæ£åžžã«èªã¿åãããå Žåã«ã®ã¿çºçããŸãããé·ããŒãã®è¡ã«å¯Ÿããä¿è·ããããŸããã
ã³ãŒãã¹ããããïŒ
int main( int argc, char **argv ) { char buf[ 4096 ]; FILE *fp = NULL; .... if (....) { fp = stdin; } .... if ( fp == NULL ) { .... } else { while ((rc == 0 || contoper) && fgets(buf, sizeof(buf), fp) != NULL) { buf[ strlen( buf ) - 1 ] = '\0'; /* remove trailing newline */ if ( *buf != '\0' ) { rc = dodelete( ld, buf ); if ( rc != 0 ) retval = rc; } } } .... }
PVS-StudioèŠå ïŒ V1010 CWE-20æªãã§ãã¯ã®æ±æããŒã¿ãã€ã³ããã¯ã¹ã§äœ¿çšãããŠããŸãïŒ 'strlenïŒbufïŒ'ã
åé¡ã®æ¬è³ªãããæããã«ãªãããã«ãéå°ãæšãŠãŸãã
while (.... && fgets(buf, sizeof(buf), fp) != NULL) { buf[ strlen( buf ) - 1 ] = '\0'; .... }
ãã®ã³ãŒãã¯NcFTPãããåªããŠããŸãããäŸç¶ãšããŠè匱ã§ãã fgetsãªã¯ãšã¹ãã§ãé·ããŒãã®æååãå ¥åã«æž¡ãå ŽåïŒ
- fgetsïŒbufã....ïŒ -> buf ;
- fgetsïŒ....ïŒïŒ= NULL- > true ïŒ whileã«ãŒãã®æ¬äœãå®è¡ãéå§ããŸã ïŒ;
- strlenïŒbufïŒ -1- > 0-1- > -1 ;
- buf [-1] = '\ 0'
æ§æ¬²
äžèšã®ãšã©ãŒã¯éåžžã«èå³æ·±ããã®ã§ããïŒå®å®ããŠåçŸãããŠãããã觊ãããããšãã§ããŸãïŒOpenLDAPã®åé¡ã«æã䌞ã°ããªãã£ãå Žåãé€ãïŒïŒãè匱æ§ãšåŒã°ããããšã¯ã§ããŸãããåé¡ã«ã¯CVEèå¥åã¯å²ãåœãŠãããŸããã
ãã ããäžéšã®å®éã®è匱æ§ã«ã¯åãåé¡ãã¿ãŒã³ããããŸãã 以äžã®ã³ãŒãã¹ããããã¯äž¡æ¹ãšããlibidnãããžã§ã¯ãã«é©çšãããŸãã
ã³ãŒãã¹ããããïŒ
int main (int argc, char *argv[]) { .... else if (fgets (readbuf, BUFSIZ, stdin) == NULL) { if (feof (stdin)) break; error (EXIT_FAILURE, errno, _("input error")); } if (readbuf[strlen (readbuf) - 1] == '\n') readbuf[strlen (readbuf) - 1] = '\0'; .... }
PVS-StudioèŠå ïŒ V1010 CWE-20æªãã§ãã¯ã®æ±æããŒã¿ãã€ã³ããã¯ã¹ã§äœ¿çšãããŠããŸãïŒ 'strlenïŒreadbufïŒ'ã
ç¶æ³ã¯äŒŒãŠããŸãããèšé²ãã€ã³ããã¯ã¹-1ã§å®è¡ãããåã®äŸãšã¯ç°ãªããèªã¿åãã¯ããã§è¡ãããŸãã ãã ããããã¯æªå®çŸ©ã®åäœã§ãã ãã®ãšã©ãŒã«ã¯ãç¬èªã®CVEèå¥åïŒ CVE-2015-8948 ïŒãå²ãåœãŠãããŠããŸãã
åé¡ãæ€åºããåŸããã®ã³ãŒãã¯æ¬¡ã®ããã«å€æŽãããŸããã
int main (int argc, char *argv[]) { .... else if (getline (&line, &linelen, stdin) == -1) { if (feof (stdin)) break; error (EXIT_FAILURE, errno, _("input error")); } if (line[strlen (line) - 1] == '\n') line[strlen (line) - 1] = '\0'; .... }
å°ãé©ããïŒ ããã¯èµ·ãããŸãã æ°ããè匱æ§ã察å¿ããCVEèå¥åïŒ CVE-2016-6262
PVS-StudioèŠå ïŒ V1010 CWE-20æªãã§ãã¯ã®æ±æããŒã¿ãã€ã³ããã¯ã¹ã§äœ¿çšãããŠããŸãïŒ 'strlenïŒlineïŒ'ã
å¥ã®è©Šã¿ã§ã¯ãå ¥åæååã®é·ãã®ãã§ãã¯ãè¿œå ããããšã§åé¡ãä¿®æ£ãããŸããã
if (strlen (line) > 0) if (line[strlen (line) - 1] == '\n') line[strlen (line) - 1] = '\0';
æ¥ä»ãèŠãŠã¿ãŸãããã ã³ããããã¯ããŒãºãCVE-2015-8948-08/10/2015ã CVE-2016-62-62-2016幎1æ14æ¥ã®ã¯ããŒãºãã³ãããããŸãã ã€ãŸããäžèšã®ä¿®æ£ã®å·®ã¯5ãæã§ãïŒ ããã§ã¯ãã³ãŒãèšè¿°ã®åæ段éã§ãšã©ãŒãæ€åºãããªã©ã®éçåæã®å©ç¹ã«ã€ããŠæãåºããŸã...
éçåæãšã»ãã¥ãªãã£
ãã以äžã®ã³ãŒãäŸã¯ãããŸãããã代ããã«çµ±èšãšæšè«ããããŸãã ãã®ã»ã¯ã·ã§ã³ã§ã¯ãèè ã®æèŠãšèªè ã®æèŠããã®èšäºã®ä»¥åãããã¯ããã«äžèŽããªãå ŽåããããŸãã
ã泚æ åæ§ã®ãããã¯ã«é¢ããå¥ã®èšäºãèªãããšããå§ãããŸã-ã PVS-Studioã¯ã©ã®ããã«è匱æ§ãèŠã€ããã®ã«åœ¹ç«ã¡ãŸããïŒ ãã åçŽãªãšã©ãŒã®ããã«èŠããè匱æ§ã®èå³æ·±ãäŸããããŸãã ããã«ããã®èšäºã§ã¯ãçšèªãšãã»ãã¥ãªãã£ãããã¯ã«ã€ããŠæžå¿µãããå Žåã«éçåæãå¿ èŠãªçç±ã«ã€ããŠå°ã説æããŸããã
éå»10幎éã«çºèŠãããè匱æ§ã®æ°ã«é¢ããçµ±èšãèŠãŠãç¶æ³ãè©äŸ¡ããŸãããã CVE Details Webãµã€ãããããŒã¿ãååŸããŸããã
èå³æ·±ãç¶æ³ãè¿«ã£ãŠããŸãã 2014幎ãŸã§ãèšé²ãããCVEã®æ°ã¯6,000ãŠãããã®ããŒã¯ãè¶ ããŠããŸããã§ããã ãããã2017幎ã®çµ±èšã¯ãã¡ãããããã§æãèå³æ·±ããã®ã«èŠããŸã-絶察çãªãªãŒããŒïŒ14,714ãŠãããïŒã§ãã çŸåš-2018-幎ã«ã€ããŠã¯ããŸã çµäºããŠããŸãããããã§ã«èšé²ãç Žã£ãŠããŸã-15,310å°ã
ããã¯ããã¹ãŠã®æ°ãããœãããŠã§ã¢ããµããã®ãããªç©Žã§ãã£ã±ãã§ããããšãæå³ããŸããïŒ ç§ã¯èããŠããªãããããŠããã«çç±ãããïŒ
- è匱æ§ã®ãããã¯ã«å¯Ÿããé¢å¿ã®é«ãŸãã 確ãã«ãããªããã»ãã¥ãªãã£ã®ãããã¯ã«ããŸãè¿ããªããŠããã»ãã¥ãªãã£ã®ãããã¯ã«é¢ããèšäºãã¡ã¢ãã¬ããŒãããããªã«ç¹°ãè¿ãåºããããŸãã èšãæãããšãäžçš®ã®ãèªå€§åºåããäœæãããŸããã æªãã§ããïŒ ãããããªãã çµå±ã®ãšãããéçºè ã¯ã¢ããªã±ãŒã·ã§ã³ã®ã»ãã¥ãªãã£ãããéèŠããŠãããšããäºå®ã«åž°çããŸããããã¯è¯ãããšã§ãã
- éçºãããã¢ããªã±ãŒã·ã§ã³ã®æ°ã®å¢å ã ããå€ãã®ã³ãŒã-çµ±èšãè£å ããè匱æ§ãçºçããå¯èœæ§ãé«ããªããŸãã
- è匱æ§æ€çŽ¢ããŒã«ãšã³ãŒãå質ä¿èšŒã®æ¹åã ããå€ãã®éèŠ->ããå€ãã®äŸçµŠã ã¢ãã©ã€ã¶ãŒããã¡ã¶ãŒãããã³ãã®ä»ã®ããŒã«ã¯ããé«åºŠã«ãªããè匱æ§ãæ¢ããã人ã®æã«æž¡ããŸãïŒããªã±ãŒãã®ã©ã¡ãã®åŽã«ããŠãïŒã
ãããã£ãŠãæ°ããªãã¬ã³ããåŠå®çãªãã®ãšåŒã¶ããšã¯ã§ããŸãããåºç瀟ã¯æ å ±ã»ãã¥ãªãã£ã«ã€ããŠããæžå¿µããŠãããåé¡ãèŠã€ããããã®ããŒã«ãæ¹åãããŠãããããã¯ééããªãè¯å®çã§ãã
ããã¯ããå ¥æµŽãããã«ãªã©ãã¯ã¹ã§ãããšããããšã§ããïŒ ç§ã¯ããã¯æããŸããã ã¢ããªã±ãŒã·ã§ã³ã®ã»ãã¥ãªãã£ãããã¯ãå¿é ãªå Žåã¯ãã§ããã ãå€ãã®ã»ãã¥ãªãã£å¯Ÿçãè¬ããå¿ èŠããããŸãã ããã¯ããœãŒã¹ã³ãŒãããããªãã¯ãã¡ã€ã³ã«ããå Žåã«ç¹ã«åœãŠã¯ãŸããŸãã
- å€éšã®è匱æ§ã®åã蟌ã¿ã®åœ±é¿ãåããããã
- æªçšã®ç®çã§ã¢ããªã±ãŒã·ã§ã³ã®ç©Žã«èå³ãããã玳士ãã«ãã£ãŠããããŒãã³ã°ããããåŸåããããŸãã ãã®å Žåã®åžæè ã¯ããªãããã£ãšå©ããããšãã§ããŸããã
ãããžã§ã¯ãããªãŒãã³ãœãŒã¹ã§ç¿»èš³ããå¿ èŠããªããšã¯èšããããããŸããã é©åãªå質/å®å šç®¡çã念é ã«çœ®ããŠãã ããã
éç解æã¯ãã®ãããªè¿œå ã®æ段ã§ããïŒ ã¯ã éçåæã¯ãå°æ¥çŸå®ã«ãªãå¯èœæ§ã®ããæœåšçãªè匱æ§ãæ€åºããã®ã«åœ¹ç«ã¡ãŸãã
å€ãã®äººãè匱æ§ãããªãé«ã¬ãã«ã®çŸè±¡ã§ãããšèããŠããããã«æããŸãïŒç§ã¯ééãã ãšæããŸãïŒã ã¯ãããããã åçŽãªããã°ã©ãã³ã°ãšã©ãŒã®ããã«èŠããã³ãŒãã®åé¡ãæ·±å»ãªè匱æ§ã§ãã ç¹°ãè¿ãã«ãªããŸããããã®ãããªè匱æ§ã®äŸã¯ã åè¿°ã®èšäºã§æäŸãããŠããŸã ã ãåçŽãªãééããéå°è©äŸ¡ããªãã§ãã ããã
ãããã«
å ¥åããŒã¿ã®é·ãããŒãã«ããããšãã§ãããããèæ ®ããå¿ èŠãããããšãå¿ããªãã§ãã ããã
è匱æ§ã䌎ããã¹ãŠã®èªå€§åºåãåãªãèªå€§åºåã§ãããã©ããããŸãã¯åé¡ãååšããå Žåã¯èªåã§ãããšããçµè«ã
ç§ã®å Žåã¯ããããžã§ã¯ãPVS-StudioããŸã è©ŠããŠããªãå Žåã¯è©ŠããŠã¿ãªãéãã§ãã
æé«ïŒ
ãã®èšäºãè±èªåã®èŽè¡ãšå ±æãããå Žåã¯ã翻蚳ãžã®ãªã³ã¯ã䜿çšããŠãã ããïŒã»ã«ã²ã€ãŽã¡ã·ãªãšãã å ¥åããŒã¿ãåŠçãããšãã«è¶³ã§èªåèªèº«ãæã€