[bug report] netfilter: nf_tables: add elements with stateful expressions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Pablo Neira Ayuso,

The patch 409444522976: "netfilter: nf_tables: add elements with
stateful expressions" from Mar 11, 2020, leads to the following
static checker warning:

	net/netfilter/nf_tables_api.c:5140 nft_add_set_elem()
	warn: passing freed memory 'expr'

net/netfilter/nf_tables_api.c
  5067          ext = nft_set_elem_ext(set, elem.priv);
  5068          if (flags)
  5069                  *nft_set_ext_flags(ext) = flags;
  5070          if (ulen > 0) {
  5071                  udata = nft_set_ext_userdata(ext);
  5072                  udata->len = ulen - 1;
  5073                  nla_memcpy(&udata->data, nla[NFTA_SET_ELEM_USERDATA], ulen);
  5074          }
  5075          if (obj) {
  5076                  *nft_set_ext_obj(ext) = obj;
  5077                  obj->use++;
  5078          }
  5079          if (expr) {
  5080                  memcpy(nft_set_ext_expr(ext), expr, expr->ops->size);
  5081                  kfree(expr);
                              ^^^^
Freed here

  5082          }
  5083  
  5084          trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
  5085          if (trans == NULL)
  5086                  goto err_trans;
  5087  
  5088          ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
  5089          err = set->ops->insert(ctx->net, set, &elem, &ext2);
  5090          if (err) {
  5091                  if (err == -EEXIST) {
  5092                          if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) ^
  5093                              nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) ||
  5094                              nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) ^
  5095                              nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF)) {
  5096                                  err = -EBUSY;
  5097                                  goto err_element_clash;
  5098                          }
  5099                          if ((nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
  5100                               nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) &&
  5101                               memcmp(nft_set_ext_data(ext),
  5102                                      nft_set_ext_data(ext2), set->dlen) != 0) ||
  5103                              (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
  5104                               nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF) &&
  5105                               *nft_set_ext_obj(ext) != *nft_set_ext_obj(ext2)))
  5106                                  err = -EBUSY;
  5107                          else if (!(nlmsg_flags & NLM_F_EXCL))
  5108                                  err = 0;
  5109                  }
  5110                  goto err_element_clash;
  5111          }
  5112  
  5113          if (set->size &&
  5114              !atomic_add_unless(&set->nelems, 1, set->size + set->ndeact)) {
  5115                  err = -ENFILE;
  5116                  goto err_set_full;
  5117          }
  5118  
  5119          nft_trans_elem(trans) = elem;
  5120          list_add_tail(&trans->list, &ctx->net->nft.commit_list);
  5121          return 0;
  5122  
  5123  err_set_full:
  5124          set->ops->remove(ctx->net, set, &elem);
  5125  err_element_clash:
  5126          kfree(trans);
  5127  err_trans:
  5128          if (obj)
  5129                  obj->use--;
  5130          kfree(elem.priv);
  5131  err_parse_data:
  5132          if (nla[NFTA_SET_ELEM_DATA] != NULL)
  5133                  nft_data_release(&data, desc.type);
  5134  err_parse_key_end:
  5135          nft_data_release(&elem.key_end.val, NFT_DATA_VALUE);
  5136  err_parse_key:
  5137          nft_data_release(&elem.key.val, NFT_DATA_VALUE);
  5138  err_set_elem_expr:
  5139          if (expr != NULL)
  5140                  nft_expr_destroy(ctx, expr);
                                              ^^^^

Freed again

  5141  
  5142          return err;
  5143  }

regards,
dan carpenter



[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux