
PVS-Studioã¢ãã©ã€ã¶ãŒã䜿çšããŠãäžæ®çºæ§ã¡ã¢ãªããµããŒãããã¢ããªã±ãŒã·ã§ã³ã®éçºãšãããã°çšã«èšèšããããªãŒãã³PMDKã©ã€ãã©ãªã®ã³ã¬ã¯ã·ã§ã³ããã§ãã¯ããããã«ææ¡ãããŸãããå®éãã©ãããŠã§ãããããã«ãããã¯Cããã³C ++ã®å°ããªãããžã§ã¯ãã§ãããã³ã¡ã³ããé€ããåèšã³ãŒãããŒã¹ãµã€ãºã¯çŽ170KLOCã§ããããã¯ãåæçµæã®ã¬ãã¥ãŒã«å€ãã®æéãšåŽåãããããªãããšãæå³ããŸããè¡ããã
ãœãŒã¹ã³ãŒããåæããã«ã¯ãPVS-StudioããŒã«ããŒãžã§ã³7.08ã䜿çšããŸããåœç¶ã®ããšãªãããç§ãã¡ã®ããã°ã®èªè ã¯ç§ãã¡ã®ããŒã«ã«é·ãé粟éããŠããã®ã§ãç§ã¯ããã«ãã ããã€ããã¯ãããŸãããåããŠã®ç§éã«æ¥ã人ã®ããã«ãç§ã¯ãèšäºãåç §å§ãè¿ éïŒCããã³C ++ã³ãŒãã®PVS-Studioã®ã¢ãã©ã€ã¶ã«ãã£ãŠçºè¡ãããŠããè峿·±ãèŠåã衚瀺ããæ¹æ³ããšããŠã¿ãŠãã ããã¢ãã©ã€ã¶ã®ç¡æè©Šçšçãã
ä»åã¯PMDKãããžã§ã¯ãã®å éšãèŠãŠãæ°ä»ãããšã©ãŒã𿬠ç¹ã«ã€ããŠèª¬æããŸããç§ã®å é¢ã§ã¯ããããã®æ°ã¯å€ããããŸããã§ãããããã¯ããã®ãããžã§ã¯ãã®ã³ãŒãã®å質ãé«ãããšã瀺ããŠããŸããè峿·±ãããšã«ãééã£ãã³ãŒãã®ãã©ã°ã¡ã³ããããã€ãèŠã€ãã£ãã«ãããããããæ£ããæ©èœããŠããããšãããããŸã:)ãç§ãèšãããããšã¯ããããªããã¬ãŒã·ã§ã³ããããæç¢ºã«ãªãã§ãããã
èŠçŽãããšãPMDKã¯ãäžæ®çºæ§ã¡ã¢ãªå¯Ÿå¿ã¢ããªã±ãŒã·ã§ã³ã®éçºããããã°ãããã³ç®¡çãç°¡çŽ åããããã«èšèšããããªãŒãã³ãœãŒã¹ã©ã€ãã©ãªãšããŒã«ã®ã³ã¬ã¯ã·ã§ã³ã§ãã詳现ã¯ãã¡ãïŒPMDKã®ç޹ä»ãããã®ãœãŒã¹ïŒpmdkã
ç§ãããã«èŠã€ããããšãã§ãããšã©ãŒã𿬠ç¹ãèŠãŠã¿ãŸããããç§ã¯ãã¬ããŒããåæãããšãã«åžžã«æ³šæãæãããšã¯ã§ãããå€ãã®ããšãèŠéããŠããå¯èœæ§ãããããšãããã«èšããªããã°ãªããŸããããããã£ãŠããããžã§ã¯ãã®äœæè ã¯ãæ¬ é¥ãä¿®æ£ãããšãã«ãã®èšäºã ãã«å°ãããã®ã§ã¯ãªããèªåã§ã³ãŒããå確èªããããšããå§ãããŸãããããŠãèšäºãæžãã«ã¯ãèŠåã®ãªã¹ããèŠãŠãç§ãæžãããã®ã§ååã§ã:)ã
åäœããééã£ãã³ãŒã
ã¡ã¢ãªå²ãåœãŠãµã€ãº
ããã°ã©ã ãæ¬æ¥ã®åäœãããªããšãã«ãããã°ã©ããŒãã³ãŒãã®ãããã°ã«æéãè²»ããããšã¯çãããããŸããããã ããããã°ã©ã ãæ£ããæ©èœããŠããŠããã³ãŒãã«ãšã©ãŒãå«ãŸããŠããå ŽåããããŸããããã°ã©ããŒã¯å¹žéã§ããããšã©ãŒã¯çŸããŸãããPMDKãããžã§ã¯ãã§ã¯ããã®ãããªè峿·±ãç¶æ³ã«äžåºŠã«ééãããããããããå¥ã®ç« ã«ãŸãšããããšã«ããŸããã
int main(int argc, char *argv[])
{
....
struct pool *pop = malloc(sizeof(pop));
....
}
PVS-Studioã®èŠåïŒV568'sizeofïŒïŒ 'æŒç®åãã¯ã©ã¹ãžã®ãã€ã³ã¿ãŒã®ãµã€ãºãè©äŸ¡ãããã' pop 'ã¯ã©ã¹ãªããžã§ã¯ãã®ãµã€ãºã¯è©äŸ¡ããªãã®ã¯å¥åŠãªããšã§ããutil_ctl.c717
誀ã£ãéã®ã¡ã¢ãªãå²ãåœãŠãããåå ãšãªãå€å žçãªã¿ã€ããã¹ãsizeofæŒç®åã¯ãæ§é ã®ãµã€ãºã§ã¯ãªãããã®æ§é ãžã®ãã€ã³ã¿ãŒã®ãµã€ãºãè¿ããŸããæ£ãããªãã·ã§ã³ã¯æ¬¡ã®ãšããã§ãã
struct pool *pop = malloc(sizeof(pool));
ãŸãã¯
struct pool *pop = malloc(sizeof(*pop));
ãã ãããã®èª€ã£ãŠèšè¿°ãããã³ãŒãã¯ããŸãæ©èœããŸããéèŠãªã®ã¯ãããŒã«æ§é ã«ã¯1ã€ã®ãã€ã³ã¿ãŒãå«ãŸããŠãããšããããšã§ãã
struct pool {
struct ctl *ctl;
};
æ§é ã¯ãã€ã³ã¿ãšãŸã£ããåãéãå ããããšãããããŸããç©äºã¯è¯ãã§ãã
ç·ã®é·ã
次ã®ã±ãŒã¹ã«ç§»ããŸããããããã§ããsizeofæŒç®åã䜿çšããŠãšã©ãŒãçºçããŸããã
typedef void *(*pmem2_memcpy_fn)(void *pmemdest, const void *src, size_t len,
unsigned flags);
static const char *initial_state = "No code.";
static int
test_rwx_prot_map_priv_do_execute(const struct test_case *tc,
int argc, char *argv[])
{
....
char *addr_map = pmem2_map_get_address(map);
map->memcpy_fn(addr_map, initial_state, sizeof(initial_state), 0);
....
}
PVS-StudioèŠåïŒV579 [CWE-687] memcpy_fn颿°ã¯ããã€ã³ã¿ãŒãšãã®ãµã€ãºãåŒæ°ãšããŠåãåããŸããããããééãã§ãã 3çªç®ã®åŒæ°ã調ã¹ãŸãã pmem2_map_prot.c 513
ç¹æ®ãªã³ããŒé¢æ°ãžã®ãã€ã³ã¿ãŒã¯ãæååãã³ããŒããããã«äœ¿çšãããŸãããã®é¢æ°ã®åŒã³åºãããŸãã¯ããããã®3çªç®ã®åŒæ°ã«æ³šæããŠãã ããã
ããã°ã©ããŒã¯ãsizeofæŒç®åãæååãªãã©ã«ã®ãµã€ãºãèšç®ãããšæ³å®ããŠããŸããããããå®éã«ã¯ããã€ã³ã¿ãŒã®ãµã€ãºãå床èšç®ãããŸãã
幞ããæååã¯8æåã§æ§æãããŠããã64ãããã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããå Žåããã®ãµã€ãºã¯ãã€ã³ã¿ãšåãã§ãããã®çµæãæååã®8æåãã¹ãŠããã³ãŒããªããã«ãªããŸããæ£åžžã«ã³ããŒãããŸãã
å®éãç¶æ³ã¯ããã«è€éã§è峿·±ããã®ã§ãããã®ãšã©ãŒã®è§£éã¯ãã¿ãŒããã«0ãã³ããŒãããã©ããã«ãã£ãŠç°ãªããŸãã2ã€ã®ã·ããªãªãèããŠã¿ãŸãããã
ã·ããªãª1.端å0ãã³ããŒããå¿ èŠããããŸãããããããç§ã¯ééã£ãŠããŸãããããŠããã¯ããèªäœãçŸããªãç¡å®³ãªééãã§ã¯ãããŸããã9ãã€ãã§ã¯ãªãã8ãã€ãã®ã¿ãã³ããŒãããŸãããã¿ãŒããã«ãŒãã¯ãªããçµæãäºæž¬ããããšã¯ã§ããŸããããã®å Žåã宿°æååinitial_stateã®å®çŸ©ã次ã®ããã«å€æŽããããšã§ãã³ãŒããä¿®æ£ã§ããŸãã
static const char initial_state [] = "No code.";
ããã§ãsizeofïŒinitial_stateïŒå€ã¯9ã«ãªããŸãã
ã·ããªãª2.ã¿ãŒããã«ãŒãã¯ãŸã£ããå¿ èŠãããŸãããããšãã°ã以äžã«æ¬¡ã®ã³ãŒãè¡ã瀺ããŸãã
UT_ASSERTeq(memcmp(addr_map, initial_state, strlen(initial_state)), 0);
ã芧ã®ãšãããstrlen颿°ã¯å€8ãè¿ãã端åãŒãã¯æ¯èŒã«é¢äžããŸãããããããããã¯æ¬åœã«å¹žéã§ããããã¹ãŠãé 調ã§ãã
ãããã·ãã
次ã®äŸã¯ããããåäœã®ã·ããæäœã«é¢é£ããŠããŸãã
static int
clo_parse_single_uint(struct benchmark_clo *clo, const char *arg, void *ptr)
{
....
uint64_t tmax = ~0 >> (64 - 8 * clo->type_uint.size);
....
}
PVS-StudioèŠåïŒV610 [CWE-758]äžç¹å®ã®åäœãã·ããæŒç®å '>>'ã確èªããŠãã ãããå·Šã®ãªãã©ã³ã 'ã0'ã¯è² ã§ããclo.cpp 205
è² ã®å€ãå³ã«ã·ããããçµæã¯ãã³ã³ãã€ã©ã®å®è£ ã«ãã£ãŠç°ãªããŸãããããã£ãŠããã®ãããªã³ãŒãã¯æ£ããæ©èœããçŸåšååšãããã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³ã³ã³ãã€ã«ã¢ãŒãã§æåŸ ã©ããã«æ©èœããå¯èœæ§ããããŸãããããã§ã幞éã§ãã
éçšã®åªå é äœ
ãããŠãæäœã®åªå é äœã«é¢é£ããæåŸã®ã±ãŒã¹ãèããŠã¿ãŸãããã
#define BTT_CREATE_DEF_SIZE (20 * 1UL << 20) /* 20 MB */
PVS-StudioèŠåïŒV634 [CWE-783]ã*ãæäœã®åªå 床ã¯ã<<ãæäœã®åªå 床ãããé«ããªã£ãŠããŸããåŒã§æ¬åŒ§ã䜿çšããå¿ èŠãããå¯èœæ§ããããŸããbttcreate.c 204
20 MBã«çãã宿°ãååŸããããã«ãããã°ã©ããŒã¯æ¬¡ã®ããšãè¡ãããšã«ããŸããã
- 1 x 20ãããã·ããããŠ1048576ãååŸããŸããã€ãŸãã1MBã
- 1MBã«20ãæããŸãã
èšãæããã°ãããã°ã©ããŒã¯èšç®ã次ã®ããã«è¡ããããšèããŸãïŒïŒ20 *ïŒ1UL << 20ïŒïŒ
ãããå®éã«ã¯ãä¹ç®æŒç®åã®åªå 床ã¯ã·ããæŒç®åã®åªå 床ãããé«ããåŒã¯æ¬¡ã®ããã«è©äŸ¡ãããŸãïŒïŒïŒ20 * 1ULïŒ<< 20ïŒã
åæããŸããããã°ã©ããŒã¯åŒããã®ãããªé åºã§è©äŸ¡ãããããšãã»ãšãã©æãã§ããŸããã§ããã20ã«1ãæããŠãæå³ããããŸããããããã£ãŠãããã¯ãã³ãŒããããã°ã©ããŒã®æå³ãããšããã«æ©èœããªãå Žåã§ãã
ãããããã®ãšã©ãŒã¯æ±ºããŠçŸããŸãããã©ã®ããã«æžããã¯åé¡ã§ã¯ãããŸããã
- ïŒ20 * 1UL << 20ïŒ
- ïŒ20 *ïŒ1UL << 20ïŒïŒ
- ïŒïŒ20 * 1ULïŒ<< 20ïŒ
çµæã¯åžžã«åãã§ãïŒå¿ èŠãªå€ã¯åžžã«20971520ã§ãããããã°ã©ã ã¯å®å šã«æ£ããæ©èœããŸãã
ãã®ä»ã®ãšã©ãŒ
ééã£ãå Žæã®æ¬åŒ§
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
static void
enum_handles(int op)
{
....
NTSTATUS status;
while ((status = NtQuerySystemInformation(
SystemExtendedHandleInformation,
hndl_info, hi_size, &req_size)
== STATUS_INFO_LENGTH_MISMATCH)) {
hi_size = req_size + 4096;
hndl_info = (PSYSTEM_HANDLE_INFORMATION_EX)REALLOC(hndl_info,
hi_size);
}
UT_ASSERT(status >= 0);
....
}
PVS-Studioã®èŠåïŒV593 [CWE-783]ãA = B == Cãã®çš®é¡ã®åŒã確èªããããšãæ€èšããŠãã ãããåŒã¯æ¬¡ã®ããã«èšç®ãããŸãïŒ 'A =ïŒB == CïŒ'ãut.c 641
ãããããèŠãŠãã ããïŒ
while ((status = NtQuerySystemInformation(....) == STATUS_INFO_LENGTH_MISMATCH))
ããã°ã©ããŒã¯ãNtQuerySystemInformation颿°ãè¿ãå€ãã¹ããŒã¿ã¹å€æ°ã«æ ŒçŽããããã宿°ãšæ¯èŒããããšèããŠããŸããã ããã°ã©ããŒã¯ãæ¯èŒæŒç®åïŒ==ïŒã®åªå 床ãå²ãåœãŠæŒç®åïŒ=ïŒãããé«ãããšãç¥ã£ãŠããå¯èœæ§ãé«ããããæ¬åŒ§ã䜿çšããå¿ èŠããããŸãããããã圌ã¯èªåèªèº«ãå°å°ããããããééã£ãå Žæã«çœ®ããŸãããçµæãšããŠãæ¬åŒ§ã¯ãŸã£ãã圹ã«ç«ã¡ãŸãããæ£ããã³ãŒãïŒ
while ((status = NtQuerySystemInformation(....)) == STATUS_INFO_LENGTH_MISMATCH)
ãã®ãšã©ãŒã®ãããUT_ASSERTãã¯ãã¯æ©èœããŸãããå®éãã¹ããŒã¿ã¹å€æ°ã«ã¯åžžã«æ¯èŒã®çµæãã€ãŸãfalseïŒ0ïŒãŸãã¯trueïŒ1ïŒãå«ãŸããŸãããããã£ãŠãæ¡ä»¶ïŒ[0..1]> = 0ïŒã¯åžžã«çã§ãã
æœåšçãªã¡ã¢ãªãªãŒã¯
static enum pocli_ret
pocli_args_obj_root(struct pocli_ctx *ctx, char *in, PMEMoid **oidp)
{
char *input = strdup(in);
if (!input)
return POCLI_ERR_MALLOC;
if (!oidp)
return POCLI_ERR_PARS;
....
}
PVS-StudioèŠåïŒV773 [CWE-401]ãå ¥åããã€ã³ã¿ãŒãè§£æŸããã«é¢æ°ãçµäºããŸãããã¡ã¢ãªãªãŒã¯ãçºçããå¯èœæ§ããããŸããpmemobjcli.c 238 oidpãnullãã€ã³ã¿ãŒã§ããããšã倿ãã
å Žåãstrdup颿°ãåŒã³åºããŠäœæãããæååã®ã³ããŒã¯å€±ãããŸããæåã®çã¯ãã¡ã¢ãªãå²ãåœãŠãåã«ãã§ãã¯ãå»¶æããããšã§ãã
static enum pocli_ret
pocli_args_obj_root(struct pocli_ctx *ctx, char *in, PMEMoid **oidp)
{
if (!oidp)
return POCLI_ERR_PARS;
char *input = strdup(in);
if (!input)
return POCLI_ERR_MALLOC;
....
}
ãŸãã¯ãã¡ã¢ãªãæç€ºçã«è§£æŸã§ããŸãã
static enum pocli_ret
pocli_args_obj_root(struct pocli_ctx *ctx, char *in, PMEMoid **oidp)
{
char *input = strdup(in);
if (!input)
return POCLI_ERR_MALLOC;
if (!oidp)
{
free(input);
return POCLI_ERR_PARS;
}
....
}
ãªãŒããŒãããŒã®å¯èœæ§
typedef long long os_off_t;
void
do_memcpy(...., int dest_off, ....., size_t mapped_len, .....)
{
....
LSEEK(fd, (os_off_t)(dest_off + (int)(mapped_len / 2)), SEEK_SET);
....
}
PVS-StudioèŠåïŒV1028 [CWE-190]ãªãŒããŒãããŒã®å¯èœæ§ããããŸããçµæã§ã¯ãªãããªãã©ã³ãããã£ã¹ãããããšãæ€èšããŠãã ãããmemcpy_common.c 62os_off_t
ã¿ã€ããžã®è¿œå ã®çµæãæç€ºçã«ãã£ã¹ãããããšã¯æå³ããããŸããããŸãã2ã€ã®intå€ã远å ãããšãã«çºçããå¯èœæ§ã®ãããªãŒããŒãããŒããä¿è·ããŸããã第äºã«ã远å ã®çµæã¯ããšã«ããos_off_tã¿ã€ãã«æé»çã«æ¡åŒµãããŸããæç€ºçãªåãã£ã¹ãã¯åã«åé·ã§ãã ç§ã¯ãã®ããã«æžãæ¹ãæ£ãããšæããŸãïŒ
LSEEK(fd, dest_off + (os_off_t)(mapped_len) / 2, SEEK_SET);
ããã§ãsize_tã¿ã€ãã®ç¬Šå·ãªãã®å€ã笊å·ä»ãã®å€ã«å€æãããŸãïŒã³ã³ãã€ã©ããã®èŠåããªãããã«ããããïŒãåæã«ãè¿œå æã«ãªãŒããŒãããŒãçºçããããšã¯ãããŸããã
äžé©åãªãªãŒããŒãããŒä¿è·
static DWORD
get_rel_wait(const struct timespec *abstime)
{
struct __timeb64 t;
_ftime64_s(&t);
time_t now_ms = t.time * 1000 + t.millitm;
time_t ms = (time_t)(abstime->tv_sec * 1000 +
abstime->tv_nsec / 1000000);
DWORD rel_wait = (DWORD)(ms - now_ms);
return rel_wait < 0 ? 0 : rel_wait;
}
PVS-StudioèŠåïŒV547 [CWE-570]åŒ 'rel_wait <0'ã¯åžžã«falseã§ãã笊å·ãªãã¿ã€ãã®å€ã0æªæºã«ãªãããšã¯ãããŸãããos_thread_windows.c359
ãã§ãã¯ãã©ã®ç¶æ³ããä¿è·ããå¿ èŠããããã«ã€ããŠã¯ããããããŸãããããšã«ããæ©èœããŸãããrel_wait倿°ã¯ç¬Šå·ãªãDWORDã¿ã€ãã§ããããã¯ãçµæãåžžã«çã§ãããããrel_wait <0ã®æ¯èŒã¯æå³ããªãããšãæå³ããŸãã
ã¡ã¢ãªãæ£åžžã«å²ãåœãŠãããããšã®ç¢ºèªã®æ¬ åŠ
ã¡ã¢ãªãå²ãåœãŠãããŠããããšã®ç¢ºèªã¯ãã¢ããªã±ãŒã·ã§ã³ã®ãªãªãŒã¹ããŒãžã§ã³ãã³ã³ãã€ã«ãããŠããå Žåã¯äœãããªãassertãã¯ãã䜿çšããŠè¡ãããŸãããããã£ãŠãmalloc颿°ãNULLãè¿ãç¶æ³ã®åŠçã¯ãªããšèšããŸããäŸïŒ
static void
remove_extra_node(TOID(struct tree_map_node) *node)
{
....
unsigned char *new_key = (unsigned char *)malloc(new_key_size);
assert(new_key != NULL);
memcpy(new_key, D_RO(tmp)->key, D_RO(tmp)->key_size);
....
}
PVS-StudioèŠåïŒV575 [CWE-628]æœåšçãªnullãã€ã³ã¿ãŒããmemcpyã颿°ã«æž¡ãããŸããæåã®åŒæ°ã調ã¹ãŸãããã§ãã¯è¡ïŒ340ã338ãrtree_map.c 340
ä»ã®å Žæã§ã¯ãã¢ãµãŒããããããŸããïŒ
static void
calc_pi_mt(void)
{
....
HANDLE *workers = (HANDLE *) malloc(sizeof(HANDLE) * pending);
for (i = 0; i < pending; ++i) {
workers[i] = CreateThread(NULL, 0, calc_pi,
&tasks[i], 0, NULL);
if (workers[i] == NULL)
break;
}
....
}
PVS-StudioèŠåïŒV522 [CWE-690]æœåšçãªãã«ãã€ã³ã¿ãŒãã¯ãŒã«ãŒãã®åç §è§£é€ãããå¯èœæ§ããããŸãããã§ãã¯è¡ïŒ126ã124ãpi.c126
å°ãªããšã37ã®ãã®ãããªã³ãŒããã©ã°ã¡ã³ããæ°ããŸããããããã£ãŠãããããã¹ãŠãèšäºã«èšèŒããçç±ã¯ãããŸããã
äžèŠããã§ãã¯ã®æ¬ åŠã¯åãªãæ æ°ãšèŠãªãããšãã§ããããã¯åãã®ããã³ãŒãã§ãããšèšããŸããç§ã¯ãã®ç«å Žã«åæããŸãããããã°ã©ããŒã¯ããã®ãããªãã§ãã¯ãèŠéãå±éºæ§ãéå°è©äŸ¡ããŠããŸãã nullãã€ã³ã¿ãŒã¯ãåç §ãè§£é€ããããšãããšãã«ãããã°ã©ã ã®ã¯ã©ãã·ã¥ãšããŠããã«çŸãããšã¯éããŸãããç¹ã«ãã«ãã¹ã¬ããããã°ã©ã ã§ã¯ãçµæã¯ããå¥åŠã§å±éºãªãã®ã«ãªãå¯èœæ§ããããŸããäœãåé¡ã§ããªããã§ãã¯ãå¿ èŠãªã®ãããã詳现ã«çè§£ããããã«ãèšäºãèªãããšã匷ããå§ãããŸããmalloc颿°ãäœãè¿ãããã確èªããããšãéèŠãªã®ã¯ãªãã§ããã
èãã³ãŒã
CloseHandleãããã«ã³ãŒã«
static void
prepare_map(struct pmem2_map **map_ptr,
struct pmem2_config *cfg, struct pmem2_source *src)
{
....
HANDLE mh = CreateFileMapping(....);
....
UT_ASSERTne(CloseHandle(mh), 0);
....
}
PVS-Studioã®èŠåïŒV586 [CWE-675]åããªãœãŒã¹ã®å²ãåœãŠãè§£é€ããããã«ãCloseHandleã颿°ã2ååŒã³åºãããŸããpmem2_map.c 76
ãã®ã³ãŒããšPVS-Studioã®èŠåãèŠããšãæç¢ºãªãã®ãäœããªãããšã¯æããã§ããã©ãã§CloseHandleãå床åŒã³åºãããšãã§ããŸããïŒçããèŠã€ããããã«ãUT_ASSERTneãã¯ãã®å®è£ ãèŠãŠã¿ãŸãããã
#define UT_ASSERTne(lhs, rhs)\
do {\
/* See comment in UT_ASSERT. */\
if (__builtin_constant_p(lhs) && __builtin_constant_p(rhs))\
UT_ASSERT_COMPILE_ERROR_ON((lhs) != (rhs));\
UT_ASSERTne_rt(lhs, rhs);\
} while (0)
ããã¯ããã»ã©æç¢ºã«ã¯ãªããŸããã§ãããUT_ASSERT_COMPILE_ERROR_ONãšã¯äœã§ããïŒUT_ASSERTne_rtãšã¯äœã§ããïŒ
åãã¯ãã®èª¬æã§èšäºãä¹±éã«ããããèªè ãèŠãããããããé ã®äžã§1ã€ã®ãã¯ããä»ã®ãã¯ãã«æ¿å ¥ããããã«åŒ·å¶ããŸããååŠçããããã¡ã€ã«ããååŸããããéãããã³ãŒãã®æçµããŒãžã§ã³ãããã«èŠãŠã¿ãŸãããã
do {
if (0 && 0) (void)((CloseHandle(mh)) != (0));
((void)(((CloseHandle(mh)) != (0)) ||
(ut_fatal(".....", 76, __FUNCTION__, "......: %s (0x%llx) != %s (0x%llx)",
"CloseHandle(mh)", (unsigned long long)(CloseHandle(mh)), "0",
(unsigned long long)(0)), 0))); } while (0);
åžžã«èª€ã£ãæ¡ä»¶ïŒ0 && 0ïŒãšãäžè¬çã«ã¯ç¡é¢ä¿ãªãã®ããã¹ãŠåé€ããŸããããããã倿ïŒ
((void)(((CloseHandle(mh)) != (0)) ||
(ut_fatal(...., "assertion failure: %s (0x%llx) != %s (0x%llx)",
....., (unsigned long long)(CloseHandle(mh)), .... ), 0)));
ãã³ãã«ãéããŠããŸãããšã©ãŒãçºçããå Žåããããã°ã¡ãã»ãŒãžãçæããããšã©ãŒã³ãŒããå床ååŸããããã«ãåãç¡å¹ãªãã³ãã«ã«å¯ŸããŠCloseHandleãåŒã³åºãããŸãã
ãšã©ãŒãçš®é¡ãããã³ãããããã³ãã«ãç¡å¹ã§ãããããCloseHandle颿°ã2ååŒã³åºãããŠãåé¡ãããŸããããã ãããã®ã³ãŒãã¯ç¡èã§ãã颿°ã1åã ãåŒã³åºããŠãè¿ãããã¹ããŒã¿ã¹ãä¿åããå¿ èŠã«å¿ããŠãã®å€ãã¡ãã»ãŒãžã«è¡šç€ºããæ¹ããããçæ³çã«ã¯æ£ããã§ãããã
å®è£ ã€ã³ã¿ãŒãã§ã€ã¹ã®äžæŽåïŒconstã®åé€ïŒ
static int
status_push(PMEMpoolcheck *ppc, struct check_status *st, uint32_t question)
{
....
} else {
status_msg_info_and_question(st->msg); // <=
st->question = question;
ppc->result = CHECK_RESULT_ASK_QUESTIONS;
st->answer = PMEMPOOL_CHECK_ANSWER_EMPTY;
PMDK_TAILQ_INSERT_TAIL(&ppc->data->questions, st, next);
}
....
}
ã¢ãã©ã€ã¶ãŒã¯æ¬¡ã®ã¡ãã»ãŒãžã衚瀺ããŸããV530[CWE-252]颿° 'status_msg_info_and_question'ã®æ»ãå€ã䜿çšããå¿ èŠããããŸããcheck_util.c 293
ãã®çç±ã¯ãstatus_msg_info_and_question颿°ã¯ãã¢ãã©ã€ã¶ãŒã®èгç¹ããã¯ãæž¡ããã宿°æååãå«ããå€éšã®ãªããžã§ã¯ãã®ç¶æ ã倿Žããªãããã§ãããããããã®é¢æ°ã¯äœããèšç®ããŠçµæãè¿ãã ãã§ãããããããªãããã®é¢æ°ãè¿ãçµæã䜿çšããªãã®ã¯å¥åŠã§ãããããŠãä»åã¯ã¢ãã©ã€ã¶ãŒãééã£ãŠããŸãããèãã®ããã³ãŒããæããŠããŸããåŒã³åºãããstatus_msg_info_and_question颿°ãã©ã®ããã«æ©èœããããèŠãŠã¿ãŸãããã
static inline int
status_msg_info_and_question(const char *msg)
{
char *sep = strchr(msg, MSG_SEPARATOR);
if (sep) {
*sep = ' ';
return 0;
}
return -1;
}
strchr 颿°ãåŒã³åºããšã宿°ã®æé»çãªåé€ãçºçããŸããå®éã®ãšãããCã§ã¯æ¬¡ã®ããã«å®£èšãããŠããŸãã
char * strchr ( const char *, int );
æåã®è§£æ±ºçã§ã¯ãããŸãããããããCèšèªã¯ãããäœã§ãããã§ã:)ã
ã¢ãã©ã€ã¶ãŒã¯æ··ä¹±ããæž¡ãããæååãå®éã«å€æŽãããŠããããšãçè§£ããŸããã§ããããããããªããæ»ãå€ã¯æãéèŠãªããšã§ã¯ãªããããªãã¯ããã䜿ãããšãã§ããŸããã
ãã ããã¢ãã©ã€ã¶ãŒã¯æ··ä¹±ããŠããŸãããèãã®ããã³ãŒããæããŠããŸããããŒãµãŒãæ··ä¹±ããããã®ã¯ãã³ãŒãã管çããäººãæ··ä¹±ãããå¯èœæ§ããããŸããconstãåé€ããŠã颿°ãããæ£çŽã«å®£èšããããšããå§ãããŸãã
static inline int
status_msg_info_and_question(char *msg)
{
char *sep = strchr(msg, MSG_SEPARATOR);
if (sep) {
*sep = ' ';
return 0;
}
return -1;
}
ãããã£ãŠãæå³ã¯ããã«æç¢ºã«ãªããã¢ãã©ã€ã¶ãŒã¯ç¡é³ã«ãªããŸãã
è€éãããã³ãŒã
static struct memory_block
heap_coalesce(struct palloc_heap *heap,
const struct memory_block *blocks[], int n)
{
struct memory_block ret = MEMORY_BLOCK_NONE;
const struct memory_block *b = NULL;
ret.size_idx = 0;
for (int i = 0; i < n; ++i) {
if (blocks[i] == NULL)
continue;
b = b ? b : blocks[i];
ret.size_idx += blocks[i] ? blocks[i]->size_idx : 0;
}
....
}
PVS-StudioèŠåïŒV547 [CWE-571]åŒ 'ãããã¯[i]'ã¯åžžã«çã§ããheap.c 1054
å Žåã¯ãããã¯[i]ã== NULLãããã®åŸãç¶ç¶æãããªã¬ãããã«ãŒããæ¬¡ã®å埩ãéå§ããŸãããããã£ãŠãèŠçŽ ãããã¯[i]ãåãã§ãã¯ããããšã¯æå³ããªãã3倿Œç®åã¯äžèŠã§ããã³ãŒãã¯åçŽåã§ããŸãã
....
for (int i = 0; i < n; ++i) {
if (blocks[i] == NULL)
continue;
b = b ? b : blocks[i];
ret.size_idx += blocks[i]->size_idx;
}
....
nullãã€ã³ã¿ã®çããã䜿çš
void win_mmap_fini(void)
{
....
if (mt->BaseAddress != NULL)
UnmapViewOfFile(mt->BaseAddress);
size_t release_size =
(char *)mt->EndAddress - (char *)mt->BaseAddress;
void *release_addr = (char *)mt->BaseAddress + mt->FileLen;
mmap_unreserve(release_addr, release_size - mt->FileLen);
....
}
PVS-StudioèŠåïŒV1004 [CWE-119] nullptrã«å¯ŸããŠæ€èšŒãããåŸã 'ïŒchar *ïŒmt-> BaseAddress'ãã€ã³ã¿ãŒãå®å šã«äœ¿çšãããŸããã§ãããã©ã€ã³ãã§ãã¯ïŒ226ã235 win_mmap.c 235ã¯MT-> BASEADDRESSãã€ã³ã¿ã®ãã§ãã¯ã«ãã蚌æãããããã«ãnullã«ãªãããšãã§ããŸãã
if (mt->BaseAddress != NULL)
ãã ãããã®ãã€ã³ã¿ã®äžã§ã¯ããã§ãã¯ãªãã®ç®è¡æŒç®ã§ãã§ã«äœ¿çšãããŠããŸããããšãã°ãããã§ïŒ
size_t release_size =
(char *)mt->EndAddress - (char *)mt->BaseAddress;
ããã€ãã®å€§ããªæŽæ°å€ãåä¿¡ãããŸããããã¯ãå®éã«ã¯mt-> EndAddressãã€ã³ã¿ãŒã®å€ã§ããããã¯ãã°ã§ã¯ãªããããããŸãããããã¹ãŠéåžžã«çãããããã«èŠããã³ãŒããåãã§ãã¯ããå¿ èŠãããããã«æãããŸããåãã¯ãã³ãŒããçè§£ã§ãããæããã«èª¬æçãªã³ã¡ã³ãããªããšããäºå®ã«ãããŸãã
ã°ããŒãã«å€æ°ã®ççž®å
çãååã®ã°ããŒãã«å€æ°ãå«ãŸããŠãããšãã³ãŒãã®èããããã®ã§ã¯ãªãããšæããŸããå°å°ããã®ã¯ç°¡åã§ã誀ã£ãŠããŒã«ã«ã§ã¯ãªãã°ããŒãã«å€æ°ãäžéšã®é¢æ°ã§äœ¿çšããŸããäŸïŒ
static struct critnib *c;
ãã®ãããªå€æ°ã«å¯ŸããPVS-Studioã®èŠåïŒ
- V707ã°ããŒãã«å€æ°ã«çãååãä»ããããšã¯æªãç¿æ £ãšèŠãªãããŸãã'ri'倿°ã®ååã倿Žããããšããå§ãããŸããmap.c 131
- V707ã°ããŒãã«å€æ°ã«çãååãä»ããããšã¯æªãç¿æ £ãšèŠãªãããŸãã'c'倿°ã®ååã倿Žããããšããå§ãããŸããobj_critnib_mt.c 56
- V707ã°ããŒãã«å€æ°ã«çãååãä»ããããšã¯æªãç¿æ £ãšèŠãªãããŸãã'Id'倿°ã®ååã倿Žããããšããå§ãããŸããobj_list.h 68
- V707ã°ããŒãã«å€æ°ã«çãååãä»ããããšã¯æªãç¿æ £ãšèŠãªãããŸãã'Id'倿°ã®ååã倿Žããããšããå§ãããŸããobj_list.c 34
å¥åŠãª

