From: Stefano Brivio <sbrivio@redhat.com>
To: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org
Subject: Re: [PATCH,nf-next RFC 1/2] netfilter: nf_tables: add nft_setelem_parse_key()
Date: Sat, 7 Dec 2019 23:51:38 +0100 [thread overview]
Message-ID: <20191207235138.393d306c@elisabeth> (raw)
In-Reply-To: <20191206194517.gg6e34uekje647sn@salvia>
On Fri, 6 Dec 2019 20:45:17 +0100
Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Thu, Dec 05, 2019 at 11:43:50PM +0100, Stefano Brivio wrote:
> > Hi Pablo,
> >
> > Just two nits:
> >
> > On Mon, 2 Dec 2019 14:14:06 +0100
> > Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> >
> > > Add helper function to parse the set element key netlink attribute.
> > >
> > > Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> > > ---
> > > net/netfilter/nf_tables_api.c | 56 ++++++++++++++++++++++++-------------------
> > > 1 file changed, 32 insertions(+), 24 deletions(-)
> > >
> > > diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> > > index 0db2784fee9a..13e291fac26f 100644
> > > --- a/net/netfilter/nf_tables_api.c
> > > +++ b/net/netfilter/nf_tables_api.c
> > > @@ -4490,11 +4490,31 @@ static int nft_setelem_parse_flags(const struct nft_set *set,
> > > return 0;
> > > }
> > >
> > > +static int nft_setelem_parse_key(struct nft_ctx *ctx, struct nft_set *set,
> > > + struct nft_data *key, struct nlattr *attr)
> > > +{
> > > + struct nft_data_desc desc;
> > > + int err;
> > > +
> > > + err = nft_data_init(ctx, key, sizeof(*key), &desc, attr);
> > > + if (err < 0)
> > > + goto err1;
> > > +
> > > + err = -EINVAL;
> > > + if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
> > > + goto err2;
> > > +
> > > + return 0;
> > > +err2:
> > > + nft_data_release(key, desc.type);
> > > +err1:
> > > + return err;
> > > +}
> > > +
> > > static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set,
> > > const struct nlattr *attr)
> > > {
> > > struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
> > > - struct nft_data_desc desc;
> > > struct nft_set_elem elem;
> > > struct sk_buff *skb;
> > > uint32_t flags = 0;
> > > @@ -4513,15 +4533,11 @@ static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set,
> > > if (err < 0)
> > > return err;
> > >
> > > - err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
> > > - nla[NFTA_SET_ELEM_KEY]);
> > > + err = nft_setelem_parse_key(ctx, set, &elem.key.val,
> > > + nla[NFTA_SET_ELEM_KEY]);
> > > if (err < 0)
> > > return err;
> > >
> > > - err = -EINVAL;
> > > - if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
> > > - return err;
> > > -
> > > priv = set->ops->get(ctx->net, set, &elem, flags);
> > > if (IS_ERR(priv))
> > > return PTR_ERR(priv);
> > > @@ -4720,13 +4736,13 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
> > > {
> > > struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
> > > u8 genmask = nft_genmask_next(ctx->net);
> > > - struct nft_data_desc d1, d2;
> > > struct nft_set_ext_tmpl tmpl;
> > > struct nft_set_ext *ext, *ext2;
> > > struct nft_set_elem elem;
> > > struct nft_set_binding *binding;
> > > struct nft_object *obj = NULL;
> > > struct nft_userdata *udata;
> > > + struct nft_data_desc d2;
> >
> > At this point, this could simply be desc, or data_desc.
> >
> > > struct nft_data data;
> > > enum nft_registers dreg;
> > > struct nft_trans *trans;
> > > @@ -4792,15 +4808,12 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
> > > return err;
> > > }
> > >
> > > - err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1,
> > > - nla[NFTA_SET_ELEM_KEY]);
> > > + err = nft_setelem_parse_key(ctx, set, &elem.key.val,
> > > + nla[NFTA_SET_ELEM_KEY]);
> > > if (err < 0)
> > > goto err1;
> > > - err = -EINVAL;
> > > - if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
> > > - goto err2;
> > >
> > > - nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, d1.len);
> > > + nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen);
> > > if (timeout > 0) {
> > > nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
> > > if (timeout != set->timeout)
> > > @@ -4942,7 +4955,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
> > > if (nla[NFTA_SET_ELEM_DATA] != NULL)
> > > nft_data_release(&data, d2.type);
> > > err2:
> > > - nft_data_release(&elem.key.val, d1.type);
> > > + nft_data_release(&elem.key.val, NFT_DATA_VALUE);
> > > err1:
> > > return err;
> > > }
> > > @@ -5038,7 +5051,6 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
> > > {
> > > struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
> > > struct nft_set_ext_tmpl tmpl;
> > > - struct nft_data_desc desc;
> > > struct nft_set_elem elem;
> > > struct nft_set_ext *ext;
> > > struct nft_trans *trans;
> > > @@ -5063,16 +5075,12 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
> > > if (flags != 0)
> > > nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
> > >
> > > - err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
> > > - nla[NFTA_SET_ELEM_KEY]);
> > > + err = nft_setelem_parse_key(ctx, set, &elem.key.val,
> > > + nla[NFTA_SET_ELEM_KEY]);
> > > if (err < 0)
> > > goto err1;
> > >
> > > - err = -EINVAL;
> > > - if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
> > > - goto err2;
> > > -
> > > - nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, desc.len);
> > > + nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen);
> > >
> > > err = -ENOMEM;
> > > elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0,
> > > @@ -5109,7 +5117,7 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
> > > err3:
> > > kfree(elem.priv);
> > > err2:
> > > - nft_data_release(&elem.key.val, desc.type);
> > > + nft_data_release(&elem.key.val, NFT_DATA_VALUE);
> >
> > I'm not sure if this can actually happen, but in
> > nft_setelem_parse_key() you are checking that the type is
> > NFT_DATA_VALUE, and returning error if it's not.
>
> Exactly.
>
> > If the type is not NFT_DATA_VALUE, I guess we shouldn't pass
> > NFT_DATA_VALUE to nft_data_release() here.
>
> The new nft_setelem_parse_key() function makes sure that the key is
> NFT_DATA_VALUE, otherwise bails out and calls nft_data_release() with
> desc.type.
>
> Then, moving forward in nft_add_set_elem() after the
> nft_setelem_parse_key(), if an error occurs, nft_data_release() can be
> called with NFT_DATA_VALUE, because that was already validated by
> nft_setelem_parse_key().
>
> > Maybe nft_setelem_parse_key() could clean up after itself on error.
>
> It's doing so already, right? See err2: label.
Right you are, my bad, I mixed up err2: and err1: in nft_set_delelem()
and then forgot about err2: in nft_setelem_parse_key().
Well, on the other hand, 'return err;" and 'goto fail_elem;" would have
been easier to follow, but maybe it's just my taste. :)
--
Stefano
next prev parent reply other threads:[~2019-12-07 22:51 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-12-02 13:14 [PATCH,nf-next RFC 0/2] add NFTA_SET_ELEM_KEY_END Pablo Neira Ayuso
2019-12-02 13:14 ` [PATCH,nf-next RFC 1/2] netfilter: nf_tables: add nft_setelem_parse_key() Pablo Neira Ayuso
2019-12-05 22:43 ` Stefano Brivio
2019-12-06 19:45 ` Pablo Neira Ayuso
2019-12-07 22:51 ` Stefano Brivio [this message]
2019-12-09 20:44 ` Pablo Neira Ayuso
2019-12-02 13:14 ` [PATCH,nf-next RFC 2/2] netfilter: nf_tables: add NFTA_SET_ELEM_KEY_END attribute Pablo Neira Ayuso
2019-12-05 22:44 ` Stefano Brivio
2019-12-06 19:52 ` Pablo Neira Ayuso
2019-12-07 22:52 ` Stefano Brivio
2019-12-02 16:19 ` [PATCH,nf-next RFC 0/2] add NFTA_SET_ELEM_KEY_END Stefano Brivio
2019-12-03 11:02 ` Pablo Neira Ayuso
2019-12-03 15:56 ` Stefano Brivio
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=20191207235138.393d306c@elisabeth \
--to=sbrivio@redhat.com \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
/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.