Files
RedBear-OS/netstack/src/link
Red Bear OS 3101345fe6 review: NDP state corruption fix, port double-free fix, observer limits
CRITICAL/MEDIUM BUGS FIXED:

1. ethernet.rs send_ndp_solicit: state corruption via recursive call
   The function destructured self.ndp_state by value (target, tries,
   silent_until) at the start and wrote back at the end. But between
   destructuring and writing back, self.drop_waiting_packets_v6(target)
   could recursively call self.send_ndp_solicit(Instant::ZERO) for a
   different target. The recursive call updated self.ndp_state with the
   new target's state. When control returned to the original frame, the
   original write-back clobbered the recursive call's state, silently
   losing neighbor discovery for the new target.
   Fix: use scoped pattern matches to read target/tries/silent_until
   from the live state right before they are needed, so the recursive
   call's writes are preserved. This matches the pattern used by
   send_arp (which uses ref mut and is correct).

2. scheme/socket.rs on_close: port double-free
   close_file() was called before the refcount check, so the port was
   released on every close. For a dup'd socket, the second close
   tried to release the port again — double-free.
   Fix: compute the new refcount first, only call close_file and
   remove from socket_set when the count reaches 0 (last reference).

3. scheme/tcp.rs new_socket: port + socket leak on connect failure
   If get_port() succeeded but connect() later failed, the port was
   claimed and the socket was added to socket_set, but new_socket
   returned Err. The caller (open_inner) did not insert the file
   handle, so on_close was never called. Both the port and the socket
   slot leaked.
   Fix: when connect() fails, release the auto-allocated port before
   returning. Explicit user-provided ports are still released by
   on_close when the last file is dropped (preserves the existing
   on_close-based release).

4. observer.rs capture: per-packet size limit not enforced
   Vec::with_capacity only pre-allocates; extend_from_slice copies the
   full packet. The intended per-packet limit (MAX_CAPTURE_BYTES /
   max_packets = 256 bytes) was being bypassed, allowing a single
   1500-byte packet to consume the full capture buffer.
   Fix: truncate to per_packet_limit before extending.

5. observer.rs capture: short packets bypassed filter
   Packets < 20 bytes returned true (capture anyway) regardless of
   the user's filter. A filter like 'tcp port 80' would capture all
   short packets, including non-TCP.
   Fix: return false (no match) for short packets. Filter semantics
   are now consistent: if a packet can't be matched, it's not captured.

All 29 existing tests still pass.
2026-07-09 00:42:46 +03:00
..