<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt, branch 2026_07_16.090d739</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<entry>
<title>passt.1, pesto.1: ::1 is an address, not a port</title>
<updated>2026-07-16T08:47:00+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2026-07-15T23:14:38+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=090d739bd16ed0d810bf2fe9603229aad74adc62'/>
<id>090d739bd16ed0d810bf2fe9603229aad74adc62</id>
<content type='text'>
Fixes: 4e09ddf03443 ("conf: Allow user-specified auto-scanned port forwarding ranges")
Fixes: cbd58d631db9 ("pesto: Parse and add new rules from command line")
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fixes: 4e09ddf03443 ("conf: Allow user-specified auto-scanned port forwarding ranges")
Fixes: cbd58d631db9 ("pesto: Parse and add new rules from command line")
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>dhcp: Make option parsing more robust, explicitly handle options 0 and 255</title>
<updated>2026-07-16T08:46:22+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2026-07-15T22:56:23+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=7d0c07728813880d6049abb3dc33dcaf8154ff66'/>
<id>7d0c07728813880d6049abb3dc33dcaf8154ff66</id>
<content type='text'>
The initial option-scanning loop in dhcp(), so far, ignored options 0
(Pad Option, RFC 2132, Section 3.1) and 255 (End Option, RFC 2132,
Section 3.2).

As a result:

- if we ever encountered option 0 in the middle of option fields
  (never seen in practice), we would potentially terminate the loop
  too early, before scanning remaining options

- a malformed message with an option 255 followed by a length byte
  would (reliably) cause us to terminate as we would exceed the
  allocated size for the 'opts' array, which is detected as buffer
  overflow by the FORTIFY_SOURCE mechanism

The latter was reported as potential vulnerability by AISLE, but it's
not actually a vulnerability as we always terminate without carrying
on further handling, and in our security model the guest is able to
sabotage its own connectivity in any case (for example, a malformed
frame from the hypervisor would cause us to reset the connection, or
entirely flooding the flow table would cause inbound connectivity to
stop working, etc.).

The reported behaviour, however, is indeed a defect, as it affects
the functional robustness to a hypothetical issue in a DHCP client,
and that's something we definitely want to fix.

Make the option parsing loop more robust by:

- resizing 'opts' from 255 to 256 elements: there's no particular
  reason to try to save a tiny bit of memory (which shouldn't even
  be allocated in practice) instead of being defensive about it

- explicitly handle options 0 (skip one byte, continue) and 255 (stop
  processing options) in the option-scanning loop

- scanning the last two bytes of options as well and using
  iov_tail_size(data) directly as loop condition, instead of a rather
  inconsistent usage of opt_len

