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).