https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106283

--- Comment #4 from Xuanyu Chen <xan9xxx at gmail dot com> ---
A quick status update before I start coding.

Plan for closefrom (close_range to follow):

- Add a known_function, kf_closefrom, registered in
  register_known_fd_functions.  Its impl_call_post uses the existing
  get_fd_state helper to get the fd state map, and passes it to a new
  fd_state_machine::on_closefrom.  I chose a known_function over handling
  this in fd_state_machine::on_stmt: the fds to close aren't arguments of
  the call, so we need to walk the whole sm_state_map, and on_stmt can't
  get at it through the public sm_context interface.

- For a lowfd known to be nonnegative, on_closefrom walks the map
  (skipping fds that are already invalid, closed, or stop), collecting
  first and then updating, as malloc_state_machine::on_pop_frame does.
  For each fd it uses eval_condition (fd >= lowfd):
    TRUE    -> closed
    FALSE   -> unchanged
    UNKNOWN -> stop
  I checked with __analyzer_eval that after "if (fd < 0) return;" the
  analyzer can prove fd >= 0, so the common closefrom (0) case works.

- For an unchecked fd (from open () and not yet compared against -1),
  fd >= lowfd may be UNKNOWN.  But if lowfd == 0, then after the call the
  fd is either -1 or closed, so either way it doesn't refer to an open
  file.  In that case I plan to transition it to closed rather than stop.
  This matches on_close, which already does the same for unchecked fds.

Questions:

1. Should close_range go in the same patch, or a follow-up?  I'd like to
   send closefrom first.

2. Is unchecked -> closed acceptable when lowfd == 0?  The downside is that
   if open () actually failed, a later close (fd) would be reported as a
   double-close, even though the fd was never successfully opened.

3. C libraries disagree on a negative lowfd.  glibc clamps it to 0 and
   closes everything.  On NetBSD, closefrom is just fcntl (fd, F_CLOSEM),
   and that fails with EBADF without closing anything.  This also matters
   when the sign of lowfd is unknown, even if fd >= lowfd can be proven
   TRUE.  Should I model the glibc behavior, or handle these cases
   conservatively (e.g. stop tracking the potentially affected fds)?

For the regression test I'll start with the isolated closefrom (0) case
from comment 2; the fd <= 2 path in comment 1 looks like a separate issue
(possibly related to PR 109839).

Reply via email to