ç§ãééããæãå¥åŠãªã³ãŒãã¯ãdo_memmove颿°ã«ãããŸããã¢ãã©ã€ã¶ãŒã¯2ã€ã®ããžãã£ãã瀺ããŸãããããã¯ãéåžžã«æ·±å»ãªãšã©ãŒããç§ãäœãæå³ããã®ãçè§£ããŠããªãããšã瀺ããŠããŸããã³ãŒããéåžžã«å¥åŠãªã®ã§ãèšäºã®å¥ã®ã»ã¯ã·ã§ã³ã§çºè¡ãããèŠåãæ€èšããããšã«ããŸããããããã£ãŠãæåã®èŠåãããã§çºè¡ãããŸãã
void
do_memmove(char *dst, char *src, const char *file_name,
size_t dest_off, size_t src_off, size_t bytes,
memmove_fn fn, unsigned flags, persist_fn persist)
{
....
/* do the same using regular memmove and verify that buffers match */
memmove(dstshadow + dest_off, dstshadow + dest_off, bytes / 2);
verify_contents(file_name, 0, dstshadow, dst, bytes);
verify_contents(file_name, 1, srcshadow, src, bytes);
....
}
PVS-StudioèŠåïŒV549 [CWE-688] 'memmove'颿°ã®æåã®åŒæ°ã2çªç®ã®åŒæ°ãšåãã§ããmemmove_common.c71
颿°ã®æåã®åŒæ°ãš2çªç®ã®åŒæ°ãåãã§ããããšã«æ³šæããŠãã ããããããã£ãŠããã®é¢æ°ã¯å®éã«ã¯äœãããŸãããã©ã®ãããªãªãã·ã§ã³ãæãæµ®ãã³ãŸããïŒ
- ã¡ã¢ãªãããã¯ã«ãè§Šããããã£ãã®ã§ããããããããã¯å®éã«èµ·ãããŸããïŒæé©åã³ã³ãã€ã©ã¯ãã¡ã¢ãªãããã¯ãããèªäœã«ã³ããŒããã³ãŒããåé€ããŸããïŒ
- ããã¯ãmemmove颿°ã®ããçš®ã®ãŠããããã¹ãã§ãã
- ã³ãŒãã«ã¿ã€ããã¹ãå«ãŸããŠããŸãã
ãããŠãããã¯åã颿°å ã®åæ§ã«å¥åŠãªã¹ããããã§ãïŒ
void
do_memmove(char *dst, char *src, const char *file_name,
size_t dest_off, size_t src_off, size_t bytes,
memmove_fn fn, unsigned flags, persist_fn persist)
{
....
/* do the same using regular memmove and verify that buffers match */
memmove(dstshadow + dest_off, srcshadow + src_off, 0);
verify_contents(file_name, 2, dstshadow, dst, bytes);
verify_contents(file_name, 3, srcshadow, src, bytes);
....
}
PVS-StudioèŠåïŒV575 [CWE-628]ãmemmoveã颿°ã¯ã0ãèŠçŽ ãåŠçããŸãã3çªç®ã®åŒæ°ã調ã¹ãŸããmemmove_common.c82
颿°ã¯0ãã€ããç§»åããŸããããã¯äœã§ããïŒåäœãã¹ãïŒæã¡ééãïŒ
ç§ã«ãšã£ãŠããã®ã³ãŒãã¯çè§£ã§ãããå¥åŠã§ãã
ãªãã³ãŒãã¢ãã©ã€ã¶ãŒã䜿çšããã®ã§ããïŒ
ãšã©ãŒãã»ãšãã©èŠã€ãã£ãŠããªããããã³ãŒãéçºããã»ã¹ã«ã¢ãã©ã€ã¶ãŒãå°å ¥ããã®ã¯äžåçã«æãããããããŸããããã ããéçåæããŒã«ã䜿çšãããã€ã³ãã¯ã1åéãã®ãã§ãã¯ã§ã¯ãªããã³ãŒãã®èšè¿°æ®µéã§ã®ãšã©ãŒã®å®æçãªæ€åºã«ãããŸãããã以å€ã®å Žåããããã®ãšã©ãŒã¯ãããé«äŸ¡ã§äœéãªæ¹æ³ïŒãããã°ããã¹ãããŠãŒã¶ãŒã¬ãã¥ãŒãªã©ïŒã§æ€åºãããŸãããã®ã¢ã€ãã¢ã«ã€ããŠã¯ããéçã³ãŒãåæã䜿çšãããŠããªãããã«æ€åºã§ããªããšã©ãŒããšããèšäºã§è©³ãã説æãããŠããŸãããã®èšäºãããçè§£ããŠããããšããå§ãããŸããæ¬¡ã«ãåœç€Ÿã®Webãµã€ãã«ã¢ã¯ã»ã¹ããŠãPVS-StudioãããŠã³ããŒãããŠè©ŠããŠãããžã§ã¯ãã確èªããŠãã ããã
æž èŽããããšãããããŸããïŒ

ãã®èšäºãè±èªã話ãèŽè¡ãšå ±æãããå Žåã¯ã翻蚳ãªã³ã¯ã䜿çšããŠãã ããïŒAndreyKarpovãIntelã«ããPMDKã©ã€ãã©ãªã³ã¬ã¯ã·ã§ã³ã®éçã³ãŒãåæãšå®éã®ãšã©ãŒã§ã¯ãªããšã©ãŒã