This bug was found and an initial version of the patch was written by
the AISLE AI security scanning tool (https://aisle.com/platform).

Reported-by: AISLE
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The initial option-scanning loop in dhcp(), so far, ignored options 0
(Pad Option, RFC 2132, Section 3.1) and 255 (End Option, RFC 2132,
Section 3.2).

As a result:

- if we ever encountered option 0 in the middle of option fields
  (never seen in practice), we would potentially terminate the loop
  too early, before scanning remaining options

- a malformed message with an option 255 followed by a length byte
  would (reliably) cause us to terminate as we would exceed the
  allocated size for the 'opts' array, which is detected as buffer
  overflow by the FORTIFY_SOURCE mechanism

The latter was reported as potential vulnerability by AISLE, but it's
not actually a vulnerability as we always terminate without carrying
on further handling, and in our security model the guest is able to
sabotage its own connectivity in any case (for example, a malformed
frame from the hypervisor would cause us to reset the connection, or
entirely flooding the flow table would cause inbound connectivity to
stop working, etc.).

The reported behaviour, however, is indeed a defect, as it affects
the functional robustness to a hypothetical issue in a DHCP client,
and that's something we definitely want to fix.

Make the option parsing loop more robust by:

- resizing 'opts' from 255 to 256 elements: there's no particular
  reason to try to save a tiny bit of memory (which shouldn't even
  be allocated in practice) instead of being defensive about it

- explicitly handle options 0 (skip one byte, continue) and 255 (stop
  processing options) in the option-scanning loop

- scanning the last two bytes of options as well and using
  iov_tail_size(data) directly as loop condition, instead of a rather
  inconsistent usage of opt_len

This bug was found and an initial version of the patch was written by
the AISLE AI security scanning tool (https://aisle.com/platform).

Reported-by: AISLE
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>CONTRIBUTING.md: The tag is "Link:", regardless of how many we have</title>
<updated>2026-07-16T07:17:02+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2026-07-15T22:55:32+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=10847ad7f1fe1b4b78f8ee638df2865ead5e329f'/>
<id>10847ad7f1fe1b4b78f8ee638df2865ead5e329f</id>
<content type='text'>
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>udp_vu: Check iov_tail_clone() return before assigning to msg_iovlen</title>
<updated>2026-07-15T21:18:51+00:00</updated>
<author>
<name>Jon Maloy</name>
<email>jmaloy@redhat.com</email>
</author>
<published>2026-07-09T21:56:52+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=a3b9f86f39a7effc2d74833055c23bee54887894'/>
<id>a3b9f86f39a7effc2d74833055c23bee54887894</id>
<content type='text'>
iov_tail_clone() returns ssize_t and can return -1 if the destination
iov array is too small. Its return value was assigned directly to
msg.msg_iovlen which is size_t, wrapping a negative value to a large
unsigned number passed to recvmsg().

Check for failure and return early, letting the caller rewind the
virtqueue.

Signed-off-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
iov_tail_clone() returns ssize_t and can return -1 if the destination
iov array is too small. Its return value was assigned directly to
msg.msg_iovlen which is size_t, wrapping a negative value to a large
unsigned number passed to recvmsg().

Check for failure and return early, letting the caller rewind the
virtqueue.

Signed-off-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>passt: Initialise listening socket fds to -1</title>
<updated>2026-07-15T21:18:38+00:00</updated>
<author>
<name>Jon Maloy</name>
<email>jmaloy@redhat.com</email>
</author>
<published>2026-07-09T21:56:51+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=80cb5cf5a9b1b16a30c8ae4c47a87c8bfc91f20c'/>
<id>80cb5cf5a9b1b16a30c8ae4c47a87c8bfc91f20c</id>
<content type='text'>
fd_tap_listen, fd_control_listen, and fd_repair_listen are file
descriptors and should be initialised to -1 rather than the implicit
0, consistent with the other fd fields in passt_ctx.

Signed-off-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
fd_tap_listen, fd_control_listen, and fd_repair_listen are file
descriptors and should be initialised to -1 rather than the implicit
0, consistent with the other fd fields in passt_ctx.

Signed-off-by: Jon Maloy &lt;jmaloy@redhat.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>fwd: Don't rewrite inbound multicast destinations</title>
<updated>2026-07-14T23:22:47+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-13T05:38:56+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=fc6c774f6705800cc9409713e678001ca6c4a581'/>
<id>fc6c774f6705800cc9409713e678001ca6c4a581</id>
<content type='text'>
fwd_nat_from_host() (nearly) always rewrites the destination address for
inbound flows to the observed guest address.  Usually, that makes sense:
regardless of the host address to which the new flow arrived, we want to
direct it to the guest.  However, that clearly does not make sense for
multicast - it should still appear as a multicast transmission to the
guest.

In particular this can work very badly for multicast protocols which use
the same source and destination ports by convention (e.g. mDNS).  In this
case, we will attempt to forword multicast packets to our own socket,
causing a forwarding loop (see bug 209 for more details).

While it's certainly not enough to make us handle multicast correctly in
all circumstances, not translating multicast destinations is closer to
correct, and prevents bug 209 at least.

Link: https://bugs.passt.top/show_bug.cgi?id=209
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
fwd_nat_from_host() (nearly) always rewrites the destination address for
inbound flows to the observed guest address.  Usually, that makes sense:
regardless of the host address to which the new flow arrived, we want to
direct it to the guest.  However, that clearly does not make sense for
multicast - it should still appear as a multicast transmission to the
guest.

In particular this can work very badly for multicast protocols which use
the same source and destination ports by convention (e.g. mDNS).  In this
case, we will attempt to forword multicast packets to our own socket,
causing a forwarding loop (see bug 209 for more details).

While it's certainly not enough to make us handle multicast correctly in
all circumstances, not translating multicast destinations is closer to
correct, and prevents bug 209 at least.

Link: https://bugs.passt.top/show_bug.cgi?id=209
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>fwd: Reorder DNAPT and SNAT steps in fwd_nat_from_host()</title>
<updated>2026-07-14T23:22:47+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-13T05:38:55+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=9013b5911f5f53d34e6e1a2f4683c616a13d2209'/>
<id>9013b5911f5f53d34e6e1a2f4683c616a13d2209</id>
<content type='text'>
The order in which we translate source and destination addresses is a bit
unclear in fwd_nat_from_host().  Reorder things to make it clearer:
   1. Pick guest-side destination address, where options require it
   2. Pick guest-side source address (needs to be different for SPLICE and
      TAP)
   3. If (1) didn't determine destination, pick a fallback to match family
      and scope of source address from (2).

As a small bonus this lets us make step (1) common between SPLICE and TAP
paths.  The value of this is a bit dubious right now, but it will make some
future changes clearer.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The order in which we translate source and destination addresses is a bit
unclear in fwd_nat_from_host().  Reorder things to make it clearer:
   1. Pick guest-side destination address, where options require it
   2. Pick guest-side source address (needs to be different for SPLICE and
      TAP)
   3. If (1) didn't determine destination, pick a fallback to match family
      and scope of source address from (2).

As a small bonus this lets us make step (1) common between SPLICE and TAP
paths.  The value of this is a bit dubious right now, but it will make some
future changes clearer.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>fwd: Rework default address logic for inbound flows</title>
<updated>2026-07-14T23:22:47+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-13T05:38:54+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=addd76dd9bc4306aa620bb0177d63368a24dc59d'/>
<id>addd76dd9bc4306aa620bb0177d63368a24dc59d</id>
<content type='text'>
fwd_nat_from_host() needs to determine the guest side destination address
for the new flow.  In some cases that's controlled by the forwarding rule
or --host-lo-to-ns-lo logic, but by default we use the observed guest
address.  We need to pick the right one to match the source address,
though.

Currently this is done with similar, but not quite identical logic in the
spliced and non-spliced paths.  Introduce a new fwd_default_guest_addr()
helper to make explicit:
 * We have the same logic for splice and tap paths
 * This is a fallback path if nothing else determined the address (we
   use this default nearly all the time now, but it might change in future)
 * We're matching IP family and scope with the guest side source address

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
fwd_nat_from_host() needs to determine the guest side destination address
for the new flow.  In some cases that's controlled by the forwarding rule
or --host-lo-to-ns-lo logic, but by default we use the observed guest
address.  We need to pick the right one to match the source address,
though.

Currently this is done with similar, but not quite identical logic in the
spliced and non-spliced paths.  Introduce a new fwd_default_guest_addr()
helper to make explicit:
 * We have the same logic for splice and tap paths
 * This is a fallback path if nothing else determined the address (we
   use this default nearly all the time now, but it might change in future)
 * We're matching IP family and scope with the guest side source address

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>udp: Validate that we have a unicast source address</title>
<updated>2026-07-14T23:22:47+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-13T05:38:53+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=66fdabd85c3eac3a87979f05484de2c90af9a272'/>
<id>66fdabd85c3eac3a87979f05484de2c90af9a272</id>
<content type='text'>
When creating a UDP flow from a socket we, correctly, check that the source
address is unicast - multicast addresses are not valid as a source address.
However, when creating a flow from tap we only check the source address
is specified, not that it is unicast.  Correct this.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When creating a UDP flow from a socket we, correctly, check that the source
address is unicast - multicast addresses are not valid as a source address.
However, when creating a flow from tap we only check the source address
is specified, not that it is unicast.  Correct this.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>fwd: Clarify semantics of --host-lo-to-ns-lo</title>
<updated>2026-07-14T23:22:40+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-13T05:38:52+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=26f2130de6dc3bba45bfab435531d909d219f7a6'/>
<id>26f2130de6dc3bba45bfab435531d909d219f7a6</id>
<content type='text'>
The semantics of --host-lo-to-ns-lo as described in the man page don't
quite make sense: It says without the option forwarded packets will appear
to come _from_ the guest's public address, which is not usually true.
Instead the packets will arrive *to* the guest's public address.  The exact
semantics are also a bit confusing in general.

Rewrite both the man page and code to clarify this.  The new rule is that
it redirects connections addressed to a host loopback address to the same
loopback address in the guest.  This is notionally different from what we
had in two ways:
  * We can now deliver to nonstandard loopback addresses within the guest,
    not just the default one.  This is technically a behavioural change,
    but I think will be less surprising behaviour.
  * The decision is now made on the original _destination_ address, rather
    than source address.  That's different theoretically, but not in
    practice, since loopback packets must have loopback addresses for both
    source and destination.

We make it explicitly incompatible with --no-splice - previously it
was allowed, but would have no effect in that case.

As well as being more precise right now, these semantics will intersect
better with other upcoming changes to the forwarding logic.

Link: https://bugs.passt.top/show_bug.cgi?id=212
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The semantics of --host-lo-to-ns-lo as described in the man page don't
quite make sense: It says without the option forwarded packets will appear
to come _from_ the guest's public address, which is not usually true.
Instead the packets will arrive *to* the guest's public address.  The exact
semantics are also a bit confusing in general.

Rewrite both the man page and code to clarify this.  The new rule is that
it redirects connections addressed to a host loopback address to the same
loopback address in the guest.  This is notionally different from what we
had in two ways:
  * We can now deliver to nonstandard loopback addresses within the guest,
    not just the default one.  This is technically a behavioural change,
    but I think will be less surprising behaviour.
  * The decision is now made on the original _destination_ address, rather
    than source address.  That's different theoretically, but not in
    practice, since loopback packets must have loopback addresses for both
    source and destination.

We make it explicitly incompatible with --no-splice - previously it
was allowed, but would have no effect in that case.

As well as being more precise right now, these semantics will intersect
better with other upcoming changes to the forwarding logic.

Link: https://bugs.passt.top/show_bug.cgi?id=212
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
