I've identified a byte-order bug in libslirp's check_guestfwd() function:
libslirp/src/slirp.c lines 1094-1099
1094 │ /* check if the port is "bound" */
1095 │ for (tmp_ptr = slirp->guestfwd_list; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
1096 │ if (guest_port == tmp_ptr->ex_fport &&
1097 │ guest_addr->s_addr == tmp_ptr->ex_addr.s_addr)
1098 │ return false;
1099 │ }
This compares:
- guest_port (int in host byte order)
- tmp_ptr->ex_fport (int containing a value in network byte order from htons())
The comparison is byte-order incorrect and causes false positives when:
- Port A is stored as htons(A)
- Later, port B is checked where B equals the numeric value of htons(A) when interpreted as a host-order integer
Example:
Ports 21075 and 21330 are byte-swapped versions of each other on little-endian (x86):
- htons(21075) = 0x5352 = 21330 when interpreted as host-order int
- htons(21330) = 0x5253 = 21075 when interpreted as host-order int
When QEMU adds these as guestfwd rules:
- Adds port 21330 → stores htons(21330) = value that looks like 21075
- Tries to add port 21075 → compares 21075 == 21075 → FALSE CONFLICT!
I've identified a byte-order bug in libslirp's check_guestfwd() function:
This compares:
The comparison is byte-order incorrect and causes false positives when:
Example:
Ports 21075 and 21330 are byte-swapped versions of each other on little-endian (x86):
When QEMU adds these as guestfwd rules: