<feed xmlns='http://www.w3.org/2005/Atom'>
<title>passt/util.c, branch 2026_06_11.a9c61ff</title>
<subtitle>Plug A Simple Socket Transport</subtitle>
<link rel='alternate' type='text/html' href='https://passt.top/passt/'/>
<entry>
<title>util, passt: Close daemon-lifetime fds on exit to avoid Coverity warning</title>
<updated>2026-06-11T23:02:35+00:00</updated>
<author>
<name>Jon Maloy</name>
<email>jmaloy@redhat.com</email>
</author>
<published>2026-06-11T15:15:21+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=a9c61ffaf15347b8dfcc2347c5440e4b0e82333b'/>
<id>a9c61ffaf15347b8dfcc2347c5440e4b0e82333b</id>
<content type='text'>
conf_open_files() opens three file descriptors (fd_tap_listen,
fd_repair_listen, fd_control_listen) that are held for the entire
daemon lifetime.  Because no close() call exists for them
anywhere, Coverity flags each as INCOMPLETE_DEALLOCATOR. This is
clearly a false positive, but we still want to get rid of this
warning.

We now register the execution context in global area so that
passt_exit() can use it to close these descriptors before calling
_exit().  All exit paths (signal handler, die(), die_perror())
funnel through passt_exit(), so this covers all cases.

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>
conf_open_files() opens three file descriptors (fd_tap_listen,
fd_repair_listen, fd_control_listen) that are held for the entire
daemon lifetime.  Because no close() call exists for them
anywhere, Coverity flags each as INCOMPLETE_DEALLOCATOR. This is
clearly a false positive, but we still want to get rid of this
warning.

We now register the execution context in global area so that
passt_exit() can use it to close these descriptors before calling
_exit().  All exit paths (signal handler, die(), die_perror())
funnel through passt_exit(), so this covers all cases.

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>conf, util: Disable IPv6 if explicit IPv6 socket probe fails</title>
<updated>2026-06-10T14:48:44+00:00</updated>
<author>
<name>Stefano Brivio</name>
<email>sbrivio@redhat.com</email>
</author>
<published>2026-06-08T19:06:17+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=e1a6d9ef626aa6dbcfeef97dbbab3bd69c35b4b1'/>
<id>e1a6d9ef626aa6dbcfeef97dbbab3bd69c35b4b1</id>
<content type='text'>
In https://bugs.passt.top/show_bug.cgi?id=188, I originally reported
that if IPv6 is disabled in the kernel (for example via command line
parameter ipv6.disable=1, or disabled in build configuration), and we
attempt to forward any port, we'll exit right away after failing to
set up dual-stack listening sockets.

