Commit 1a563a0cbd ("passt: Address gcc 11 warnings") works around an
issue where the remote address passed to hash functions is seen as
uninitialised by gcc, with -flto and -O2.
It turns out we get the same exact behaviour on gcc 12.1 and 12.2, so
extend the applicability of the same workaround to gcc 12.
Don't go further than that, though: should the issue reported at:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78993
happen to be fixed in a later version of gcc, we won't need the
noinline attributes anymore. Otherwise, we'll notice.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
It's unclear what original suppressions these unmatchedSuppression
suppressions were supposed to go with. They don't trigger any warnings on
the current code that I can tell, so remove them. If we find a problem
with some cppcheck versions in future, replace them with inline
suppressions so it's clearer exactly where the issue is originating.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
We have a couple of functions that are unused (for now) by design.
Although at least one has a flag so that gcc doesn't warn, cppcheck has its
own warnings about this. Add specific inline suppressions for these rather
than a blanket suppression in the Makefile.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
I can't get this warning to trigger, even without the suppression, so
remove it. If it shows up again on some cppcheck version, we can replace
it with inline suppressions so it's clear where the issue lay.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
I can't get these warnings to trigger on the cppcheck versions I have, so
remove them. If we find in future we need to replace these, they should be
replaced with inline suppressions so its clear what's the section of code
at issue.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
I can't get this warning to trigger, so I think this suppression must be
out of date. Whether that's because we've changed our code to no longer
have the problem, or because cppcheck itself has been updated to remove a
false positive I don't know.
If we find that we do need a suppression like this for some cppcheck
version, we should replace it with an inline suppression so it's clear
what exactly is triggering the warning.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
seccomp.sh generates seccomp.h, so if we change it, we should re-build
seccomp.h as well. Add this to the make dependencies so it happens.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Since bf95322f "conf: Make the argument to --pcap option mandatory" we
no longer call localtime() in pcap.c, so we no longer need the matching
cppcheck suppression.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
In a number of places in passt we use structures to represent over the wire
or in-file data with a fixed layout. After initialization we don't access
the fields individually and just write the structure as a whole to its
destination.
Unfortunately cppcheck doesn't cope with this pattern and thinks all the
structure members are unused. We already have suppressions for this in
pcap.c and dhcp.c However, it also appears in dhcp.c and netlink.c at
least. Since this is likely to be common, it seems wiser to just suppress
the error globally.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
strtok() is non-reentrant and old-fashioned, so cppcheck would complains
about its use in conf.c if it weren't suppressed. We're single threaded
and strtok() is convenient though, so it's not really worth reworking at
this time. Convert this to an inline suppression so it's adjacent to the
code its annotating.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
qrap.c uses several old-fashioned functions that cppcheck complains about.
Since it's headed for obselesence anyway, just suppress these rather than
attempting to modernize the code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
We define our own ffsl() as a weak symbol, in case our C library doesn't
include it. On glibc systems which *do* include it, this causes a cppcheck
warning because unsurprisingly our version doesn't pick the same argument
names. Convert the suppression for this into an inline suppression.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
conf_runas() handles several of the different possible cases for the
--runas argument in a slightly odd order. Although it can parse both
numeric UIDs/GIDs and user/group names, it can't parse a numeric UID
combined with a group name or vice versa. That's not obviously useful, but
it's slightly surprising gap to have.
Rework the parsing to be more systematic: first split the option into
user and (optional) group parts, then separately parse each part as either
numeric or a name. As a bonus this removes some clang-tidy warnings.
While we're there also add cppcheck suppressions for getpwnam() and
getgrnam(). It complains about those because they're not reentrant.
passt is single threaded though, and is always likely to be during
this initialization code, even if we multithread later.
There were some existing suppressions for these in the cppcheck
invocation but they're no longer up to date. Replace them with inline
suppressions which, being next to the code, are more likely to stay
correct.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Debian and similar distros put target specific header files in
/usr/include/<arch-vendor-os>, rather than directly in /usr/include. Add
this directory to the includes for cppcheck so it can find them.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
We do some manipulation of the output of cc -v to get the target triple
for the platform, to locate headers for cppcheck. However, we can get
this more easily with cc -dumpmachine - and in fact we do so elsewhere in
the Makefile.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Adding the --quiet option to cppcheck makes the actual errors and warnings
easier to find.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
make cppcheck takes a long time, because it checks a large number of
different configurations. It's assembling this very large set of
configurations not because of conditionals in the passt code itself,
but from those in the system headers. By adding --config-exclude
directives to stop considering those configs, make cppcheck becomes
around 60x faster on my system.
Similarly, any problems that are found in the system headers are not our
problem, and so we can uniformly suppress them, rather than having specific
suppressions for particular problems in particular files (which might not
be correct for all different distro / version combinations either).
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This check complains about any identifier of less than 3 characters. For
locals and parameters this is often pointlessly verbose. Disable it.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
enum conf_port_type is local to conf.c and is used to track the port
forwarding mode during configuration. We don't keep it around in the
context structure, however the 'init_detect_ports' and 'ns_detect_ports'
fields in the context are based solely on this. Rather than changing
encoding, just include the forwarding mode into the context structure.
Move the type definition to a new port_fwd.h, which is kind of trivial at
the moment but will have more stuff later.
While we're there, "conf_port_type" doesn't really convey that this enum is
describing how port forwarding is configured. Rename it to port_fwd_mode.
The variables (now fields) of this type also have mildly confusing names
since it's not immediately obvious whether 'ns' and 'init' refer to the
source or destination of the packets. Use "in" (host to guest / init to
ns) and "out" (guest to host / ns to init) instead.
This has the added bonus that we no longer have locals 'udp_init' and
'tcp_init' which shadow global functions.
In addition, add a typedef 'port_fwd_map' for a bitmap of each port number,
which is used in several places.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Define the target machine architecture in lowercase.
The name of the executable qemu-system-* is defined from the build flags
and should be in lowercase:
( "qemu-system-" ARCH ),
I.e. qemu-system-x86_64 instead of qemu-system-X86_64. Otherwise, the
exec call will fail.
Signed-off-by: Vasiliy Ulyanov <vulyanov@suse.de>
Signed-off-by: Dario Faggioli <dfaggioli@suse.com>
Targets running static checkers (cppcheck and clang-tidy) need
seccomp.h, but the latter is not included in HEADERS. Add it.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
If we append CFLAGS to the ones passed via command line (if any),
-D options we append will override -D options passed on command line
(if any).
For example, OpenSUSE build flags include -D_FORTIFY_SOURCE=3, and we
want to have -D_FORTIFY_SOURCE=2, if and only if not overridden. The
current behaviour implies we redefine _FORTIFY_SOURCE as 2, though.
Instead of appending CFLAGS, prepend them by adding all the default
build flags to another variable, a simply expanded one (defined with
:=), named FLAGS, and pass that *before* CFLAGS in targets, so that
defines from command line can override default flags.
Reported-by: Dario Faggioli <dfaggioli@suse.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Tested-by: Dario Faggioli <dfaggioli@suse.com>
passt/pasta contains a number of routines designed to isolate passt from
the rest of the system for security. These are spread through util.c and
passt.c. Move them together into a new isolation.c file.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
We don't set any, but we should use them if they are passed in the
environment. On a Fedora Rawhide package build, annocheck
(https://sourceware.org/annobin/) reports:
Hardened: /usr/bin/passt: FAIL: bind-now test because not linked with -Wl,-z,now
...despite the build system exporting -Wl,-z,now in LDFLAGS.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
It turns out that, while on most distributions "docdir" would be
/usr/share/doc, it's /usr/share/doc/packages/ on OpenSUSE Tumbleweed.
Use an explicit docdir as shown in:
https://en.opensuse.org/openSUSE:Build_Service_cross_distribution_howto
and don't unnecessarily hardcode directory variables in the Makefile.
Otherwise, RPM builds for OpenSUSE will fail now that we have a README
there.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Distribution packages reasonably expect to have a human-readable
Markdown version of the README under /usr/share/doc/, but all we have
right now is a heavily web-oriented version.
Introduce a ugly hack to strip web-oriented parts from the current
README and install it.
It should probably work the other way around: a human-readable README
could be used as a source for the web page. But cgit needs a file
that's in the tree, not something that can be built, and
https://passt.top/ is based on cgit. It should eventually be doable
to work around this in cgit, instead.
Reported-by: Benson Muite <benson_muite@emailplus.org>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Some versions of valgrind (such as the version on my Fedora laptop -
valgrind-3.19.0-3.fc36.x86_64) use futexes. But futex is currently not
allowed in the seccomp filter, even with the extra calls added for
valgrind builds. Add it, to avoid spurious valgrind failures.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
We handle SIGQUIT and SIGTERM calling exit(), which is usually
implemented with the exit_group() system call.
If we don't allow exit_group(), we'll get a SIGSYS while handling
SIGQUIT and SIGTERM, which means a misleading non-zero exit code.
Reported-by: Wenli Quan <wquan@redhat.com>
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2101990
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
If the tests are interrupted at the right point a passt.pid file can be
left over. Clean it up with "make clean" and add it to .gitignore so it
doesn't get accidentally committed.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Two places in passt need to read files line by line (one parsing
resolv.conf, the other parsing /proc/net/*. They can't use fgets()
because in glibc that can allocate memory. Instead they use an
implementation line_read() in util.c. This has some problems:
* It has two completely separate modes of operation, one buffering
and one not, the relation between these and how they're activated
is subtle and confusing
* At least in non-buffered mode, it will mishandle an empty line,
folding them onto the start of the next non-empty line
* In non-buffered mode it will use lseek() which prevents using this
on non-regular files (we don't need that at present, but it's a
surprising limitation)
* It has a lot of difficult to read pointer mangling
Add a new cleaner implementation of allocation-free line-by-line
reading in lineread.c. This one always buffers, using a state
structure to keep track of what we need. This is larger than I'd
like, but it turns out handling all the edge cases of line-by-line
reading in C is surprisingly hard.
This just adds the code, subsequent patches will change the existing
users of line_read() to the new implementation.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
In order to probe availability of certain features the Makefile test
compiles a handful of tiny snippets, feeding those in from stdin. However
in one case - the one for -fstack-protector - it forgets to redirect the
output to stdout, meaning it creates a stray '-.s' file when make is
invoked (even make clean).
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
The use of rm commands in the clean and uninstall targets adds an explicit
leading - to ignore errors. However the built-in RM variable in make is
actually "rm -f" which already ignores errors, so the - isn't neccessary.
Also replace ${RM} with $(RM) which is the more conventional form in
Makefiles.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
pasta, pasta.avx2 and pasta.1 are all generated as a link to the
corresponding passt file. We can consolidate the 3 rules for these targets
into a single pattern rule.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
There are several places which explicitly list the various generated
binaries, even though a $(BIN) variable already lists them. There are
several more places that list all the manpage files, introduce a
$(MANPAGES) variable to remove that repetition as well.
Tweak the generation of pasta.1 as a link to passt.1 so it's not just made
as a side effect of the pasta target.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[sbrivio: add passt.1 and qrap.1 to guest files for distro tests]
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
The passt/pasta Makefile makes fairly heavy use of GNU make's $(wildcard)
function to locate the sources and headers to build. Using wildcards for
the things to compile is usually a bad idea though: if somehow you end up
with a .c or .h file in your tree you didn't expect it can misbuild in an
exceedingly confusing way. In particular this can sometimes happen if
switching between releases / branches where files have been added or
removed without 100% cleaning the tree.
It also makes life a bit complicated if building multiple different
binaries in the same tree: we already have some rather awkward
$(filter-out) constructions to avoid including qrap.c in the passt build.
Replace use of $(wildcard) with the more idiomatic approach of defining
variables listing all the relevant source files then using that throughout.
In the rule for seccomp.h there was also a bare "*.c" which caused make to
always rebuild that target. Fix that as well.
Similarly, seccomp.sh uses a wildcard to locate the sources, which is
unwise for the same reasons. Make it take the sources to examine on the
command line instead, and have the Makefile pass them in from the same
variables.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
New from Cppcheck 2.8: all the fields of struct msg that are not
directly manipulated are now reported as unused, which is kind of
correct as those fields are used as a blob "copied" from request
to response and not as separate fields.
However, keeping the message composition explicit is probably
desirable, and adding inline suppressions makes the whole thing
rather unreadable, so just suppress unusedStructMember warnings for
dhcp.c, while also adding a suppression for unmatched suppressions
to keep earlier versions of Cppcheck happy.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Pass to seccomp.sh a list of additional syscalls valgrind needs as
EXTRA_SYSCALLS in a new 'valgrind' make target, and add corresponding
support in seccomp.sh itself.
In test setup functions, start passt with valgrind, but not for
performance tests.
Add tests checking that valgrind exits without errors after all the
other tests in the group are done.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Build-time selection of AVX2 flags and routines is not practical for
distributions, but limiting AVX2 usage to checksum routines with
specific run-time detection doesn't allow for easy performance gains
from auto-vectorisation of batched packet handling routines.
For x86_64, build non-AVX2 and AVX2 binaries, and implement a simple
wrapper replacing the current executable with the AVX2 build if it's
available, and if AVX2 is supported by the current CPU.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
There's a single AUDIT_ARCH_ARM define available (and big-endian
shouldn't be a concern with those).
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This should be convenient for users managing filesystem-bound network
namespaces: monitor the base directory of the namespace and exit if
the namespace given as PATH or NAME target is deleted. We can't add
an inotify watch directly on the namespace directory, that won't work
with nsfs.
Add an option to disable this behaviour, --no-netns-quit.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Nobody currently calls this as passt4netns, that was the name I used
before 'pasta', drop any reference before it's too late.
While at it, explicitly check that argc is bigger than or equal to
one, just as a defensive measure: argv[0] being NULL is not an issue
anyway.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
clang-tidy from LLVM 13.0.1 reports some new warnings from these
checkers:
- altera-unroll-loops, altera-id-dependent-backward-branch: ignore
for the moment being, add a TODO item
- bugprone-easily-swappable-parameters: ignore, nothing to do about
those
- readability-function-cognitive-complexity: ignore for the moment
being, add a TODO item
- altera-struct-pack-align: ignore, alignment is forced in protocol
headers
- concurrency-mt-unsafe: ignore for the moment being, add a TODO
item
Fix bugprone-implicit-widening-of-multiplication-result warnings,
though, that's doable and they seem to make sense.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
tcpi_bytes_acked and tcpi_min_rtt are only available on recent
kernel versions: provide fall-back paths (incurring some grade of
performance penalty).
Support for getrandom() was introduced in Linux 3.17 and glibc 2.25:
provide an alternate mechanism for that as well, reading from
/dev/random.
Also check if NETLINK_GET_STRICT_CHK is defined before using it:
it's not strictly needed, we'll filter out irrelevant results from
netlink anyway.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
On some distributions, on ppc64, ulimit -s returns 'unlimited': add a
reasonable default, and also make sure ulimit is invoked using the
default shell, which should ensure ulimit is actually implemented.
Also note that AUDIT_ARCH doesn't follow closely the naming reported
by 'uname -m': convert for i386 and ppc as needed.
While at it, move inclusion of seccomp.h after util.h, the former is
less generic (cosmetic/clang-tidy only).
Older kernel headers might lack a definition for AUDIT_ARCH_PPC64LE:
define that explicitly if it's not available.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Some of those warnings don't trigger even on systems with very
similar toolchains, suppress unmatchedSuppression warnings, they're
basically useless.
While at it, pass CFLAGS to cppcheck.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>