aboutgitcodebugslistschat
Commit message (Collapse)AuthorAgeFilesLines
* Move logging functions to a new file, log.cStefano Brivio2022-10-1420-138/+187
| | | | | | | | Logging to file is going to add some further complexity that we don't want to squeeze into util.c. Signed-off-by: Stefano Brivio <sbrivio@redhat.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
* test: Add rudimentary support to run selected tests onlyStefano Brivio2022-10-143-2/+53
| | | | | | | | | | | | | | | To keep this simple, only support tests that have corresponding setup and teardown functions implied by their path. For example: ./run passt/ndp will trigger the 'passt' setup and teardown functions. This is not really elegant, but it looks robust, and while David is considering proper alternatives, it should be quite useful. Signed-off-by: Stefano Brivio <sbrivio@redhat.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
* Makefile: Hack for optimised-away store in ndp() before checksum calculation2022_09_29.06aa26fStefano Brivio2022-09-292-0/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | With gcc 11 and 12, passing -flto, or -flto=auto, and -O2, intra-procedural optimisation gets rid of a fundamental bit in ndp(): the store of hop_limit in the IPv6 header, before the checksum is calculated, which on x86_64 looks like this: ip6hr->hop_limit = IPPROTO_ICMPV6; b8c0: c6 44 24 35 3a movb $0x3a,0x35(%rsp) Here, hop_limit is temporarily set to the protocol number, to conveniently get the IPv6 pseudo-header for ICMPv6 checksum calculation in memory. With LTO, the assignment just disappears from the binary. This is rather visible as NDP messages get a wrong checksum, namely the expected checksum plus 58, and they're ignored by the guest or in the namespace, meaning we can't get any IPv6 routes, as reported by Wenli Quan. The issue affects a significant number of distribution builds, including the ones for CentOS Stream 9, EPEL 9, Fedora >= 35, Mageia Cauldron, and openSUSE Tumbleweed. As a quick workaround, declare csum_unaligned() as "noipa" for gcc 11 and 12, with -flto and -O2. This disables inlining and cloning, which causes the assignment to be compiled again. Leave a TODO item: we should figure out if a gcc issue has already been reported, and report one otherwise. There's no apparent justification as to why the store could go away. Reported-by: Wenli Quan <wquan@redhat.com> Link: https://bugzilla.redhat.com/show_bug.cgi?id=2129713 Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* udp: Replace pragma to ignore bogus stringop-overread warning with workaroundStefano Brivio2022-09-292-31/+18
| | | | | | | | | | | | | | | | | | | Commit c318ffcb4c93 ("udp: Ignore bogus -Wstringop-overread for write() from gcc 12.1") uses a gcc pragma to ignore a bogus warning, which started appearing on gcc 12.1 (aarch64 and x86_64) due to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103483 ...but gcc 12.2 has the same issue. Not just that: if LTO is enabled, the pragma itself is ignored (this wasn't the case with gcc 12.1), because of: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80922 Drop the pragma, and assign a frame (in the networking sense) pointer from the offset of the Ethernet header in the buffer, then pass it to write() and pcap(), so that gcc doesn't obsess anymore with the fact that an Ethernet header is 14 bytes and we're sending more than that. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Makefile: Extend noinline workarounds for LTO and -O2 to gcc 12Stefano Brivio2022-09-291-3/+3
| | | | | | | | | | | | | | | | Commit 1a563a0cbd49 ("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>
* cppcheck: Remove unused unmatchedSuppression suppressionsDavid Gibson2022-09-291-3/+0
| | | | | | | | | | | 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>
* Mark unused functions for cppcheckDavid Gibson2022-09-293-1/+2
| | | | | | | | | | 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>
* cppcheck: Remove unused va_list_usedBeforeStarted suppressionDavid Gibson2022-09-291-2/+0
| | | | | | | | | 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>
* cppcheck: Remove unused objectIndex suppressionsDavid Gibson2022-09-291-3/+0
| | | | | | | | | | 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>
* cppcheck: Remove unused knownConditionTrueFalse suppressionDavid Gibson2022-09-291-2/+0
| | | | | | | | | | | | | | 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>
* cppcheck: Avoid errors due to zeroes in bitwise ORsDavid Gibson2022-09-291-0/+2
| | | | | | | | | | | | Recent versions of cppcheck give warnings if using a bitwise OR (|) where some of the arguments are zero. We're triggering these warnings in our generated seccomp.h header, because BPF_LD and BPF_W are zero-valued. However putting these defines in makes the generate code clearer, even though they could be left out without changing the values. So, add cppcheck suppressions to the generated code. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Regenerate seccomp.h if seccomp.sh changesDavid Gibson2022-09-291-2/+2
| | | | | | | | 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>
* cppcheck: Suppress NULL pointer warning in tcp_sock_consume()David Gibson2022-09-291-0/+1
| | | | | | | | | | | | | Recent versions of cppcheck give a warning due to the NULL buffer passed to recv() in tcp_sock_consume(). Since this apparently works, I assume it's actually valid, but cppcheck doesn't know that recv() can take a NULL buffer. So, use a suppression to get rid of the error. Also add an unmatchedSuppression suppression since only some cppcheck versions complain about this. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* cppcheck: Suppress same-value-in-ternary branches warningDavid Gibson2022-09-291-0/+1
| | | | | | | | | | | | | | TIMER_INTERVAL is the minimum of two separately defined intervals which happen to have the same value at present. This results in an expression which has the same value in both branches of a ternary operator, which cppcheck warngs about. This is logically sound in this case, so suppress the error (we appear to already have a similar suppression for clang-tidy). Also add an unmatchedSuppression suppression, since only some cppcheck versions complain about this instance. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* qrap: Handle case of PATH environment variable being unsetDavid Gibson2022-09-291-2/+3
| | | | | | | | | | | | | clang-tidy warns that in passing getenv("PATH") to strncpy() we could be passing a NULL pointer. While it's unusual for PATH to be unset, it's not impossible and this would indeed cause getenv() to return NULL. Handle this case by never recognizing argv[2] as a qemu binary name if PATH is not set. This is... no flakier than the detection of whether it's a binary name already is. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* cppcheck: Remove localtime suppression for pcap.cDavid Gibson2022-09-291-1/+0
| | | | | | | | | 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>
* cppcheck: Broaden suppression for unused struct membersDavid Gibson2022-09-291-2/+1
| | | | | | | | | | | | | | | | 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>
* Avoid ugly 'end' members in netlink structuresDavid Gibson2022-09-291-9/+10
| | | | | | | | | | | | | | We use a number of complex structures to format messages to send to netlink. In some cases we add imaginary 'end' members not because they actually mean something on the wire, but so that we can use offsetof() on the member to determine the relevant size. Adding extra things to the structures for this is kinda nasty. We can use a different construct with offsetof and sizeof to avoid them. As a bonus this removes some cppcheck warnings about unused struct members. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* cppcheck: Use inline suppression for strtok() in conf.cDavid Gibson2022-09-292-1/+2
| | | | | | | | | | | 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>
* cppcheck: Use inline suppressions for qrap.cDavid Gibson2022-09-292-2/+4
| | | | | | | | | 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>
* cppcheck: Use inline suppression for ffsl()David Gibson2022-09-292-2/+1
| | | | | | | | | | 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>
* cppcheck: Work around false positive NULL pointer dereference errorDavid Gibson2022-09-291-0/+1
| | | | | | | | | | | | | Some versions of cppcheck could errneously report a NULL pointer deference inside a sizeof(). This is now fixed in cppcheck upstream[0]. For systems using an affected version, add a suppression to work around the bug. Also add an unmatchedSuppression suppression so the suppression itself doesn't cause a warning if you *do* have a fixed cppcheck. [0] https://github.com/danmar/cppcheck/pull/4471 Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Stricter checking for nsholder.cDavid Gibson2022-09-292-2/+2
| | | | | | | | | | | | Add the -Wextra -pedantic and -std=c99 flags when compiling the nsholder test helper to get extra compiler checks, like we already use for the main source code. While we're there, fix some %d (signed) printf descriptors being used for unsigned values (uid_t and gid_t). Pointed out by cppcheck. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Don't shadow global function namesDavid Gibson2022-09-291-5/+5
| | | | | | | | cppcheck points out that qrap's main shadows the global err() function with a local. Rename it to rc to avoid the clash. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Don't shadow 'i' in conf_ports()David Gibson2022-09-291-2/+5
| | | | | | | | | | | | | | The counter 'i' is used in a number of places in conf_ports(), but in one of those we unnecessarily shadow it in an inner scope. We could re-use the same 'i' every time, but each use is logically separate, so instead remove the outer declaration and declare it locally in each of the clauses where we need it. While we're there change it from a signed to unsigned int, since it's used to iterate over port numbers which are generally treated as unsigned. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* cppcheck: Reduce scope of some variablesDavid Gibson2022-09-293-5/+7
| | | | | | | Minor style improvement suggested by cppcheck. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Clean up parsing in conf_runas()David Gibson2022-09-292-47/+51
| | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Pack DHCPv6 "on wire" structuresDavid Gibson2022-09-291-13/+13
| | | | | | | | | | | | | | | | | | | dhcpv6.c contains a number of structures which represent actual DHCPv6 packets as they appear on the wire, which will break if the structures don't have exactly the in-memory layout we expect. Therefore, we should mark these structures as ((packed)). The contents of them means this is unlikely to change the layout in practice - and since it was working, presumably didn't on any arch we were testing on. However it's not impossible for the compiler on some arch to insert unexpected padding in one of these structures, so we should be explicit. clang-tidy warned about this since we were using memcmp() to compare some of these structures, which it thought might not have a unique representation. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Catch failures when installing signal handlersDavid Gibson2022-09-291-2/+4
| | | | | | | | | Stop ignoring the return codes from sigaction() and signal(). Unlikely to happen in practice, but if it ever did it could lead to really hard to debug problems. So, take clang-tidy's advice and check for errors here. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* clang-tidy: Remove duplicate #include from icmp.cDavid Gibson2022-09-291-1/+0
| | | | | Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* clang-tidy: Fix spurious null pointer warning in pasta_start_ns()David Gibson2022-09-291-1/+4
| | | | | | | | | | | | clang-tidy isn't quite clever enough to figure out that getenv("SHELL") will return the same thing both times here, which makes it conclude that shell could be NULL, causing problems later. It's a bit ugly that we call getenv() twice in any case, so rework this in a way that clang-tidy can figure out shell won't be NULL. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* clang-tidy: Suppress warning about unchecked error in logfn macroDavid Gibson2022-09-291-1/+1
| | | | | | | | | clang-tidy complains that we're not checking the result of vfprintf in logfn(). There's not really anything we can do if this fails here, so just suppress the error with a cast to void. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* Clean up parsing of port rangesDavid Gibson2022-09-291-140/+102
| | | | | | | | | | | | | | | | | | | | conf_ports() parses ranges of ports for the -t, -u, -T and -U options. The code is quite difficult to the follow, to the point that clang-tidy and cppcheck disagree on whether one of the pointers can be NULL at some points. Rework the code with the use of two new helper functions: * parse_port_range() operates a bit like strtoul(), but can parse a whole port range specification (e.g. '80' or '1000-1015') * next_chunk() does the necessary wrapping around strchr() to advance to just after the next given delimiter, while cleanly handling if there are no more delimiters The new version is easier to follow, and also removes some cppcheck warnings. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* cppcheck: Add target specific headersDavid Gibson2022-09-291-1/+1
| | | | | | | | | 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>
* Makefile: Simplify getting target triple for compilerDavid Gibson2022-09-291-2/+2
| | | | | | | | | | 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>
* cppcheck: Run quietlyDavid Gibson2022-09-291-1/+1
| | | | | | | | 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>
* cppcheck: Avoid excessive scanning due to system headersDavid Gibson2022-09-291-14/+6
| | | | | | | | | | | | | | | | | 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>
* clang-tidy: Disable 'readability-identifier-length'David Gibson2022-09-291-1/+6
| | | | | | | | 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>
* test: Remove unneccessary pane naming from layout_two_guestsDavid Gibson2022-09-291-4/+0
| | | | | | | | | This loop goes through and gives a numeric label to each pane, even though we name the panes properly shortly thereafter. Looks like a leftover from some earlier version. Remove it. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* test: Simplify data handling for transfer testsDavid Gibson2022-09-2910-294/+214
| | | | | | | | | | | | | | | | | | | | | | | | | | Many of our tests are based around performing transfers of sample data across passt/pasta created links. The data flow here can be a bit hard to follow since, e.g. we create a file transfer it to the guest, then transfer it back to the host across several different tests. This also means that the test cases aren't independent of each other. Because we don't have the original file available at both ends in some cases, we compare them by generating md5sums at each end and comparing them, which is a bit complicated. Make a number of changes to simplify this: 1. Pre-generate the sample data files as a test asset, rather than building them on the fly during the tests proper 2. Include the sample data files in the mbuto guest image 3. Because we have good copies of the original data available in all contexts, we can now simply use 'cmp' to check if the transfer has worked, avoiding md5sum complications. 4. Similarly we can always use the original copy of the sample data on the send side of each transfer, meaning that the tests become more independent of each other. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* test: Use --config-net for namespace setupDavid Gibson2022-09-291-14/+3
| | | | | | | | | | | | | | The setup functions for passt_in_ns and two_guests perform some fairly slow dhclient calls to configure the network in the namespace before starting the guest. This isn't really part of the tests, just necessary for the operations later. We can simplify and speed this up a bit by using pasta's '--config-net' option to configure the networking for us. As a bonus this means we have at least a minimal test of the --config-net option itself. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* test: More robust wait for pasta/passt to be readyDavid Gibson2022-09-291-5/+10
| | | | | | | | | | | | | When we start passt or pasta, it may take a short time to be ready to handle packets, especially if running under valgrind. We have a number of semi-arbitrary fixed sleeps to account for this. We can do this more robustly by exploiting the fact that pasta/passt doesn't write its pidfile until it's ready to go, so if we wait for the pidfile to be created, we can proceed with confidence. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* test: Remove unnecessary sleeps from shutdown testsDavid Gibson2022-09-292-2/+0
| | | | | | | | These are hangovers from older ways of shutting down the pasta/passt processes and no longer serve any purpose. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* test: Add wait_for() shell helperDavid Gibson2022-09-292-3/+9
| | | | | | | | | | Add a shell helper function to wait for some command to succeed - typically a test for something to be done by a background process. Use it in the context code which waits for the guest to respond to ssh-over-vsock connections. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
* icmp: Correct off by one errors dealing with number of echo request ids2022_09_24.8978f65David Gibson2022-09-241-2/+3
| | | | | | | | | | ICMP echo request and reply packets include a 16-bit 'id' value. We have some arrays indexed by this id value. Unfortunately we size those arrays with USHRT_MAX (65535) when they need to be sized by the total number of id values (65536). This could lead to buffer overruns. Resize the arrays correctly, using a new define for the purpose. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Fix widespread off-by-one error dealing with port numbersDavid Gibson2022-09-245-16/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | Port numbers (for both TCP and UDP) are 16-bit, and so fit exactly into a 'short'. USHRT_MAX is therefore the maximum port number and this is widely used in the code. Unfortunately, a lot of those places don't actually want the maximum port number (USHRT_MAX == 65535), they want the total number of ports (65536). This leads to a number of potentially nasty consequences: * We have buffer overruns on the port_fwd::delta array if we try to use port 65535 * We have similar potential overruns for the tcp_sock_* arrays * Interestingly udp_act had the correct size, but we can calculate it in a more direct manner * We have a logical overrun of the ports bitmap as well, although it will just use an unused bit in the last byte so isnt harmful * Many loops don't consider port 65535 (which does mitigate some but not all of the buffer overruns above) * In udp_invert_portmap() we incorrectly compute the reverse port translation for return packets Correct all these by using a new NUM_PORTS defined explicitly for this purpose. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Treat port numbers as unsignedDavid Gibson2022-09-243-8/+9
| | | | | | | | | | | Port numbers are unsigned values, but we're storing them in (signed) int variables in some places. This isn't actually harmful, because int is large enough to hold the entire range of ports. However in places we don't want to use an in_port_t (usually to avoid overflow on the last iteration of a loop) it makes more conceptual sense to use an unsigned int. This will also avoid some problems with later cleanups. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Pass entire port forwarding configuration substructure to conf_ports()David Gibson2022-09-241-40/+22
| | | | | | | | | conf_ports() switches on the optname argument to select the target array for several updates. Now that all these maps are in a common structure, we can simplify by just passing in a pointer to the whole struct port_fwd to update. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Don't use indirect remap functions for conf_ports()David Gibson2022-09-245-55/+7
| | | | | | | | | | Now that we've delayed initialization of the UDP specific "reverse" map until udp_init(), the only difference between the various 'remap' functions used in conf_ports() is which array they target. So, simplify by open coding the logic into conf_ports() with a pointer to the correct mapping array. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* udp: Delay initialization of UDP reversed port mapping tableDavid Gibson2022-09-242-4/+23
| | | | | | | | | | | | | | | Because it's connectionless, when mapping UDP ports we need, in addition to the table of deltas for destination ports needed by TCP, we need an inverted table to translate the source ports on return packets. Currently we fill out the inverted table at the same time we construct the main table in udp_remap_to_tap() and udp_remap_to_init(). However, we don't use either table until after we've initialized UDP, so we can delay the construction of the reverse table to udp_init(). This makes the configuration more symmetric between TCP and UDP which will enable further cleanups. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>