All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: syzbot <syzbot+29125d208b3dae9a7019@syzkaller.appspotmail.com>,
	pablo@netfilter.org
Cc: coreteam@netfilter.org, davem@davemloft.net, fw@strlen.de,
	kadlec@netfilter.org, linux-kernel@vger.kernel.org,
	netdev@vger.kernel.org, netfilter-devel@vger.kernel.org,
	syzkaller-bugs@googlegroups.com
Subject: Re: KASAN: use-after-free Read in __nf_tables_abort
Date: Tue, 21 Jan 2020 14:32:36 +0300	[thread overview]
Message-ID: <20200121113235.GA1847@kadam> (raw)
In-Reply-To: <000000000000367175059c90b6bf@google.com>

I think I see the problem, but I'm not sure how you want to fix it...

net/netfilter/nf_tables_api.c
   942  static int nf_tables_newtable(struct net *net, struct sock *nlsk,
   943                                struct sk_buff *skb, const struct nlmsghdr *nlh,
   944                                const struct nlattr * const nla[],
   945                                struct netlink_ext_ack *extack)
   946  {
   947          const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
   948          u8 genmask = nft_genmask_next(net);
   949          int family = nfmsg->nfgen_family;
   950          const struct nlattr *attr;
   951          struct nft_table *table;
   952          u32 flags = 0;
   953          struct nft_ctx ctx;
   954          int err;
   955  
   956          lockdep_assert_held(&net->nft.commit_mutex);
   957          attr = nla[NFTA_TABLE_NAME];
   958          table = nft_table_lookup(net, attr, family, genmask);
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is looking up table in net->nft.tables

   959          if (IS_ERR(table)) {
   960                  if (PTR_ERR(table) != -ENOENT)
   961                          return PTR_ERR(table);
   962          } else {
   963                  if (nlh->nlmsg_flags & NLM_F_EXCL) {
   964                          NL_SET_BAD_ATTR(extack, attr);
   965                          return -EEXIST;
   966                  }
   967                  if (nlh->nlmsg_flags & NLM_F_REPLACE)
   968                          return -EOPNOTSUPP;
   969  
   970                  nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
   971                  return nf_tables_updtable(&ctx);
                               ^^^^^^^^^^^^^^^^^^^^^^^
Then it adds it to &ctx->net->nft.commit_list

   972          }
   973  
   974          if (nla[NFTA_TABLE_FLAGS]) {
   975                  flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
   976                  if (flags & ~NFT_TABLE_F_DORMANT)
   977                          return -EINVAL;
   978          }
   979  
   980          err = -ENOMEM;
   981          table = kzalloc(sizeof(*table), GFP_KERNEL);
   982          if (table == NULL)
   983                  goto err_kzalloc;
   984  
   985          table->name = nla_strdup(attr, GFP_KERNEL);
   986          if (table->name == NULL)
   987                  goto err_strdup;
   988  
   989          err = rhltable_init(&table->chains_ht, &nft_chain_ht_params);
   990          if (err)
   991                  goto err_chain_ht;
   992  
   993          INIT_LIST_HEAD(&table->chains);
   994          INIT_LIST_HEAD(&table->sets);
   995          INIT_LIST_HEAD(&table->objects);
   996          INIT_LIST_HEAD(&table->flowtables);
   997          table->family = family;
   998          table->flags = flags;
   999          table->handle = ++table_handle;
  1000  
  1001          nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
  1002          err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Added to ctx->net->nft.commit_list

  1003          if (err < 0)
  1004                  goto err_trans;
  1005  
  1006          list_add_tail_rcu(&table->list, &net->nft.tables);
                                                ^^^^^^^^^^^^^^^^
Added to net->nft.tables

  1007          return 0;
  1008  err_trans:
  1009          rhltable_destroy(&table->chains_ht);
  1010  err_chain_ht:
  1011          kfree(table->name);
  1012  err_strdup:
  1013          kfree(table);

net/netfilter/nf_tables_api.c
  6995  static void nf_tables_commit_release(struct net *net)
  6996  {
  6997          struct nft_trans *trans;
  6998  
  6999          /* all side effects have to be made visible.
  7000           * For example, if a chain named 'foo' has been deleted, a
  7001           * new transaction must not find it anymore.
  7002           *
  7003           * Memory reclaim happens asynchronously from work queue
  7004           * to prevent expensive synchronize_rcu() in commit phase.
  7005           */
  7006          if (list_empty(&net->nft.commit_list)) {
  7007                  mutex_unlock(&net->nft.commit_mutex);
  7008                  return;
  7009          }
  7010  
  7011          trans = list_last_entry(&net->nft.commit_list,
  7012                                  struct nft_trans, list);
  7013          get_net(trans->ctx.net);
  7014          WARN_ON_ONCE(trans->put_net);
  7015  
  7016          trans->put_net = true;
  7017          spin_lock(&nf_tables_destroy_list_lock);
  7018          list_splice_tail_init(&net->nft.commit_list, &nf_tables_destroy_list);
                                       ^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^
This starts the process of freeing everything from net->nft.commit_list,
but we need to delete it from the net->nft.tables list as well.

  7019          spin_unlock(&nf_tables_destroy_list_lock);
  7020  
  7021          mutex_unlock(&net->nft.commit_mutex);
  7022  
  7023          schedule_work(&trans_destroy_work);
  7024  }

regards,
dan carpenter

  reply	other threads:[~2020-01-21 11:36 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-20 11:37 KASAN: use-after-free Read in __nf_tables_abort syzbot
2020-01-21 11:32 ` Dan Carpenter [this message]
2020-01-21 12:37 ` syzbot
2020-01-21 21:50 ` syzbot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200121113235.GA1847@kadam \
    --to=dan.carpenter@oracle.com \
    --cc=coreteam@netfilter.org \
    --cc=davem@davemloft.net \
    --cc=fw@strlen.de \
    --cc=kadlec@netfilter.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    --cc=syzbot+29125d208b3dae9a7019@syzkaller.appspotmail.com \
    --cc=syzkaller-bugs@googlegroups.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.