The original instance of that issue is now fixed for pasta by commit
75dcbc300bf0 ("pasta: Warn, disable matching IP version if not
supported, in local mode") together with the new implementation of
the rule forwarding table, starting from commit b223bec48213 ("fwd,
tcp, udp: Set up listening sockets based on forward table"), because
we first parse forwarding options, then probe for IPv6 support in the
target namespace (and disable IPv6 as a result), and finally bind
sockets once we already know that IPv6 support is disabled.

But we don't do that when invoked as passt, because we have no target
namespace and hence no probing for IPv6 support whatsoever.

Add IPv6 to the socket features we test in sock_probe_features(), and,
if we fail to create an IPv6 socket for whatever reason (which might
include security policies as well), disable IPv6 support altogether,
so that we won't attempt to use dual-stack sockets for port forwarding
either.

Note that the probe comes without any sort of debug message, because
at this point we haven't parsed the configuration yet, and we would
therefore print that regardless of the selected logging level and
other options, including --ipv4-only, which would be rather confusing.
I doubt we'll miss this kind of message though, IPv6 support being
disabled is anyway obvious from the initial configuration dump.

Reported-by: Chi Cuong HA &lt;ChiCuong.HA@amadeus.com&gt;
Reported-by: Romain Geissler &lt;romain.geissler@amadeus.com&gt;
Link: https://bugs.passt.top/show_bug.cgi?id=188
Fixes: 4ddd59bc6085 ("conf: Separate local mode for each IP version, don't enable disabled IP version")
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>
In https://bugs.passt.top/show_bug.cgi?id=188, I originally reported
that if IPv6 is disabled in the kernel (for example via command line
parameter ipv6.disable=1, or disabled in build configuration), and we
attempt to forward any port, we'll exit right away after failing to
set up dual-stack listening sockets.

The original instance of that issue is now fixed for pasta by commit
75dcbc300bf0 ("pasta: Warn, disable matching IP version if not
supported, in local mode") together with the new implementation of
the rule forwarding table, starting from commit b223bec48213 ("fwd,
tcp, udp: Set up listening sockets based on forward table"), because
we first parse forwarding options, then probe for IPv6 support in the
target namespace (and disable IPv6 as a result), and finally bind
sockets once we already know that IPv6 support is disabled.

But we don't do that when invoked as passt, because we have no target
namespace and hence no probing for IPv6 support whatsoever.

Add IPv6 to the socket features we test in sock_probe_features(), and,
if we fail to create an IPv6 socket for whatever reason (which might
include security policies as well), disable IPv6 support altogether,
so that we won't attempt to use dual-stack sockets for port forwarding
either.

Note that the probe comes without any sort of debug message, because
at this point we haven't parsed the configuration yet, and we would
therefore print that regardless of the selected logging level and
other options, including --ipv4-only, which would be rather confusing.
I doubt we'll miss this kind of message though, IPv6 support being
disabled is anyway obvious from the initial configuration dump.

Reported-by: Chi Cuong HA &lt;ChiCuong.HA@amadeus.com&gt;
Reported-by: Romain Geissler &lt;romain.geissler@amadeus.com&gt;
Link: https://bugs.passt.top/show_bug.cgi?id=188
Fixes: 4ddd59bc6085 ("conf: Separate local mode for each IP version, don't enable disabled IP version")
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>pcap: Pass explicit L2 length to pcap_iov()</title>
<updated>2026-05-19T23:21:42+00:00</updated>
<author>
<name>Laurent Vivier</name>
<email>lvivier@redhat.com</email>
</author>
<published>2026-05-13T11:52:15+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=533ef11ecb4edd98c7adad3b51c40fdcc2f0671d'/>
<id>533ef11ecb4edd98c7adad3b51c40fdcc2f0671d</id>
<content type='text'>
With vhost-user multibuffer frames, the iov can be larger than the
actual L2 frame. The previous approach of computing L2 length as
iov_size() - offset would overcount and write extra bytes into the
pcap file.

Pass the L2 frame length explicitly to pcap_frame() and pcap_iov(),
and write exactly that many bytes instead of the full iov remainder.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-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>
With vhost-user multibuffer frames, the iov can be larger than the
actual L2 frame. The previous approach of computing L2 length as
iov_size() - offset would overcount and write extra bytes into the
pcap file.

Pass the L2 frame length explicitly to pcap_frame() and pcap_iov(),
and write exactly that many bytes instead of the full iov remainder.

Signed-off-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Reviewed-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>bitmap: Split bitmap helper functions into their own module</title>
<updated>2026-03-28T13:36:02+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-03-27T04:34:29+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=51eaaa7be714229c1b2e2f7ba5f3c5eae36c8a61'/>
<id>51eaaa7be714229c1b2e2f7ba5f3c5eae36c8a61</id>
<content type='text'>
Currently bitmap functions are in util.[ch] along with a lot of other
stuff.  In preparation for sharing them with a configuration client, move
these out into their own files.

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>
Currently bitmap functions are in util.[ch] along with a lot of other
stuff.  In preparation for sharing them with a configuration client, move
these out into their own files.

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>serialise: Split functions user for serialisation from util.c</title>
<updated>2026-03-28T13:35:41+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-03-27T04:34:16+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=8081aa597be4007f3ef15fe8ce11ec8ad0ab8b42'/>
<id>8081aa597be4007f3ef15fe8ce11ec8ad0ab8b42</id>
<content type='text'>
The read_all_buf() and write_all_buf() functions in util.c are
primarily used for serialising data structures to a stream during
migraiton.  We're going to have further use for such serialisation
when we add dynamic configuration updates, where we'll want to share
the code with the client program.

To make that easier move the functions into a new serialise.c
file, and rename thematically.

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 read_all_buf() and write_all_buf() functions in util.c are
primarily used for serialising data structures to a stream during
migraiton.  We're going to have further use for such serialisation
when we add dynamic configuration updates, where we'll want to share
the code with the client program.

To make that easier move the functions into a new serialise.c
file, and rename thematically.

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>treewide: Spell ASSERT() as assert()</title>
<updated>2026-03-20T20:05:29+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-03-19T06:11:43+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=bc872d91765dfd6ff34b0e9a34bce410fac1cef3'/>
<id>bc872d91765dfd6ff34b0e9a34bce410fac1cef3</id>
<content type='text'>
The standard library assert(3), at least with glibc, hits our seccomp
filter and dies with SIGSYS before it's able to print a message, making it
near useless.  Therefore, since 7a8ed9459dfe ("Make assertions actually
useful") we've instead used our own implementation, named ASSERT().

This makes our code look slightly odd though - ASSERT() has the same
overall effect as assert(), it's just a different implementation.  More
importantly this makes it awkward to share code between passt/pasta proper
and things that compile in a more typical environment.  We're going to want
that for our upcoming dynamic configuration tool.

Address this by overriding the standard library's assert() implementation
with our own, instead of giving ours its own name.

The standard assert() is supposed to be omitted if NDEBUG is defined,
which ours doesn't do.  Implement that as well, so ours doesn't
unexpectedly differ.  For the -DNDEBUG case we do this by *not* overriding
assert(), since it will be a no-op anyway.  This requires a few places to
add a #include &lt;assert.h&gt; to let us compile (albeit with warnings) when
-DNDEBUG.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Fix some conflicts and missing conversions as a result of
 applying "vu_common: Move iovec management into vu_collect()" first]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The standard library assert(3), at least with glibc, hits our seccomp
filter and dies with SIGSYS before it's able to print a message, making it
near useless.  Therefore, since 7a8ed9459dfe ("Make assertions actually
useful") we've instead used our own implementation, named ASSERT().

This makes our code look slightly odd though - ASSERT() has the same
overall effect as assert(), it's just a different implementation.  More
importantly this makes it awkward to share code between passt/pasta proper
and things that compile in a more typical environment.  We're going to want
that for our upcoming dynamic configuration tool.

Address this by overriding the standard library's assert() implementation
with our own, instead of giving ours its own name.

The standard assert() is supposed to be omitted if NDEBUG is defined,
which ours doesn't do.  Implement that as well, so ours doesn't
unexpectedly differ.  For the -DNDEBUG case we do this by *not* overriding
assert(), since it will be a no-op anyway.  This requires a few places to
add a #include &lt;assert.h&gt; to let us compile (albeit with warnings) when
-DNDEBUG.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
[sbrivio: Fix some conflicts and missing conversions as a result of
 applying "vu_common: Move iovec management into vu_collect()" first]
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Add missing includes to headers</title>
<updated>2026-03-04T16:39:57+00:00</updated>
<author>
<name>Peter Foley</name>
<email>pefoley@google.com</email>
</author>
<published>2026-02-23T18:11:19+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=adbf5c135f19db5b6751393b7f5cbf516031bde8'/>
<id>adbf5c135f19db5b6751393b7f5cbf516031bde8</id>
<content type='text'>
Support build systems like bazel that check that headers are
self-contained.

Also update includes so that clang-include-cleaner succeeds.

Tested with:
clang-include-cleaner-19 --extra-arg=-D_GNU_SOURCE --extra-arg=-DPAGE_SIZE=4096 --extra-arg=-DVERSION=\"git\" --extra-arg=-DHAS_GETRANDOM *.h *.c

Signed-off-by: Peter Foley &lt;pefoley@google.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Support build systems like bazel that check that headers are
self-contained.

Also update includes so that clang-include-cleaner succeeds.

Tested with:
clang-include-cleaner-19 --extra-arg=-D_GNU_SOURCE --extra-arg=-DPAGE_SIZE=4096 --extra-arg=-DVERSION=\"git\" --extra-arg=-DHAS_GETRANDOM *.h *.c

Signed-off-by: Peter Foley &lt;pefoley@google.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix build when HAS_GETRANDOM is undefined</title>
<updated>2026-02-24T11:09:48+00:00</updated>
<author>
<name>Peter Foley</name>
<email>pefoley@google.com</email>
</author>
<published>2026-02-23T17:27:39+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=66e59418a88751ee5309bf9dfc9ce7d34e211b4e'/>
<id>66e59418a88751ee5309bf9dfc9ce7d34e211b4e</id>
<content type='text'>
e.g.
util.c:1163:14: error: use of undeclared identifier 'dev_random'; did you mean 'raw_random'?
 1163 |                 ret = read(dev_random, (char *)buf + random_read,

Fixes: 71d5deed5eed ("util: Add general low-level random bytes helper")
Signed-off-by: Peter Foley &lt;pefoley@google.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
e.g.
util.c:1163:14: error: use of undeclared identifier 'dev_random'; did you mean 'raw_random'?
 1163 |                 ret = read(dev_random, (char *)buf + random_read,

Fixes: 71d5deed5eed ("util: Add general low-level random bytes helper")
Signed-off-by: Peter Foley &lt;pefoley@google.com&gt;
Reviewed-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>util: Be more defensive about buffer overruns in read_file()</title>
<updated>2026-01-10T18:27:40+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2026-01-07T01:46:02+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=0bd2e6883d560c038e49a3cf68984d63f87ca67a'/>
<id>0bd2e6883d560c038e49a3cf68984d63f87ca67a</id>
<content type='text'>
clang-21.1.7 complains about read_file(), thinking that total_read might
come to exceed buf_size, leading to an out of bounds access at the end of
the function.  In fact, the semantics of read()'s return mean this can't
ever happen.  But we already have to check for the total_read == buf_size
case, so it's basically free to change it to &gt;= and suppress the error.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
clang-21.1.7 complains about read_file(), thinking that total_read might
come to exceed buf_size, leading to an out of bounds access at the end of
the function.  In fact, the semantics of read()'s return mean this can't
ever happen.  But we already have to check for the total_read == buf_size
case, so it's basically free to change it to &gt;= and suppress the error.

Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Laurent Vivier &lt;lvivier@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>pasta: Clean up waiting pasta child on failures</title>
<updated>2025-12-12T21:23:14+00:00</updated>
<author>
<name>David Gibson</name>
<email>david@gibson.dropbear.id.au</email>
</author>
<published>2025-12-11T03:54:36+00:00</published>
<link rel='alternate' type='text/html' href='https://passt.top/passt/commit/?id=87f1a917d881d0881d6db5fdc2345f345a0e30d1'/>
<id>87f1a917d881d0881d6db5fdc2345f345a0e30d1</id>
<content type='text'>
When pasta is invoked with a command rather than an existing namespace to
attach to, it spawns a child process to run a shell or other command.  We
create that process during conf(), since we need the namespace to exist for
much of our setup.  However, we don't want the specified command to run
until the pasta network interface is ready for use.  Therefore,
pasta_spawn_cmd() executing in the child waits before exec()ing.  main()
signals the child to continue with SIGUSR1 shortly before entering the
main forwarding loop.

This has the downside that if we exit due to any kind of failure between
conf() and the SIGUSR1, the child process will be around waiting
indefinitely.  The user must manually clean this up.

Make this cleaner, by having the child use PR_SET_PDEATHSIG to have
itself killed if the parent dies during this window.  Technically
speaking this is racy: if the parent dies before the child can call
the prctl() it will be left zombie-like as before.  However, as long
as the parent completes pasta_wait_for_ns() before dying, I wasn't
able to trigger the race.  Since the consequences of this going wrong
are merely a bit ugly, I think that's good enough.

Suggested-by: Paul Holzinger &lt;pholzing@redhat.com&gt;
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Paul Holzinger &lt;pholzing@redhat.com&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 pasta is invoked with a command rather than an existing namespace to
attach to, it spawns a child process to run a shell or other command.  We
create that process during conf(), since we need the namespace to exist for
much of our setup.  However, we don't want the specified command to run
until the pasta network interface is ready for use.  Therefore,
pasta_spawn_cmd() executing in the child waits before exec()ing.  main()
signals the child to continue with SIGUSR1 shortly before entering the
main forwarding loop.

This has the downside that if we exit due to any kind of failure between
conf() and the SIGUSR1, the child process will be around waiting
indefinitely.  The user must manually clean this up.

Make this cleaner, by having the child use PR_SET_PDEATHSIG to have
itself killed if the parent dies during this window.  Technically
speaking this is racy: if the parent dies before the child can call
the prctl() it will be left zombie-like as before.  However, as long
as the parent completes pasta_wait_for_ns() before dying, I wasn't
able to trigger the race.  Since the consequences of this going wrong
are merely a bit ugly, I think that's good enough.

Suggested-by: Paul Holzinger &lt;pholzing@redhat.com&gt;
Signed-off-by: David Gibson &lt;david@gibson.dropbear.id.au&gt;
Reviewed-by: Paul Holzinger &lt;pholzing@redhat.com&gt;
Signed-off-by: Stefano Brivio &lt;sbrivio@redhat.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
