Hacker News new | ask | show | jobs
by wahern 25 days ago
> Now, is it exploitable that `find` also reads the uninitialized auto variable `status` (UB) from a `waitpid(&status)` before checking if `waitpid()` returned error? (not reported) I can't imagine an architecture or compiler where it would be, no.

I presume you're referring to this code:

  pid = waitpid(pid, &status, 0);
  if (WIFEXITED(status))
    rval = WEXITSTATUS(status);
  else
    rval = -1;
The only signal handler find installs is for SIGINFO, and it uses the SA_RESTART flag, so EINTR can be ruled out. The pid argument is definitely valid as you can't reach the above if it wasn't, and there's no other way for the child process to be reaped[1], so no ECHILD.

A check should probably be added in case the situation changes in the future, triggering spooky action at a distance, or were that code to be copy+pasted somewhere where the invariants didn't hold. But I think the current code in its current context is, strictly speaking, correct as-is.

[1] OpenBSD lacks the kernel features for such surprises that might theoretically be possible on Linux.

2 comments

Indeed. That's why I didn't deem it worth reporting.

But in my code, I would have fixed for the reasons you mention. Sprinkle enough of these around, and some low percentage will in the future have its assumption invalidated.

Couldn’t waitpid return EINTR if the (parent) process were stopped and then continued?

EINTR scares the crap out of me because nobody expects it!

No. You only get EINTR when a signal handler fires and you didn't use the SA_RESTART flag with sigaction. If you don't install any signal handlers, or you use SA_RESTART on all handlers, or you've blocked/masked all signals (or at least the ones with handlers), you won't get EINTR.

When writing library code, it's important to consider EINTR because you can't know about signal dispositions. Though, the common practice of looping on EINTR kind of defeats the purpose.