summaryrefslogtreecommitdiffstats
path: root/iptables
Commit message (Collapse)AuthorAgeFilesLines
* tests: shell: Fix syntax in ipt-restore/0010-noflush-new-chain_0Phil Sutter2020-05-291-0/+1
| | | | | | | | The here-doc statement missed the final delimiter. Worked anyways because end-of-file would do the trick. Fixes: a103fbfadf4c1 ("xtables-restore: Fix parser feed from line buffer") Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Drop save_counters callback from family_opsPhil Sutter2020-05-187-16/+3
| | | | | | | All families use the same callback function, just fold it into the sole place it's called. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Merge nft_*_rule_find() functionsPhil Sutter2020-05-187-112/+40
| | | | | | | | | Both ebtables and arptables are fine with using nft_ipv46_rule_find() instead of their own implementations. Take the chance and move the former into nft.c as a static helper since it is used in a single place, only. Then get rid of the callback from family_ops. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Don't exit early after printing help textsPhil Sutter2020-05-113-9/+10
| | | | | | | Follow regular code path after handling --help option to gracefully deinit and free stuff. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Fix leak when replacing a rulePhil Sutter2020-05-111-1/+2
| | | | | | | | | | If nft_rule_append() is called with a reference rule, it is supposed to insert the new rule at the reference position and then remove the reference from cache. Instead, it removed the new rule from cache again right after inserting it. Also, it missed to free the removed rule. Fixes: 5ca9acf51adf9 ("xtables: Fix position of replaced rules in cache") Signed-off-by: Phil Sutter <phil@nwl.cc>
* arptables: Fix leak in nft_arp_print_rule()Phil Sutter2020-05-111-0/+2
| | | | | | | The function missed to clear struct iptables_command_state again after use. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Use clear_cs() instead of open codingPhil Sutter2020-05-114-10/+4
| | | | | | | | In a few places, initialized struct iptables_command_state was not fully deinitialized. Change them to call nft_clear_iptables_command_state() which does it properly. Signed-off-by: Phil Sutter <phil@nwl.cc>
* libxtables: Introduce xtables_fini()Phil Sutter2020-05-1111-6/+36
| | | | | | | | | | | | Record handles of loaded shared objects in a linked list and dlclose() them from the newly introduced function. While functionally not necessary, this clears up valgrind's memcheck output when also displaying reachable memory. Since this is an extra function that doesn't change the existing API, increment both current and age. Signed-off-by: Phil Sutter <phil@nwl.cc>
* ebtables: Free statically loaded extensions againPhil Sutter2020-05-114-2/+20
| | | | | | | | | All ebtables extensions are loaded upon program start as due to the lack of '-m' parameters, loading on demand is not possible. Introduce nft_fini_eb() to counteract nft_init_eb() and free dynamic memory in matches and targets from there. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Fix leak when deleting rulesPhil Sutter2020-05-111-1/+1
| | | | | | | For NFT_COMPAT_RULE_DELETE jobs, batch_obj_del() has to do the rule freeing, they are no longer in cache. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Fix leaks in ebt_add_policy_rule()Phil Sutter2020-05-111-6/+12
| | | | | | | | | | | | | | | | | | The function leaked memory allocated in temporary struct iptables_command_state, clean it immediately after use. In any of the udata-related error cases, allocated nftnl_rule would leak, fix this by introducing a common error path to goto. In regular code path, the allocated nftnl_rule would still leak: batch_obj_del() does not free rules in NFT_COMPAT_RULE_APPEND jobs, as they typically sit in cache as well. Policy rules in turn weren't added to cache: They are created immediately before commit and never referenced from other rules. Add them now so they are freed just like regular rules. Fixes: aff1162b3e4b7 ("ebtables-nft: Support user-defined chain policies") Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Clear all lists in nft_fini()Phil Sutter2020-05-111-3/+9
| | | | | | | | Remove and free any pending entries in obj_list and err_list as well. To get by without having to declare list-specific cursors, use generic list_head types and call list_entry() explicitly. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Re-establish cache consistency checkPhil Sutter2020-05-111-0/+11
| | | | | | | | | | | | | Restore code ensuring __nft_build_cache() returns a consistent cache in which all ruleset elements belong to the same generation. This check was removed by commit 200bc39965149 ("nft: cache: Fix iptables-save segfault under stress") as it could lead to segfaults if a partial cache fetch was done while cache's chain list was traversed. With the new cache fetch logic, __nft_build_cache() is never called while holding references to cache entries. Signed-off-by: Phil Sutter <phil@nwl.cc>
* tests: shell: Implement --valgrind modePhil Sutter2020-05-111-0/+47
| | | | | | | | | | | | | | | | | | Wrap every call to $XT_MULTI with valgrind, or actually a wrapper script which does the valgrind wrap and stores the log if it contains something relevant. Carefully name the wrapper script(s) so that test cases' checks on $XT_MULTI name stay intact. This mode slows down testsuite execution horribly. Luckily, it's not meant for constant use, though. For now, ignore commands with non-zero exit status - error paths typically hit direct exit() calls and therefore leave reachable memory in place. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Fix for '-F' in iptables dumpsPhil Sutter2020-05-111-0/+34
| | | | | | | | | | | When restoring a dump which contains an explicit flush command, previously added rules are removed from cache and the following commit will try to create netlink messages based on freed memory. Fix this by weeding any rule-based commands from obj_list if they address the same chain. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Optimize caching for flush commandPhil Sutter2020-05-113-1/+39
| | | | | | | | | | | | | | | | | | When flushing all chains and verbose mode is not enabled, nft_rule_flush() uses a shortcut: It doesn't specify a chain name for NFT_MSG_DELRULE, so the kernel will flush all existing chains without user space needing to know which they are. The above allows to avoid a chain cache, but there's a caveat: nft_xt_builtin_init() will create base chains as it assumes they are missing and thereby possibly overrides any non-default chain policies. Solve this by making nft_xt_builtin_init() cache-aware: If a command doesn't need a chain cache, there's no need to bother with creating any non-existing builtin chains, either. For the sake of completeness, also do nothing if cache is not initialized (although that shouldn't happen). Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Fetch cache for specific chainsPhil Sutter2020-05-113-8/+81
| | | | | | | | | | | | | | | | | Iterate over command list and collect chains to cache. Insert them into a sorted list to pass to __nft_build_cache(). If a command is interested in all chains (e.g., --list), cmd->chain remains unset. To record this case reliably, use a boolean ('all_chains'). Otherwise, it is hard to distinguish between first call to nft_cache_level_set() and previous command with NULL cmd->chain value. When caching only specific chains, manually add builtin ones for the given table as well - otherwise nft_xt_builtin_init() will act as if they don't exist and possibly override non-default chain policies. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft-cache: Introduce __fetch_chain_cache()Phil Sutter2020-05-111-20/+30
| | | | | | | Extract the inner part of fetch_chain_cache() into a dedicated function, preparing for individual chain caching. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft-cache: Fetch cache per tablePhil Sutter2020-05-117-44/+64
| | | | | | | | | | | | | | | | | | | | | | | | | | | Restore per-table operation of cache routines as initially implemented in commit e2883c5531e6e ("nft-cache: Support partial cache per table"). As before, this doesn't limit fetching of tables (their number is supposed to be low) but instead limits fetching of sets, chains and rules to the specified table. For this to behave correctly when restoring without flushing over multiple tables, cache must be freed fully after each commit - otherwise the previous table's cache level is reused for the current one. The exception being fake cache, used for flushing restore: NFT_CL_FAKE is set just once at program startup, so it must stay set otherwise consecutive tables cause pointless cache fetching. The sole use-case requiring a multi-table cache, iptables-save, is indicated by req->table being NULL. Therefore, req->table assignment is a bit sloppy: All calls to nft_cache_level_set() are assumed to set the same table value, collision detection exists merely to catch programming mistakes. Make nft_fini() call nft_release_cache() instead of flush_chain_cache(), the former does a full cache deinit including cache_req contents. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Introduce struct nft_cache_reqPhil Sutter2020-05-112-16/+22
| | | | | | | | | | This embedded struct collects cache requirement info gathered from parsed nft_cmds and is interpreted by __nft_build_cache(). While being at it, remove unused parameters passed to the latter function, nft_handle pointer is sufficient. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Improve fake cache integrationPhil Sutter2020-05-113-15/+4
| | | | | | | | With NFT_CL_FAKE being highest cache level while at the same time __nft_build_cache() treating it equal to NFT_CL_TABLES, no special handling for fake cache is required anymore. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Simplify rule and set fetchersPhil Sutter2020-05-111-15/+5
| | | | | | | | | | | | Since no incremental cache fetching happens anymore, code fetching rules for chains or elements for sets may safely assume that whatever is in cache also didn't get populated with rules or elements before. Therefore no (optional) chain name needs to be passed on to fetch_rule_cache() and fetch_set_cache() doesn't have to select for which sets in a table to call set_fetch_elem_cb(). Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: missing nft_fini() call in bridge familyPablo Neira Ayuso2020-05-111-0/+2
| | | | | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: remove cache build callsPablo Neira Ayuso2020-05-113-42/+0
| | | | | | | | | The cache requirements are now calculated once from the parsing phase. There is no need to call __nft_build_cache() from several spots in the codepath anymore. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: restore among supportPablo Neira Ayuso2020-05-113-2/+32
| | | | | | | Update among support to work again with the new parser and cache logic. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: calculate cache requirements from list of commandsPablo Neira Ayuso2020-05-118-127/+119
| | | | | | | | | | | | | | | | | | | | This patch uses the new list of commands to calculate the cache requirements, the rationale after this updates is the following: #1 Parsing, that builds the list of commands and it also calculates cache level requirements. #2 Cache building. #3 Translate commands to jobs #4 Translate jobs to netlink This patch removes the pre-parsing code in xtables-restore.c to calculate the cache. After this patch, cache is calculated only once, there is no need to cancel and refetch for an in-transit transaction. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: split parsing from netlink commandsPablo Neira Ayuso2020-05-1115-143/+726
| | | | | | | | | | | | | | This patch updates the parser to generate a list of command objects. This list of commands is then transformed to a list of netlink jobs. This new command object stores the rule using the nftnl representation via nft_rule_new(). To reduce the number of updates in this patch, the nft_*_rule_find() functions have been updated to restore the native representation to skip the update of the rule comparison code. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Phil Sutter <phil@nwl.cc>
* ebtables-restore: Table line to trigger implicit commitPhil Sutter2020-05-111-0/+4
| | | | | | | | | | | | | | Cache code is suited for holding multiple tables' data at once. The only users of that are xtables-save and ebtables-restore with its support for multiple tables and lack of explicit COMMIT lines. Remove the second user by introducing implicit commits upon table line parsing. This would allow to make cache single table only, but then xtables-save would fetch cache multiple times (once for each table) and therefore lose atomicity with regards to the acquired kernel ruleset image. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Fetch sets per tablePhil Sutter2020-05-111-11/+15
| | | | | | | Kernel accepts a table name when dumping sets, so make use of that in case a table was passed to fetch_set_cache() but no set name. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Init per table set list along with chain listPhil Sutter2020-05-111-15/+4
| | | | | | | This simplifies code a bit and also aligns set and chain lists handling in cache. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Eliminate init_chain_cache()Phil Sutter2020-05-111-12/+4
| | | | | | | The function is always called immediately after fetch_table_cache(), so merge it into the latter. Signed-off-by: Phil Sutter <phil@nwl.cc>
* ebtables-restore: Drop custom table flush routinePhil Sutter2020-05-113-30/+1
| | | | | | | | At least since flushing xtables-restore doesn't fetch chains from kernel anymore, problems with pending policy rule delete jobs can't happen anymore. Signed-off-by: Phil Sutter <phil@nwl.cc>
* iptables: flush stdout after every verbose log.Maciej Żenczykowski2020-05-112-2/+6
| | | | | | | | | | | | | | | | | | | | | Ensures that each logged line is flushed to stdout after it's written, and not held in any buffer. Places to modify found via: git grep -C5 'fputs[(]buffer, stdout[)];' On Android iptables-restore -v is run as netd daemon's child process and fed actions via pipe. '#PING' is used to verify the child is still responsive, and thus needs to be unbuffered. Luckily if you're running iptables-restore in verbose mode you probably either don't care about performance or - like Android - actually need this. Test: builds, required on Android for ip6?tables-restore netd subprocess health monitoring. Signed-off-by: Maciej Żenczykowski <maze@google.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: Add test for nfbz#1391Phil Sutter2020-04-281-0/+7
| | | | | | | | Problem is fixed since commit c550c81fd373e ("nft: cache: Fix nft_release_cache() under stress"), looks like another case of use-after-free. Signed-off-by: Phil Sutter <phil@nwl.cc>
* iptables: include sys/time.h to fix lack of struct timeval declarationMaciej Żenczykowski2020-04-281-0/+1
| | | | | | | | | | | | | | | This fixes clang compiler warnings: iptables/xshared.h:176:50: error: declaration of 'struct timeval' will not be visible outside of this function [-Werror,-Wvisibility] extern int xtables_lock_or_exit(int wait, struct timeval *tv); ^ iptables/xshared.h:179:57: error: declaration of 'struct timeval' will not be visible outside of this function [-Werror,-Wvisibility] void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval); ^ Test: builds with less warnings Signed-off-by: Maciej Żenczykowski <maze@google.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: Test -F in dump filesPhil Sutter2020-04-231-0/+12
| | | | | | | While not really useful, iptables-nft-restore shouldn't segfault either. This tests the problem described in nfbz#1407. Signed-off-by: Phil Sutter <phil@nwl.cc>
* tests: shell: Extend ipt-restore/0004-restore-race_0Phil Sutter2020-04-231-3/+2
| | | | | | | | | Add a second table to dump/restore. This triggers failures after reverting c550c81fd373e ("nft: cache: Fix nft_release_cache() under stress"), hence acts as a reproducer for the bug fixed by that commit as well. Signed-off-by: Phil Sutter <phil@nwl.cc>
* tests: shell: Improve ipt-restore/0001load-specific-table_0 a bitPhil Sutter2020-04-231-1/+1
| | | | | | | | Instead of reading from stdin, pass dump file as regular parameter. This way dump file name occurs in 'bash -x' output which helps finding out where things fail. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xshared: Drop pointless assignment in add_param_to_argv()Phil Sutter2020-04-231-1/+0
| | | | | | This must be a leftover from a previous cleanup. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft-shared: skip check for jumpto if cs->target is unsetPablo Neira Ayuso2020-04-151-1/+2
| | | | | | | | | The command_jump() function leaves cs->target unset if the target is not found. Let's check if the jumpto string mismatches only in this case. https://bugzilla.netfilter.org/show_bug.cgi?id=1422 Tested-by: Etienne Champetier <etienne.champetier@anevia.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: cache: Fix iptables-save segfault under stressPhil Sutter2020-03-161-14/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If kernel ruleset is constantly changing, code called by nft_is_table_compatible() may crash: For each item in table's chain list, nft_is_chain_compatible() is called. This in turn calls nft_build_cache() to fetch chain's rules. Though if kernel genid has changed meanwhile, cache is flushed and rebuilt from scratch, thereby freeing table's chain list - the foreach loop in nft_is_table_compatible() then operates on freed memory. A simple reproducer (may need a few calls): | RULESET='*filter | :INPUT ACCEPT [10517:1483527] | :FORWARD ACCEPT [0:0] | :OUTPUT ACCEPT [1714:105671] | COMMIT | ' | | for ((i = 0; i < 100; i++)); do | iptables-nft-restore <<< "$RULESET" & | done & | iptables-nft-save To fix the problem, basically revert commit ab1cd3b510fa5 ("nft: ensure cache consistency") so that __nft_build_cache() no longer flushes the cache. Instead just record kernel's genid when fetching for the first time. If kernel rule set changes until the changes are committed, the commit simply fails and local cache is being rebuilt. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Fix for unused variable warningsPhil Sutter2020-03-161-3/+1
| | | | | | | Loop index variable was left in place after removing the loops. Fixes: 39ec645093baa ("nft: cache: Simplify chain list allocation") Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Review flush_cache()Phil Sutter2020-03-061-9/+11
| | | | | | | | | While fixing for iptables-nft-restore under stress, I managed to hit NULL-pointer deref in flush_cache(). Given that nftnl_*_list_free() functions are not NULL-pointer tolerant, better make sure such are not passed by accident. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Simplify chain list allocationPhil Sutter2020-03-061-27/+19
| | | | | | | | | | Allocate chain lists right after fetching table cache, regardless of whether partial cache is fetched or not. Chain list pointers reside in struct nft_cache's table array and hence are present irrespective of actual tables in kernel. Given the small number of tables, there wasn't much overhead avoided by the conditional in fetch_chain_cache(). Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Make nft_rebuild_cache() respect fake cachePhil Sutter2020-03-062-4/+10
| | | | | | | | | | | | If transaction needed a refresh in nft_action(), restore with flush would fetch a full cache instead of merely refreshing table list contained in "fake" cache. To fix this, nft_rebuild_cache() must distinguish between fake cache and full rule cache. Therefore introduce NFT_CL_FAKE to be distinguished from NFT_CL_RULES. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Fix nft_release_cache() under stressPhil Sutter2020-03-061-2/+8
| | | | | | | | | | | | | | | | | iptables-nft-restore calls nft_action(h, NFT_COMPAT_COMMIT) for each COMMIT line in input. When restoring a dump containing multiple large tables, chances are nft_rebuild_cache() has to run multiple times. If the above happens, consecutive table contents are added to __cache[1] which nft_rebuild_cache() then frees, so next commit attempt accesses invalid memory. Fix this by making nft_release_cache() (called after each successful commit) return things into pre-rebuild state again, but keeping the fresh cache copy. Fixes: f6ad231d698c7 ("nft: keep original cache in case of ERESTART") Signed-off-by: Phil Sutter <phil@nwl.cc>
* xtables: Review nft_init()Phil Sutter2020-02-2410-42/+24
| | | | | | | | | | | | | | | | | Move common code into nft_init(), such as: * initial zeroing nft_handle fields * family ops lookup and assignment to 'ops' field * setting of 'family' field This requires minor adjustments in xtables_restore_main() so extra field initialization doesn't happen before nft_init() call. As a side-effect, this fixes segfaulting xtables-monitor binary when printing rules for trace event as in that code-path 'ops' field wasn't initialized. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xtables: Drop -4 and -6 support from xtables-{save,restore}Phil Sutter2020-02-242-18/+2
| | | | | | Legacy tools don't support those options, either. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xtables: Align effect of -4/-6 options with legacyPhil Sutter2020-02-242-13/+96
| | | | | | | | | | Legacy iptables doesn't accept -4 or -6 if they don't match the symlink's native family. The only exception to that is iptables-restore which simply ignores the lines introduced by non-matching options, which is useful to create combined dump files for feeding into both iptables-restore and ip6tables-restore. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Drop pointless assignmentPhil Sutter2020-02-181-1/+0
| | | | | | | | No need to set 'i' to zero here, it is not used before the next assignment. Fixes: 77e6a93d5c9dc ("xtables: add and set "implict" flag on transaction objects") Signed-off-by: Phil Sutter <phil@nwl.cc>