review: 4 critical fixes (ICMP queue, refcount, udp panic, vlan send)

CRITICAL BUGS FIXED:

1. router/mod.rs: ICMP errors for Unreachable/Prohibit went to rx_buffer
   (infinite loop back to input) instead of tx_buffer (sent to source).
   Combined Unreachable/Prohibit arms; both now use tx_buffer.

2. scheme/socket.rs dup(): refcount leak in update_with branch.
   OLD code: new_handle.socket_handle() got +2 when update_with was
   Some, but only decremented once on close. Net: SH1 over-counted (+1),
   SH2 (new listening socket from update_with) never tracked at all.
   FIX: in update_with branch, increment refcount of 'socket_handle'
   (the new SH), not new_handle.socket_handle(). The always-run
   increment at the bottom covers new_handle. Both increments serve
   different purposes and are now distinct.

3. scheme/udp.rs: 4 .expect() panic vectors in bind/send/recv.
   'Can't bind', 'Can't send', 'Can't receive', 'Can't recieve' all
   panicked the daemon. Now return EIO via ? operator.

4. link/vlan.rs (and vxlan/gre/ipip already partially fixed in R42):
   send() pushed tagged packets into self.recv_queue, creating a
   self-loop where packets were never delivered. Now drops packets
   with a debug log since no parent device reference exists.

5. link/qdisc.rs: TokenBucket token_add could overflow u64 on long
   elapsed durations. Changed to saturating_mul.

DOC FIX:
6. filter/table.rs docstring example used --sport 1024:65535 (port
   range) but parse_port only accepts single port. Changed example to
   use single port value. Range support is a future enhancement.

All 29 existing tests still pass.
This commit is contained in:
Red Bear OS
2026-07-09 00:29:46 +03:00
parent 46e70a5472
commit baea0e523b
9 changed files with 40 additions and 34 deletions
+8 -3
View File
@@ -834,22 +834,27 @@ where
if let Some((socket_handle, data)) = update_with {
if let SchemeFile::Socket(ref mut file) = *file {
// We replace the socket_handle pointed by file so update the ref_counts
// accordingly
// We replace the socket_handle pointed by file so update
// the ref_counts accordingly.
self.ref_counts
.entry(file.socket_handle)
.and_modify(|e| *e = e.saturating_sub(1))
.or_insert(0);
// Increment refcount of the NEW socket (socket_handle)
// that the file is being updated to point at.
*self
.ref_counts
.entry(new_handle.socket_handle())
.entry(socket_handle)
.or_insert(0) += 1;
file.socket_handle = socket_handle;
file.data = data;
}
}
// Increment refcount for the new_handle fd being inserted.
// This is always done (regardless of update_with) because
// new_handle represents a new fd in the handle table.
*self
.ref_counts
.entry(new_handle.socket_handle())