Scanning in thread

Vulnerability potential None
DDoS potential Low

Scanning in a thread is not encouraged

Impact

Reading interactive input (scanf, std::cin, fgets on stdin) from a worker thread is discouraged. The standard input stream is a single shared resource with no notion of “which thread the line belongs to”: if more than one thread reads it, input is split between them non-deterministically, and a blocking read parks the thread indefinitely with no clean way to cancel it. A pool worker that blocks on scanf is effectively removed from the pool until a line arrives, which may be never.

This is mainly a design defect — input handling belongs in one place (usually the main thread or a dedicated reader) — but it also creates real liveness problems: threads stuck in a blocking read at shutdown prevent the program from exiting cleanly.

Vulnerability potential

There is no direct security exposure here: consuming bytes from stdin does not corrupt memory or cross a trust boundary by itself. The only practical risk is liveness — a thread blocked forever on input ties up a worker and can stall shutdown or exhaust the pool — which is why the DoS rating is Low and the vulnerability rating is None. (A scanf("%s", buf) with no width would be a separate buffer-overflow defect, not this one.)

Technical details

Blocking, uncancellable reads

scanf/cin on a terminal or pipe block until data arrives or EOF. A blocked thread holds its stack and any resources it owns; there is no portable way to interrupt a thread parked in a blocking read(2) other than closing the fd or sending a signal, both of which are awkward and racy.

Shared stream, split input

Per POSIX the FILE is locked per call, so a single scanf is internally consistent, but two threads each calling scanf race for whatever the user types: one gets some fields, the other gets the rest, so neither parses what the user intended. The buffered nature of stdio makes the split even less predictable.

Format/state hazards

A failed conversion leaves the offending characters in the buffer; with several threads reading, recovering from a parse error (clearing the stream) becomes unreliable because another thread may consume the very characters you tried to discard.

Catching the issue

Static analysis / linters

The analyzer emitting this diagnostic flags scanf/fscanf(stdin, …)/std::cin usage in functions executed off the main thread. Review rules can forbid console input outside a single designated reader.

Centralize input

Read all interactive input in one place (the main thread or one reader thread) and hand parsed values to workers through a queue. Workers should never touch stdin.

Make reads cancellable

Where a thread must wait on input, use non-blocking I/O with poll/select plus a self-pipe or eventfd so the wait can be woken at shutdown, instead of a bare blocking scanf.

How to reproduce

Run this with two threads reading stdin: type several numbers and observe that the values are split between the threads unpredictably, and that the program will not exit until both blocking reads happen to receive input.

#include <iostream>
#include <thread>

void reader(int id)
{
    int x;
    while (std::cin >> x)            // blocking read on the shared stream
        std::cout << "thread " << id << " got " << x << "\n";
}

int main()
{
    std::thread a(reader, 1), b(reader, 2);
    a.join();
    b.join();
    return 0;
}