Call to a non-reentrant POSIX function

ID

objectivec.correctness.mt_unsafe

Severity

low

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

medium

Resource

Concurrency

Language

Objective-C

Description

Reports a call to a POSIX or libc function that is documented as non-reentrant - the random number generators, strtok, strerror, the getpw*/getgr* account lookups, the gethost*/getserv*/getproto* resolvers, readdir, crypt, inet_ntoa and the ecvt/fcvt/gcvt converters. The _r variants and the Objective-C and arc4random alternatives are not reported. The date and time family is reported separately by avoid-time-h, getenv and system by avoid-stdlib-process-functions, and tmpnam by avoid-stdio.

Rationale

Each of these functions keeps its result, or its iteration state, in a single buffer shared by the whole process. A second thread that calls the same function overwrites that buffer while the first thread still holds a pointer into it, so the first thread reads another thread’s answer - the wrong account, the wrong host, another strtok cursor - with no error returned anywhere. The generators are worse than wrong: rand and random mutate one global seed, so concurrent callers can be handed the same value. None of this shows up under light load, which is why it survives testing and appears as an unreproducible defect once a queue starts running the code concurrently.

The following code illustrates the pattern detected by this rule:

@implementation Session
- (NSArray *)splitFields:(char *)line {
    // FLAGGED: Call to a non-reentrant POSIX function
    char *field = strtok(line, ",");
    while (field) {
        // FLAGGED: Call to a non-reentrant POSIX function
        field = strtok(NULL, ",");
    }
    return @[];
}
@end

Remediation

Call the _r variant, which takes a caller-supplied buffer - strtok_r, strerror_r, getpwnam_r, getlogin_r, readdir_r - or the Objective-C equivalent, which never shares state: NSString componentsSeparatedByString: for strtok, NSError for strerror, NSHost or getaddrinfo for gethostbyname, NSFileManager for readdir. Replace rand, random and the drand48 family with arc4random_uniform, which needs no seed and is thread-safe.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved