<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt, branch master</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<entry>
<title>main: Ensure fds 0-2 are populated</title>
<updated>2026-07-18T07:54:37+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-17T05:46:34+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=c80d9db312dfa98909bf3b3a5b2655785cdb3b07'/>
<id>c80d9db312dfa98909bf3b3a5b2655785cdb3b07</id>
<content type='text'>
Usually fds 0-2 are stdin, stdout and stderr.  However, there are certain
use cases where passt can be invoked with one or more of those standard fds
closed.  In those cases, anything we open might be placed in one of the
standard slots.  For the handful of things we open early enough, this can
be a problem because we close fds 0-2 in __daemon(), replacing them with
dupes of /dev/null.

We could avoid closing those fds in __daemon() if they're not standard
streams.  However, leaving things other than the standard streams in fds
0-2 is a footgun: a stray printf() that occurs in a circumstance it
shouldn't could send harmful garbage to a device or socket.  It's also
likely to be confusing if debugging with strace or similar.

To avoid this, fill any missing standard streams with a dupe of /dev/null,
right after isolate_fds().  Since open()ing /dev/null itself could land in
one of those fd 0-2 slots, we need to be careful when we close it not to
leave a new gap.

Link: https://bugs.passt.top/show_bug.cgi?id=215
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>
Usually fds 0-2 are stdin, stdout and stderr.  However, there are certain
use cases where passt can be invoked with one or more of those standard fds
closed.  In those cases, anything we open might be placed in one of the
standard slots.  For the handful of things we open early enough, this can
be a problem because we close fds 0-2 in __daemon(), replacing them with
dupes of /dev/null.

We could avoid closing those fds in __daemon() if they're not standard
streams.  However, leaving things other than the standard streams in fds
0-2 is a footgun: a stray printf() that occurs in a circumstance it
shouldn't could send harmful garbage to a device or socket.  It's also
likely to be confusing if debugging with strace or similar.

To avoid this, fill any missing standard streams with a dupe of /dev/null,
right after isolate_fds().  Since open()ing /dev/null itself could land in
one of those fd 0-2 slots, we need to be careful when we close it not to
leave a new gap.

Link: https://bugs.passt.top/show_bug.cgi?id=215
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>isolation: Move --fd descriptor to a number of our choosing</title>
<updated>2026-07-18T07:54:31+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-17T05:46:33+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=fd5b0807f5d0706e9247662f26c31b6bc8337f19'/>
<id>fd5b0807f5d0706e9247662f26c31b6bc8337f19</id>
<content type='text'>
Some users of passt pass an fd for the tap interface in, with the --fd
parameter, rather than having passt open it itself.  This requires some
slightly fiddly logic in isolate_fds() so we don't close() it along with
any other file descriptors leaked into us by the parent.

More importantly, this is broken if the passed fd is 0, 1 or 2, since in
that case we will assume it's a standard stream and close it in __daemon().
We explicitly disallow 1 or 2 in conf_tap_fd(), but 0 has been permitted
since aa1cc8922 ("conf: allow --fd 0").  It looks like the use case of the
contributor of that patch didn't involve daemonizing passt.

To fix this more robustly, use dup2() to move to the passed fd to 3.  This
removes the possibility of mixing it up with a standard stream, and as a
bonus makes the close_range() logic much simpler.  With isolate_fds() made
safe for --fd 1 and --fd 2, we can remove the logic excluding those from
conf_fd_tap().

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>
Some users of passt pass an fd for the tap interface in, with the --fd
parameter, rather than having passt open it itself.  This requires some
slightly fiddly logic in isolate_fds() so we don't close() it along with
any other file descriptors leaked into us by the parent.

More importantly, this is broken if the passed fd is 0, 1 or 2, since in
that case we will assume it's a standard stream and close it in __daemon().
We explicitly disallow 1 or 2 in conf_tap_fd(), but 0 has been permitted
since aa1cc8922 ("conf: allow --fd 0").  It looks like the use case of the
contributor of that patch didn't involve daemonizing passt.

To fix this more robustly, use dup2() to move to the passed fd to 3.  This
removes the possibility of mixing it up with a standard stream, and as a
bonus makes the close_range() logic much simpler.  With isolate_fds() made
safe for --fd 1 and --fd 2, we can remove the logic excluding those from
conf_fd_tap().

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>conf: Make conf_tap_fd() operate more like conf_mode()</title>
<updated>2026-07-18T07:54:29+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-17T05:46:32+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=ab825955836cb04c1e994d17af4c50a243ea67a0'/>
<id>ab825955836cb04c1e994d17af4c50a243ea67a0</id>
<content type='text'>
We have two cases where we need to parse specific options early:
conf_tap_fd() and conf_mode().  conf_tap_fd() has a slightly odd interface,
requiring the caller to use getopt_long() to find the right option, then
pass it in.  Alter it to work like conf_mode() instead, where all the
command line parsing logic is contained within the conf.c function.

This is slightly more lines, but has a clearer division of responsibility.

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>
We have two cases where we need to parse specific options early:
conf_tap_fd() and conf_mode().  conf_tap_fd() has a slightly odd interface,
requiring the caller to use getopt_long() to find the right option, then
pass it in.  Alter it to work like conf_mode() instead, where all the
command line parsing logic is contained within the conf.c function.

