Skip to content

VNX-663: Use of a Non-reentrant Function in a Concurrent Context

Reports Java static fields of non-thread-safe types (SimpleDateFormat, DecimalFormat, MessageDigest, Cipher, Mac, Matcher...) and C/C++ calls to static-buffer libc functions (strtok, localtime, gmtime, getpwuid, gethostbyname...) in files that start threads.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-663
Severity Low
SARIF level note
Kind sast
Languages Java, C, C++
CWE CWE-663
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L
Tags concurrency thread-safety reentrancy cwe-663
Source internal/sast/rules/vnx-663.rego

Overview

VNX-663 maps to CWE-663: Use of a Non-reentrant Function in a Concurrent Context.

  • Java: a static field of type SimpleDateFormat, DateFormat, DecimalFormat, NumberFormat, MessageFormat, ChoiceFormat, MessageDigest, Mac, Cipher, Signature or java.util.regex.Matcher, shared by every thread.
  • C/C++: a call to strtok, localtime, gmtime, ctime, asctime, getpwnam, getpwuid, getgrnam, getgrgid, gethostbyname, gethostbyaddr, getservbyname, getlogin, ttyname, strsignal, ecvt, fcvt, crypt or inet_ntoa (also as std::) in a file that starts threads (pthread_create, std::thread/std::jthread, std::async, CreateThread, _beginthreadex, #pragma omp).

Not reported: ThreadLocal holders, DateTimeFormatter and Pattern (thread-safe), local and instance formatters, a static formatter the same file locks with synchronized (NAME) or uses only inside synchronized methods, the _r variants, member calls and lookalike names, declarations that share a libc name, files that start no threads (a thread marker in a comment does not count), comments and string literals.

Why This Matters

Two threads formatting with one SimpleDateFormat corrupt its internal Calendar and return wrong dates or throw. strtok and localtime keep their state in a static buffer, so one thread’s call silently overwrites another’s result.

What Gets Flagged

private static final SimpleDateFormat ISO = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");   // FLAGGED
private static MessageDigest sha256;                                                       // FLAGGED
char *tok = strtok(line, ",");          /* FLAGGED: file calls pthread_create */
struct tm *t = localtime(&now);         /* FLAGGED */

Remediation

  1. Java: use java.time.format.DateTimeFormatter, a ThreadLocal, or a new instance per call (MessageDigest.getInstance is cheap).
  2. C/C++: use strtok_r, localtime_r, gmtime_r, getpwuid_r, getaddrinfo/inet_ntop.

References

Suppressing this rule

Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):

# nosec vnx-663
// nosec vnx-663

Or record an ignore rule: vulnetix ignore add --rule vnx-663 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-663.rego, cli/internal/sast/docs/vnx-663.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.