I have a question: we will try_module_get in __netlink_dump_start(), but why we need to call try_module_get again in nft_netlink_dump_start ??
2018-07-23 17:52 GMT+08:00 shaochun chen <cscn...@gmail.com>: > allocate memory in ->start(), it's not convenient for users. > if call ->done() isn't ok for clean memory when netlink_dump_start() fail, > maybe we should have another function ->clean() to clean memory. > > 2018-07-23 17:28 GMT+08:00 Florian Westphal <f...@strlen.de>: > >> Pablo Neira Ayuso <pa...@netfilter.org> wrote: >> > > diff --git a/net/netfilter/nf_tables_api.c >> b/net/netfilter/nf_tables_api.c >> > > --- a/net/netfilter/nf_tables_api.c >> > > +++ b/net/netfilter/nf_tables_api.c >> > > @@ -5010,6 +5013,22 @@ nft_obj_filter_alloc(const struct nlattr * >> const nla[]) >> > > return filter; >> > > } >> > > >> > > +static int nf_tables_dump_obj_start(struct netlink_callback *cb) >> > > +{ >> > > + const struct nlattr * const *nla = cb->data; >> >> On-Stack input. >> I can't see how its wrong, ->start() happens from same context as >> netlink_dump_start so its valid. >> >> > > + struct nft_obj_filter *filter = NULL; >> > > + >> > > + if (nla[NFTA_OBJ_TABLE] || >> > > + nla[NFTA_OBJ_TYPE]) { >> > > + filter = nft_obj_filter_alloc(nla); >> > > + if (IS_ERR(filter)) >> > > + return -ENOMEM; >> > > + } >> > > + >> > > + cb->data = filter; >> >> And this replaced the on-stack input with dynamically >> allocated one, which will be free'd via ->done(). >> >> > > /* called with rcu_read_lock held */ >> > > static int nf_tables_getobj(struct net *net, struct sock *nlsk, >> > > struct sk_buff *skb, const struct nlmsghdr >> *nlh, >> > > @@ -5028,21 +5047,13 @@ static int nf_tables_getobj(struct net *net, >> struct sock *nlsk, >> > > >> > > if (nlh->nlmsg_flags & NLM_F_DUMP) { >> > > struct netlink_dump_control c = { >> > > + .start = nf_tables_dump_obj_start, >> > > .dump = nf_tables_dump_obj, >> > > .done = nf_tables_dump_obj_done, >> > > .module = THIS_MODULE, >> > > + .data = (void *)nla, >> > >> > You cannot do this. >> > >> > nla is allocated in this stack. >> >> Yes. >> >> > the nla will not be available in the second recv(), it won't be there. >> >> Its replaced in ->start(). >> >> As David pointed out, once ->start() returns 0 we set cb_running, i.e. >> only after successful ->start() netlink core will call ->dump() again. >> >> So I see no problem setting ->data to onstack cookie and then >> duplicating it to heap via kmemdup in ->start(). >> >> As far as I can see netlink core offers all functionality already, >> so we only need to switch netfilter to make use of it. >> >> If you disagree please let me know, otherwise I will cook up >> a patch along this pattern for net/netfilter/*. >> >> Thanks. >> > >