This is slightly more lines, but has a clearer division of responsibility.

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>isolation, conf: Set c-&gt;fd_tap from early parse of --fd</title>
<updated>2026-07-18T07:54:27+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-17T05:46:31+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=33e0fbc396f494e2fdd8033191b76d2c4aef43ec'/>
<id>33e0fbc396f494e2fdd8033191b76d2c4aef43ec</id>
<content type='text'>
We parse --fd twice: once in isolate_initial() just to avoid clobbering
the passed in fd.  Then we parse it "for real" in conf(), to set c-&gt;fd_tap
and other configuration variables.

Change this, so that we return the value parsed early from
isolate_initial() and set c-&gt;fd_tap from that.  This doesn't accomplish
much immediately, but will make some further cleanups possible.

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>
We parse --fd twice: once in isolate_initial() just to avoid clobbering
the passed in fd.  Then we parse it "for real" in conf(), to set c-&gt;fd_tap
and other configuration variables.

Change this, so that we return the value parsed early from
isolate_initial() and set c-&gt;fd_tap from that.  This doesn't accomplish
much immediately, but will make some further cleanups possible.

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>isolation: Move close_open_files() to isolate_fds()</title>
<updated>2026-07-18T07:54:24+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-17T05:46:30+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=0a510066e9169409e9021798224bea5297c1e529'/>
<id>0a510066e9169409e9021798224bea5297c1e529</id>
<content type='text'>
Most functions in util.c are, well, utilities, that are useful in a bunch
of places.  close_open_files(), however, is very specific, it's only called
from isolate_initial(), and performs a very specific step of our self
isolation.  So, it makes more sense as a function in isolate.c - move it
there and rename it to isolate_fds().

In addition, call it directly from main() rather than from
isolate_initial().  That's pretty arbitrary now, but will make some
subsequent changes easier.

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>
Most functions in util.c are, well, utilities, that are useful in a bunch
of places.  close_open_files(), however, is very specific, it's only called
from isolate_initial(), and performs a very specific step of our self
isolation.  So, it makes more sense as a function in isolate.c - move it
there and rename it to isolate_fds().

In addition, call it directly from main() rather than from
isolate_initial().  That's pretty arbitrary now, but will make some
subsequent changes easier.

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>passt: Always close pidfile_fd, not just when daemonizing</title>
<updated>2026-07-18T07:53:47+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-07-17T05:46:29+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=b0ca29ed09e9f6e33408b7207eaf4dec9a650e89'/>
<id>b0ca29ed09e9f6e33408b7207eaf4dec9a650e89</id>
<content type='text'>
In order to satisfy static checkers that we don't have an fd leak,
a9c61ffaf153 added a close() of c-&gt;pidfile_fd, amongst others.  However,
it only close()s it in the case where we daemonize into the background.
While less universally useful in the foreground / non-daemon case, it's
perfectly reasonable to still have a pidfile.  We'll still write it, and
we should still close it.

Fixes: a9c61ffaf153 ("util, passt: Close daemon-lifetime fds on exit to avoid Coverity warning")
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>
In order to satisfy static checkers that we don't have an fd leak,
a9c61ffaf153 added a close() of c-&gt;pidfile_fd, amongst others.  However,
it only close()s it in the case where we daemonize into the background.
While less universally useful in the foreground / non-daemon case, it's
perfectly reasonable to still have a pidfile.  We'll still write it, and
we should still close it.

Fixes: a9c61ffaf153 ("util, passt: Close daemon-lifetime fds on exit to avoid Coverity warning")
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>tap: Fix EAGAIN/EWOULDBLOCK check in tap_pasta_input()</title>
<updated>2026-07-17T10:39:12+00:00</updated>
<author>
<name>Hayato Kiwata</name>
<email>dev@haytok.jp</email>
</author>
<published>2026-07-16T17:21:21+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=5418bd9a06c71f5c8e47a71aa460baf6d2a4f32e'/>
<id>5418bd9a06c71f5c8e47a71aa460baf6d2a4f32e</id>
<content type='text'>
On Linux, EAGAIN and EWOULDBLOCK have the same value. Commit
d2a1dc744b10 ("tap: Restructure in tap_pasta_input()") added a check for
EWOULDBLOCK on purpose:

&gt; - Check for EWOULDBLOCK as well as EAGAIN for the benefit of any future
&gt;   ports where those might not have the same value

However, the condition uses &amp;&amp; instead of ||, so it can never be true on a
platform where EAGAIN and EWOULDBLOCK are different.

Use || instead so that the check works as intended on such platforms.

Fixes: d2a1dc744b10 ("tap: Restructure in tap_pasta_input()")
Signed-off-by: Hayato Kiwata &lt;dev@haytok.jp&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>
On Linux, EAGAIN and EWOULDBLOCK have the same value. Commit
d2a1dc744b10 ("tap: Restructure in tap_pasta_input()") added a check for
EWOULDBLOCK on purpose:

&gt; - Check for EWOULDBLOCK as well as EAGAIN for the benefit of any future
&gt;   ports where those might not have the same value

However, the condition uses &amp;&amp; instead of ||, so it can never be true on a
platform where EAGAIN and EWOULDBLOCK are different.

Use || instead so that the check works as intended on such platforms.

Fixes: d2a1dc744b10 ("tap: Restructure in tap_pasta_input()")
Signed-off-by: Hayato Kiwata &lt;dev@haytok.jp&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.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>
</feed>
