1. 02 May, 2019 5 commits
    • Florian Westphal's avatar
      netfilter: nf_tables: warn when expr implements only one of activate/deactivate · 27458b54
      Florian Westphal authored
      ->destroy is only allowed to free data, or do other cleanups that do not
      have side effects on other state, such as visibility to other netlink
      requests.
      
      Such things need to be done in ->deactivate.
      As a transaction can fail, we need to make sure we can undo such
      operations, therefore ->activate() has to be provided too.
      
      So print a warning and refuse registration if expr->ops provides
      only one of the two operations.
      
      v2: fix nft_expr_check_ops to not repeat same check twice (Jones Desougi)
      Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
      Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
      27458b54
    • Florian Westphal's avatar
      netfilter: nft_compat: destroy function must not have side effects · cb2e343d
      Florian Westphal authored
      The nft_compat destroy function deletes the nft_xt object from a list.
      This isn't allowed anymore. Destroy functions are called asynchronously,
      i.e. next batch can find the object that has a pending ->destroy()
      invocation:
      
      cpu0                       cpu1
       worker
         ->destroy               for_each_entry()
      	                     if (x == ...
      			        return x->ops;
           list_del(x)
           kfree_rcu(x)
                                 expr->ops->... // ops was free'd
      
      To resolve this, the list_del needs to occur before the transaction
      mutex gets released.  nf_tables has a 'deactivate' hook for this
      purpose, so use that to unlink the object from the list.
      
      Fixes: 0935d558 ("netfilter: nf_tables: asynchronous release")
      Reported-by: default avatarTaehee Yoo <ap420073@gmail.com>
      Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
      Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
      cb2e343d
    • Florian Westphal's avatar
      netfilter: nf_tables: split set destruction in deactivate and destroy phase · 3dbba8eb
      Florian Westphal authored
      [ Upstream commit cd5125d8 ]
      
      Splits unbind_set into destroy_set and unbinding operation.
      
      Unbinding removes set from lists (so new transaction would not
      find it anymore) but keeps memory allocated (so packet path continues
      to work).
      
      Rebind function is added to allow unrolling in case transaction
      that wants to remove set is aborted.
      
      Destroy function is added to free the memory, but this could occur
      outside of transaction in the future.
      Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
      Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
      Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
      3dbba8eb
    • Florian Westphal's avatar
      netfilter: nft_compat: make lists per netns · 7693bae6
      Florian Westphal authored
      [ Upstream commit cf52572e ]
      
      There are two problems with nft_compat since the netlink config
      plane uses a per-netns mutex:
      
      1. Concurrent add/del accesses to the same list
      2. accesses to a list element after it has been free'd already.
      
      This patch fixes the first problem.
      
      Freeing occurs from a work queue, after transaction mutexes have been
      released, i.e., it still possible for a new transaction (even from
      same net ns) to find the to-be-deleted expression in the list.
      
      The ->destroy functions are not allowed to have any such side effects,
      i.e. the list_del() in the destroy function is not allowed.
      
      This part of the problem is solved in the next patch.
      I tried to make this work by serializing list access via mutex
      and by moving list_del() to a deactivate callback, but
      Taehee spotted following race on this approach:
      
        NET #0                          NET #1
         >select_ops()
         ->init()
                                         ->select_ops()
         ->deactivate()
         ->destroy()
            nft_xt_put()
             kfree_rcu(xt, rcu_head);
                                         ->init() <-- use-after-free occurred.
      
      Unfortunately, we can't increment reference count in
      select_ops(), because we can't undo the refcount increase in
      case a different expression fails in the same batch.
      
      (The destroy hook will only be called in case the expression
       was initialized successfully).
      
      Fixes: f102d66b ("netfilter: nf_tables: use dedicated mutex to guard transactions")
      Reported-by: default avatarTaehee Yoo <ap420073@gmail.com>
      Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
      Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
      Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
      7693bae6
    • Florian Westphal's avatar
      netfilter: nft_compat: use refcnt_t type for nft_xt reference count · db99f122
      Florian Westphal authored
      [ Upstream commit 12c44aba ]
      
      Using standard integer type was fine while all operations on it were
      guarded by the nftnl subsys mutex.
      
      This isn't true anymore:
      1. transactions are guarded only by a pernet mutex, so concurrent
         rule manipulation in different netns is racy
      2. the ->destroy hook runs from a work queue after the transaction
         mutex has been released already.
      
      cpu0                           cpu1 (net 1)        cpu2 (net 2)
       kworker
          nft_compat->destroy        nft_compat->init    nft_compat->init
            if (--nft_xt->ref == 0)   nft_xt->ref++        nft_xt->ref++
      
      Switch to refcount_t.  Doing this however only fixes a minor aspect,
      nft_compat also performs linked-list operations in an unsafe way.
      
      This is addressed in the next two patches.
      
      Fixes: f102d66b ("netfilter: nf_tables: use dedicated mutex to guard transactions")
      Fixes: 0935d558 ("netfilter: nf_tables: asynchronous release")
      Reported-by: default avatarTaehee Yoo <ap420073@gmail.com>
      Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
      Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
      Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
      db99f122
  2. 27 Apr, 2019 35 commits