1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
4   *
5   * This software has been sponsored by Sophos Astaro <http://www.sophos.com>
6   */
7  
8  #include <linux/kernel.h>
9  #include <linux/init.h>
10  #include <linux/module.h>
11  #include <linux/netlink.h>
12  #include <linux/netfilter.h>
13  #include <linux/netfilter/nfnetlink.h>
14  #include <linux/netfilter/nf_tables.h>
15  #include <linux/netfilter/nf_tables_compat.h>
16  #include <linux/netfilter/x_tables.h>
17  #include <linux/netfilter_ipv4/ip_tables.h>
18  #include <linux/netfilter_ipv6/ip6_tables.h>
19  #include <linux/netfilter_bridge/ebtables.h>
20  #include <linux/netfilter_arp/arp_tables.h>
21  #include <net/netfilter/nf_tables.h>
22  #include <net/netfilter/nf_log.h>
23  
24  /* Used for matches where *info is larger than X byte */
25  #define NFT_MATCH_LARGE_THRESH	192
26  
27  struct nft_xt_match_priv {
28  	void *info;
29  };
30  
nft_compat_chain_validate_dependency(const struct nft_ctx * ctx,const char * tablename)31  static int nft_compat_chain_validate_dependency(const struct nft_ctx *ctx,
32  						const char *tablename)
33  {
34  	enum nft_chain_types type = NFT_CHAIN_T_DEFAULT;
35  	const struct nft_chain *chain = ctx->chain;
36  	const struct nft_base_chain *basechain;
37  
38  	if (!tablename ||
39  	    !nft_is_base_chain(chain))
40  		return 0;
41  
42  	basechain = nft_base_chain(chain);
43  	if (strcmp(tablename, "nat") == 0) {
44  		if (ctx->family != NFPROTO_BRIDGE)
45  			type = NFT_CHAIN_T_NAT;
46  		if (basechain->type->type != type)
47  			return -EINVAL;
48  	}
49  
50  	return 0;
51  }
52  
53  union nft_entry {
54  	struct ipt_entry e4;
55  	struct ip6t_entry e6;
56  	struct ebt_entry ebt;
57  	struct arpt_entry arp;
58  };
59  
60  static inline void
nft_compat_set_par(struct xt_action_param * par,const struct nft_pktinfo * pkt,const void * xt,const void * xt_info)61  nft_compat_set_par(struct xt_action_param *par,
62  		   const struct nft_pktinfo *pkt,
63  		   const void *xt, const void *xt_info)
64  {
65  	par->state	= pkt->state;
66  	par->thoff	= nft_thoff(pkt);
67  	par->fragoff	= pkt->fragoff;
68  	par->target	= xt;
69  	par->targinfo	= xt_info;
70  	par->hotdrop	= false;
71  }
72  
nft_target_eval_xt(const struct nft_expr * expr,struct nft_regs * regs,const struct nft_pktinfo * pkt)73  static void nft_target_eval_xt(const struct nft_expr *expr,
74  			       struct nft_regs *regs,
75  			       const struct nft_pktinfo *pkt)
76  {
77  	void *info = nft_expr_priv(expr);
78  	struct xt_target *target = expr->ops->data;
79  	struct sk_buff *skb = pkt->skb;
80  	struct xt_action_param xt;
81  	int ret;
82  
83  	nft_compat_set_par(&xt, pkt, target, info);
84  
85  	ret = target->target(skb, &xt);
86  
87  	if (xt.hotdrop)
88  		ret = NF_DROP;
89  
90  	switch (ret) {
91  	case XT_CONTINUE:
92  		regs->verdict.code = NFT_CONTINUE;
93  		break;
94  	default:
95  		regs->verdict.code = ret;
96  		break;
97  	}
98  }
99  
nft_target_eval_bridge(const struct nft_expr * expr,struct nft_regs * regs,const struct nft_pktinfo * pkt)100  static void nft_target_eval_bridge(const struct nft_expr *expr,
101  				   struct nft_regs *regs,
102  				   const struct nft_pktinfo *pkt)
103  {
104  	void *info = nft_expr_priv(expr);
105  	struct xt_target *target = expr->ops->data;
106  	struct sk_buff *skb = pkt->skb;
107  	struct xt_action_param xt;
108  	int ret;
109  
110  	nft_compat_set_par(&xt, pkt, target, info);
111  
112  	ret = target->target(skb, &xt);
113  
114  	if (xt.hotdrop)
115  		ret = NF_DROP;
116  
117  	switch (ret) {
118  	case EBT_ACCEPT:
119  		regs->verdict.code = NF_ACCEPT;
120  		break;
121  	case EBT_DROP:
122  		regs->verdict.code = NF_DROP;
123  		break;
124  	case EBT_CONTINUE:
125  		regs->verdict.code = NFT_CONTINUE;
126  		break;
127  	case EBT_RETURN:
128  		regs->verdict.code = NFT_RETURN;
129  		break;
130  	default:
131  		regs->verdict.code = ret;
132  		break;
133  	}
134  }
135  
136  static const struct nla_policy nft_target_policy[NFTA_TARGET_MAX + 1] = {
137  	[NFTA_TARGET_NAME]	= { .type = NLA_NUL_STRING },
138  	[NFTA_TARGET_REV]	= NLA_POLICY_MAX(NLA_BE32, 255),
139  	[NFTA_TARGET_INFO]	= { .type = NLA_BINARY },
140  };
141  
142  static void
nft_target_set_tgchk_param(struct xt_tgchk_param * par,const struct nft_ctx * ctx,struct xt_target * target,void * info,union nft_entry * entry,u16 proto,bool inv)143  nft_target_set_tgchk_param(struct xt_tgchk_param *par,
144  			   const struct nft_ctx *ctx,
145  			   struct xt_target *target, void *info,
146  			   union nft_entry *entry, u16 proto, bool inv)
147  {
148  	par->net	= ctx->net;
149  	par->table	= ctx->table->name;
150  	switch (ctx->family) {
151  	case AF_INET:
152  		entry->e4.ip.proto = proto;
153  		entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0;
154  		break;
155  	case AF_INET6:
156  		if (proto)
157  			entry->e6.ipv6.flags |= IP6T_F_PROTO;
158  
159  		entry->e6.ipv6.proto = proto;
160  		entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
161  		break;
162  	case NFPROTO_BRIDGE:
163  		entry->ebt.ethproto = (__force __be16)proto;
164  		entry->ebt.invflags = inv ? EBT_IPROTO : 0;
165  		break;
166  	case NFPROTO_ARP:
167  		break;
168  	}
169  	par->entryinfo	= entry;
170  	par->target	= target;
171  	par->targinfo	= info;
172  	if (nft_is_base_chain(ctx->chain)) {
173  		const struct nft_base_chain *basechain =
174  						nft_base_chain(ctx->chain);
175  		const struct nf_hook_ops *ops = &basechain->ops;
176  
177  		par->hook_mask = 1 << ops->hooknum;
178  	} else {
179  		par->hook_mask = 0;
180  	}
181  	par->family	= ctx->family;
182  	par->nft_compat = true;
183  }
184  
target_compat_from_user(struct xt_target * t,void * in,void * out)185  static void target_compat_from_user(struct xt_target *t, void *in, void *out)
186  {
187  	int pad;
188  
189  	memcpy(out, in, t->targetsize);
190  	pad = XT_ALIGN(t->targetsize) - t->targetsize;
191  	if (pad > 0)
192  		memset(out + t->targetsize, 0, pad);
193  }
194  
195  static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1] = {
196  	[NFTA_RULE_COMPAT_PROTO]	= { .type = NLA_U32 },
197  	[NFTA_RULE_COMPAT_FLAGS]	= { .type = NLA_U32 },
198  };
199  
nft_parse_compat(const struct nlattr * attr,u16 * proto,bool * inv)200  static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv)
201  {
202  	struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1];
203  	u32 l4proto;
204  	u32 flags;
205  	int err;
206  
207  	err = nla_parse_nested_deprecated(tb, NFTA_RULE_COMPAT_MAX, attr,
208  					  nft_rule_compat_policy, NULL);
209  	if (err < 0)
210  		return err;
211  
212  	if (!tb[NFTA_RULE_COMPAT_PROTO] || !tb[NFTA_RULE_COMPAT_FLAGS])
213  		return -EINVAL;
214  
215  	flags = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_FLAGS]));
216  	if (flags & NFT_RULE_COMPAT_F_UNUSED ||
217  	    flags & ~NFT_RULE_COMPAT_F_MASK)
218  		return -EINVAL;
219  	if (flags & NFT_RULE_COMPAT_F_INV)
220  		*inv = true;
221  
222  	l4proto = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_PROTO]));
223  	if (l4proto > U16_MAX)
224  		return -EINVAL;
225  
226  	*proto = l4proto;
227  
228  	return 0;
229  }
230  
nft_compat_wait_for_destructors(void)231  static void nft_compat_wait_for_destructors(void)
232  {
233  	/* xtables matches or targets can have side effects, e.g.
234  	 * creation/destruction of /proc files.
235  	 * The xt ->destroy functions are run asynchronously from
236  	 * work queue.  If we have pending invocations we thus
237  	 * need to wait for those to finish.
238  	 */
239  	nf_tables_trans_destroy_flush_work();
240  }
241  
242  static int
nft_target_init(const struct nft_ctx * ctx,const struct nft_expr * expr,const struct nlattr * const tb[])243  nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
244  		const struct nlattr * const tb[])
245  {
246  	void *info = nft_expr_priv(expr);
247  	struct xt_target *target = expr->ops->data;
248  	struct xt_tgchk_param par;
249  	size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO]));
250  	u16 proto = 0;
251  	bool inv = false;
252  	union nft_entry e = {};
253  	int ret;
254  
255  	target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info);
256  
257  	if (ctx->nla[NFTA_RULE_COMPAT]) {
258  		ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv);
259  		if (ret < 0)
260  			return ret;
261  	}
262  
263  	nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv);
264  
265  	nft_compat_wait_for_destructors();
266  
267  	ret = xt_check_target(&par, size, proto, inv);
268  	if (ret < 0) {
269  		if (ret == -ENOENT) {
270  			const char *modname = NULL;
271  
272  			if (strcmp(target->name, "LOG") == 0)
273  				modname = "nf_log_syslog";
274  			else if (strcmp(target->name, "NFLOG") == 0)
275  				modname = "nfnetlink_log";
276  
277  			if (modname &&
278  			    nft_request_module(ctx->net, "%s", modname) == -EAGAIN)
279  				return -EAGAIN;
280  		}
281  
282  		return ret;
283  	}
284  
285  	/* The standard target cannot be used */
286  	if (!target->target)
287  		return -EINVAL;
288  
289  	return 0;
290  }
291  
__nft_mt_tg_destroy(struct module * me,const struct nft_expr * expr)292  static void __nft_mt_tg_destroy(struct module *me, const struct nft_expr *expr)
293  {
294  	module_put(me);
295  	kfree(expr->ops);
296  }
297  
298  static void
nft_target_destroy(const struct nft_ctx * ctx,const struct nft_expr * expr)299  nft_target_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
300  {
301  	struct xt_target *target = expr->ops->data;
302  	void *info = nft_expr_priv(expr);
303  	struct module *me = target->me;
304  	struct xt_tgdtor_param par;
305  
306  	par.net = ctx->net;
307  	par.target = target;
308  	par.targinfo = info;
309  	par.family = ctx->family;
310  	if (par.target->destroy != NULL)
311  		par.target->destroy(&par);
312  
313  	__nft_mt_tg_destroy(me, expr);
314  }
315  
nft_extension_dump_info(struct sk_buff * skb,int attr,const void * info,unsigned int size,unsigned int user_size)316  static int nft_extension_dump_info(struct sk_buff *skb, int attr,
317  				   const void *info,
318  				   unsigned int size, unsigned int user_size)
319  {
320  	unsigned int info_size, aligned_size = XT_ALIGN(size);
321  	struct nlattr *nla;
322  
323  	nla = nla_reserve(skb, attr, aligned_size);
324  	if (!nla)
325  		return -1;
326  
327  	info_size = user_size ? : size;
328  	memcpy(nla_data(nla), info, info_size);
329  	memset(nla_data(nla) + info_size, 0, aligned_size - info_size);
330  
331  	return 0;
332  }
333  
nft_target_dump(struct sk_buff * skb,const struct nft_expr * expr,bool reset)334  static int nft_target_dump(struct sk_buff *skb,
335  			   const struct nft_expr *expr, bool reset)
336  {
337  	const struct xt_target *target = expr->ops->data;
338  	void *info = nft_expr_priv(expr);
339  
340  	if (nla_put_string(skb, NFTA_TARGET_NAME, target->name) ||
341  	    nla_put_be32(skb, NFTA_TARGET_REV, htonl(target->revision)) ||
342  	    nft_extension_dump_info(skb, NFTA_TARGET_INFO, info,
343  				    target->targetsize, target->usersize))
344  		goto nla_put_failure;
345  
346  	return 0;
347  
348  nla_put_failure:
349  	return -1;
350  }
351  
nft_target_validate(const struct nft_ctx * ctx,const struct nft_expr * expr)352  static int nft_target_validate(const struct nft_ctx *ctx,
353  			       const struct nft_expr *expr)
354  {
355  	struct xt_target *target = expr->ops->data;
356  	unsigned int hook_mask = 0;
357  	int ret;
358  
359  	if (ctx->family != NFPROTO_IPV4 &&
360  	    ctx->family != NFPROTO_IPV6 &&
361  	    ctx->family != NFPROTO_INET &&
362  	    ctx->family != NFPROTO_BRIDGE &&
363  	    ctx->family != NFPROTO_ARP)
364  		return -EOPNOTSUPP;
365  
366  	ret = nft_chain_validate_hooks(ctx->chain,
367  				       (1 << NF_INET_PRE_ROUTING) |
368  				       (1 << NF_INET_LOCAL_IN) |
369  				       (1 << NF_INET_FORWARD) |
370  				       (1 << NF_INET_LOCAL_OUT) |
371  				       (1 << NF_INET_POST_ROUTING));
372  	if (ret)
373  		return ret;
374  
375  	if (nft_is_base_chain(ctx->chain)) {
376  		const struct nft_base_chain *basechain =
377  						nft_base_chain(ctx->chain);
378  		const struct nf_hook_ops *ops = &basechain->ops;
379  
380  		hook_mask = 1 << ops->hooknum;
381  		if (target->hooks && !(hook_mask & target->hooks))
382  			return -EINVAL;
383  
384  		ret = nft_compat_chain_validate_dependency(ctx, target->table);
385  		if (ret < 0)
386  			return ret;
387  	}
388  	return 0;
389  }
390  
__nft_match_eval(const struct nft_expr * expr,struct nft_regs * regs,const struct nft_pktinfo * pkt,void * info)391  static void __nft_match_eval(const struct nft_expr *expr,
392  			     struct nft_regs *regs,
393  			     const struct nft_pktinfo *pkt,
394  			     void *info)
395  {
396  	struct xt_match *match = expr->ops->data;
397  	struct sk_buff *skb = pkt->skb;
398  	struct xt_action_param xt;
399  	bool ret;
400  
401  	nft_compat_set_par(&xt, pkt, match, info);
402  
403  	ret = match->match(skb, &xt);
404  
405  	if (xt.hotdrop) {
406  		regs->verdict.code = NF_DROP;
407  		return;
408  	}
409  
410  	switch (ret ? 1 : 0) {
411  	case 1:
412  		regs->verdict.code = NFT_CONTINUE;
413  		break;
414  	case 0:
415  		regs->verdict.code = NFT_BREAK;
416  		break;
417  	}
418  }
419  
nft_match_large_eval(const struct nft_expr * expr,struct nft_regs * regs,const struct nft_pktinfo * pkt)420  static void nft_match_large_eval(const struct nft_expr *expr,
421  				 struct nft_regs *regs,
422  				 const struct nft_pktinfo *pkt)
423  {
424  	struct nft_xt_match_priv *priv = nft_expr_priv(expr);
425  
426  	__nft_match_eval(expr, regs, pkt, priv->info);
427  }
428  
nft_match_eval(const struct nft_expr * expr,struct nft_regs * regs,const struct nft_pktinfo * pkt)429  static void nft_match_eval(const struct nft_expr *expr,
430  			   struct nft_regs *regs,
431  			   const struct nft_pktinfo *pkt)
432  {
433  	__nft_match_eval(expr, regs, pkt, nft_expr_priv(expr));
434  }
435  
436  static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX + 1] = {
437  	[NFTA_MATCH_NAME]	= { .type = NLA_NUL_STRING },
438  	[NFTA_MATCH_REV]	= NLA_POLICY_MAX(NLA_BE32, 255),
439  	[NFTA_MATCH_INFO]	= { .type = NLA_BINARY },
440  };
441  
442  /* struct xt_mtchk_param and xt_tgchk_param look very similar */
443  static void
nft_match_set_mtchk_param(struct xt_mtchk_param * par,const struct nft_ctx * ctx,struct xt_match * match,void * info,union nft_entry * entry,u16 proto,bool inv)444  nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
445  			  struct xt_match *match, void *info,
446  			  union nft_entry *entry, u16 proto, bool inv)
447  {
448  	par->net	= ctx->net;
449  	par->table	= ctx->table->name;
450  	switch (ctx->family) {
451  	case AF_INET:
452  		entry->e4.ip.proto = proto;
453  		entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0;
454  		break;
455  	case AF_INET6:
456  		if (proto)
457  			entry->e6.ipv6.flags |= IP6T_F_PROTO;
458  
459  		entry->e6.ipv6.proto = proto;
460  		entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
461  		break;
462  	case NFPROTO_BRIDGE:
463  		entry->ebt.ethproto = (__force __be16)proto;
464  		entry->ebt.invflags = inv ? EBT_IPROTO : 0;
465  		break;
466  	case NFPROTO_ARP:
467  		break;
468  	}
469  	par->entryinfo	= entry;
470  	par->match	= match;
471  	par->matchinfo	= info;
472  	if (nft_is_base_chain(ctx->chain)) {
473  		const struct nft_base_chain *basechain =
474  						nft_base_chain(ctx->chain);
475  		const struct nf_hook_ops *ops = &basechain->ops;
476  
477  		par->hook_mask = 1 << ops->hooknum;
478  	} else {
479  		par->hook_mask = 0;
480  	}
481  	par->family	= ctx->family;
482  	par->nft_compat = true;
483  }
484  
match_compat_from_user(struct xt_match * m,void * in,void * out)485  static void match_compat_from_user(struct xt_match *m, void *in, void *out)
486  {
487  	int pad;
488  
489  	memcpy(out, in, m->matchsize);
490  	pad = XT_ALIGN(m->matchsize) - m->matchsize;
491  	if (pad > 0)
492  		memset(out + m->matchsize, 0, pad);
493  }
494  
495  static int
__nft_match_init(const struct nft_ctx * ctx,const struct nft_expr * expr,const struct nlattr * const tb[],void * info)496  __nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
497  		 const struct nlattr * const tb[],
498  		 void *info)
499  {
500  	struct xt_match *match = expr->ops->data;
501  	struct xt_mtchk_param par;
502  	size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO]));
503  	u16 proto = 0;
504  	bool inv = false;
505  	union nft_entry e = {};
506  	int ret;
507  
508  	match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info);
509  
510  	if (ctx->nla[NFTA_RULE_COMPAT]) {
511  		ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv);
512  		if (ret < 0)
513  			return ret;
514  	}
515  
516  	nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv);
517  
518  	nft_compat_wait_for_destructors();
519  
520  	return xt_check_match(&par, size, proto, inv);
521  }
522  
523  static int
nft_match_init(const struct nft_ctx * ctx,const struct nft_expr * expr,const struct nlattr * const tb[])524  nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
525  	       const struct nlattr * const tb[])
526  {
527  	return __nft_match_init(ctx, expr, tb, nft_expr_priv(expr));
528  }
529  
530  static int
nft_match_large_init(const struct nft_ctx * ctx,const struct nft_expr * expr,const struct nlattr * const tb[])531  nft_match_large_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
532  		     const struct nlattr * const tb[])
533  {
534  	struct nft_xt_match_priv *priv = nft_expr_priv(expr);
535  	struct xt_match *m = expr->ops->data;
536  	int ret;
537  
538  	priv->info = kmalloc(XT_ALIGN(m->matchsize), GFP_KERNEL_ACCOUNT);
539  	if (!priv->info)
540  		return -ENOMEM;
541  
542  	ret = __nft_match_init(ctx, expr, tb, priv->info);
543  	if (ret)
544  		kfree(priv->info);
545  	return ret;
546  }
547  
548  static void
__nft_match_destroy(const struct nft_ctx * ctx,const struct nft_expr * expr,void * info)549  __nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr,
550  		    void *info)
551  {
552  	struct xt_match *match = expr->ops->data;
553  	struct module *me = match->me;
554  	struct xt_mtdtor_param par;
555  
556  	par.net = ctx->net;
557  	par.match = match;
558  	par.matchinfo = info;
559  	par.family = ctx->family;
560  	if (par.match->destroy != NULL)
561  		par.match->destroy(&par);
562  
563  	__nft_mt_tg_destroy(me, expr);
564  }
565  
566  static void
nft_match_destroy(const struct nft_ctx * ctx,const struct nft_expr * expr)567  nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
568  {
569  	__nft_match_destroy(ctx, expr, nft_expr_priv(expr));
570  }
571  
572  static void
nft_match_large_destroy(const struct nft_ctx * ctx,const struct nft_expr * expr)573  nft_match_large_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
574  {
575  	struct nft_xt_match_priv *priv = nft_expr_priv(expr);
576  
577  	__nft_match_destroy(ctx, expr, priv->info);
578  	kfree(priv->info);
579  }
580  
__nft_match_dump(struct sk_buff * skb,const struct nft_expr * expr,void * info)581  static int __nft_match_dump(struct sk_buff *skb, const struct nft_expr *expr,
582  			    void *info)
583  {
584  	struct xt_match *match = expr->ops->data;
585  
586  	if (nla_put_string(skb, NFTA_MATCH_NAME, match->name) ||
587  	    nla_put_be32(skb, NFTA_MATCH_REV, htonl(match->revision)) ||
588  	    nft_extension_dump_info(skb, NFTA_MATCH_INFO, info,
589  				    match->matchsize, match->usersize))
590  		goto nla_put_failure;
591  
592  	return 0;
593  
594  nla_put_failure:
595  	return -1;
596  }
597  
nft_match_dump(struct sk_buff * skb,const struct nft_expr * expr,bool reset)598  static int nft_match_dump(struct sk_buff *skb,
599  			  const struct nft_expr *expr, bool reset)
600  {
601  	return __nft_match_dump(skb, expr, nft_expr_priv(expr));
602  }
603  
nft_match_large_dump(struct sk_buff * skb,const struct nft_expr * e,bool reset)604  static int nft_match_large_dump(struct sk_buff *skb,
605  				const struct nft_expr *e, bool reset)
606  {
607  	struct nft_xt_match_priv *priv = nft_expr_priv(e);
608  
609  	return __nft_match_dump(skb, e, priv->info);
610  }
611  
nft_match_validate(const struct nft_ctx * ctx,const struct nft_expr * expr)612  static int nft_match_validate(const struct nft_ctx *ctx,
613  			      const struct nft_expr *expr)
614  {
615  	struct xt_match *match = expr->ops->data;
616  	unsigned int hook_mask = 0;
617  	int ret;
618  
619  	if (ctx->family != NFPROTO_IPV4 &&
620  	    ctx->family != NFPROTO_IPV6 &&
621  	    ctx->family != NFPROTO_INET &&
622  	    ctx->family != NFPROTO_BRIDGE &&
623  	    ctx->family != NFPROTO_ARP)
624  		return -EOPNOTSUPP;
625  
626  	ret = nft_chain_validate_hooks(ctx->chain,
627  				       (1 << NF_INET_PRE_ROUTING) |
628  				       (1 << NF_INET_LOCAL_IN) |
629  				       (1 << NF_INET_FORWARD) |
630  				       (1 << NF_INET_LOCAL_OUT) |
631  				       (1 << NF_INET_POST_ROUTING));
632  	if (ret)
633  		return ret;
634  
635  	if (nft_is_base_chain(ctx->chain)) {
636  		const struct nft_base_chain *basechain =
637  						nft_base_chain(ctx->chain);
638  		const struct nf_hook_ops *ops = &basechain->ops;
639  
640  		hook_mask = 1 << ops->hooknum;
641  		if (match->hooks && !(hook_mask & match->hooks))
642  			return -EINVAL;
643  
644  		ret = nft_compat_chain_validate_dependency(ctx, match->table);
645  		if (ret < 0)
646  			return ret;
647  	}
648  	return 0;
649  }
650  
651  static int
nfnl_compat_fill_info(struct sk_buff * skb,u32 portid,u32 seq,u32 type,int event,u16 family,const char * name,int rev,int target)652  nfnl_compat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
653  		      int event, u16 family, const char *name,
654  		      int rev, int target)
655  {
656  	struct nlmsghdr *nlh;
657  	unsigned int flags = portid ? NLM_F_MULTI : 0;
658  
659  	event = nfnl_msg_type(NFNL_SUBSYS_NFT_COMPAT, event);
660  	nlh = nfnl_msg_put(skb, portid, seq, event, flags, family,
661  			   NFNETLINK_V0, 0);
662  	if (!nlh)
663  		goto nlmsg_failure;
664  
665  	if (nla_put_string(skb, NFTA_COMPAT_NAME, name) ||
666  	    nla_put_be32(skb, NFTA_COMPAT_REV, htonl(rev)) ||
667  	    nla_put_be32(skb, NFTA_COMPAT_TYPE, htonl(target)))
668  		goto nla_put_failure;
669  
670  	nlmsg_end(skb, nlh);
671  	return skb->len;
672  
673  nlmsg_failure:
674  nla_put_failure:
675  	nlmsg_cancel(skb, nlh);
676  	return -1;
677  }
678  
nfnl_compat_get_rcu(struct sk_buff * skb,const struct nfnl_info * info,const struct nlattr * const tb[])679  static int nfnl_compat_get_rcu(struct sk_buff *skb,
680  			       const struct nfnl_info *info,
681  			       const struct nlattr * const tb[])
682  {
683  	u8 family = info->nfmsg->nfgen_family;
684  	const char *name, *fmt;
685  	struct sk_buff *skb2;
686  	int ret = 0, target;
687  	u32 rev;
688  
689  	if (tb[NFTA_COMPAT_NAME] == NULL ||
690  	    tb[NFTA_COMPAT_REV] == NULL ||
691  	    tb[NFTA_COMPAT_TYPE] == NULL)
692  		return -EINVAL;
693  
694  	name = nla_data(tb[NFTA_COMPAT_NAME]);
695  	rev = ntohl(nla_get_be32(tb[NFTA_COMPAT_REV]));
696  	target = ntohl(nla_get_be32(tb[NFTA_COMPAT_TYPE]));
697  
698  	switch(family) {
699  	case AF_INET:
700  		fmt = "ipt_%s";
701  		break;
702  	case AF_INET6:
703  		fmt = "ip6t_%s";
704  		break;
705  	case NFPROTO_BRIDGE:
706  		fmt = "ebt_%s";
707  		break;
708  	case NFPROTO_ARP:
709  		fmt = "arpt_%s";
710  		break;
711  	default:
712  		pr_err("nft_compat: unsupported protocol %d\n", family);
713  		return -EINVAL;
714  	}
715  
716  	if (!try_module_get(THIS_MODULE))
717  		return -EINVAL;
718  
719  	rcu_read_unlock();
720  	try_then_request_module(xt_find_revision(family, name, rev, target, &ret),
721  				fmt, name);
722  	if (ret < 0)
723  		goto out_put;
724  
725  	skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
726  	if (skb2 == NULL) {
727  		ret = -ENOMEM;
728  		goto out_put;
729  	}
730  
731  	/* include the best revision for this extension in the message */
732  	if (nfnl_compat_fill_info(skb2, NETLINK_CB(skb).portid,
733  				  info->nlh->nlmsg_seq,
734  				  NFNL_MSG_TYPE(info->nlh->nlmsg_type),
735  				  NFNL_MSG_COMPAT_GET,
736  				  family, name, ret, target) <= 0) {
737  		kfree_skb(skb2);
738  		goto out_put;
739  	}
740  
741  	ret = nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid);
742  out_put:
743  	rcu_read_lock();
744  	module_put(THIS_MODULE);
745  
746  	return ret;
747  }
748  
749  static const struct nla_policy nfnl_compat_policy_get[NFTA_COMPAT_MAX+1] = {
750  	[NFTA_COMPAT_NAME]	= { .type = NLA_NUL_STRING,
751  				    .len = NFT_COMPAT_NAME_MAX-1 },
752  	[NFTA_COMPAT_REV]	= NLA_POLICY_MAX(NLA_BE32, 255),
753  	[NFTA_COMPAT_TYPE]	= { .type = NLA_U32 },
754  };
755  
756  static const struct nfnl_callback nfnl_nft_compat_cb[NFNL_MSG_COMPAT_MAX] = {
757  	[NFNL_MSG_COMPAT_GET]	= {
758  		.call		= nfnl_compat_get_rcu,
759  		.type		= NFNL_CB_RCU,
760  		.attr_count	= NFTA_COMPAT_MAX,
761  		.policy		= nfnl_compat_policy_get
762  	},
763  };
764  
765  static const struct nfnetlink_subsystem nfnl_compat_subsys = {
766  	.name		= "nft-compat",
767  	.subsys_id	= NFNL_SUBSYS_NFT_COMPAT,
768  	.cb_count	= NFNL_MSG_COMPAT_MAX,
769  	.cb		= nfnl_nft_compat_cb,
770  };
771  
772  static struct nft_expr_type nft_match_type;
773  
nft_match_reduce(struct nft_regs_track * track,const struct nft_expr * expr)774  static bool nft_match_reduce(struct nft_regs_track *track,
775  			     const struct nft_expr *expr)
776  {
777  	const struct xt_match *match = expr->ops->data;
778  
779  	return strcmp(match->name, "comment") == 0;
780  }
781  
782  static const struct nft_expr_ops *
nft_match_select_ops(const struct nft_ctx * ctx,const struct nlattr * const tb[])783  nft_match_select_ops(const struct nft_ctx *ctx,
784  		     const struct nlattr * const tb[])
785  {
786  	struct nft_expr_ops *ops;
787  	struct xt_match *match;
788  	unsigned int matchsize;
789  	char *mt_name;
790  	u32 rev, family;
791  	int err;
792  
793  	if (tb[NFTA_MATCH_NAME] == NULL ||
794  	    tb[NFTA_MATCH_REV] == NULL ||
795  	    tb[NFTA_MATCH_INFO] == NULL)
796  		return ERR_PTR(-EINVAL);
797  
798  	mt_name = nla_data(tb[NFTA_MATCH_NAME]);
799  	rev = ntohl(nla_get_be32(tb[NFTA_MATCH_REV]));
800  	family = ctx->family;
801  
802  	match = xt_request_find_match(family, mt_name, rev);
803  	if (IS_ERR(match))
804  		return ERR_PTR(-ENOENT);
805  
806  	if (match->matchsize > nla_len(tb[NFTA_MATCH_INFO])) {
807  		err = -EINVAL;
808  		goto err;
809  	}
810  
811  	ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL_ACCOUNT);
812  	if (!ops) {
813  		err = -ENOMEM;
814  		goto err;
815  	}
816  
817  	ops->type = &nft_match_type;
818  	ops->eval = nft_match_eval;
819  	ops->init = nft_match_init;
820  	ops->destroy = nft_match_destroy;
821  	ops->dump = nft_match_dump;
822  	ops->validate = nft_match_validate;
823  	ops->data = match;
824  	ops->reduce = nft_match_reduce;
825  
826  	matchsize = NFT_EXPR_SIZE(XT_ALIGN(match->matchsize));
827  	if (matchsize > NFT_MATCH_LARGE_THRESH) {
828  		matchsize = NFT_EXPR_SIZE(sizeof(struct nft_xt_match_priv));
829  
830  		ops->eval = nft_match_large_eval;
831  		ops->init = nft_match_large_init;
832  		ops->destroy = nft_match_large_destroy;
833  		ops->dump = nft_match_large_dump;
834  	}
835  
836  	ops->size = matchsize;
837  
838  	return ops;
839  err:
840  	module_put(match->me);
841  	return ERR_PTR(err);
842  }
843  
nft_match_release_ops(const struct nft_expr_ops * ops)844  static void nft_match_release_ops(const struct nft_expr_ops *ops)
845  {
846  	struct xt_match *match = ops->data;
847  
848  	module_put(match->me);
849  	kfree(ops);
850  }
851  
852  static struct nft_expr_type nft_match_type __read_mostly = {
853  	.name		= "match",
854  	.select_ops	= nft_match_select_ops,
855  	.release_ops	= nft_match_release_ops,
856  	.policy		= nft_match_policy,
857  	.maxattr	= NFTA_MATCH_MAX,
858  	.owner		= THIS_MODULE,
859  };
860  
861  static struct nft_expr_type nft_target_type;
862  
863  static const struct nft_expr_ops *
nft_target_select_ops(const struct nft_ctx * ctx,const struct nlattr * const tb[])864  nft_target_select_ops(const struct nft_ctx *ctx,
865  		      const struct nlattr * const tb[])
866  {
867  	struct nft_expr_ops *ops;
868  	struct xt_target *target;
869  	char *tg_name;
870  	u32 rev, family;
871  	int err;
872  
873  	if (tb[NFTA_TARGET_NAME] == NULL ||
874  	    tb[NFTA_TARGET_REV] == NULL ||
875  	    tb[NFTA_TARGET_INFO] == NULL)
876  		return ERR_PTR(-EINVAL);
877  
878  	tg_name = nla_data(tb[NFTA_TARGET_NAME]);
879  	rev = ntohl(nla_get_be32(tb[NFTA_TARGET_REV]));
880  	family = ctx->family;
881  
882  	if (strcmp(tg_name, XT_ERROR_TARGET) == 0 ||
883  	    strcmp(tg_name, XT_STANDARD_TARGET) == 0 ||
884  	    strcmp(tg_name, "standard") == 0)
885  		return ERR_PTR(-EINVAL);
886  
887  	target = xt_request_find_target(family, tg_name, rev);
888  	if (IS_ERR(target))
889  		return ERR_PTR(-ENOENT);
890  
891  	if (!target->target) {
892  		err = -EINVAL;
893  		goto err;
894  	}
895  
896  	if (target->targetsize > nla_len(tb[NFTA_TARGET_INFO])) {
897  		err = -EINVAL;
898  		goto err;
899  	}
900  
901  	ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL_ACCOUNT);
902  	if (!ops) {
903  		err = -ENOMEM;
904  		goto err;
905  	}
906  
907  	ops->type = &nft_target_type;
908  	ops->size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize));
909  	ops->init = nft_target_init;
910  	ops->destroy = nft_target_destroy;
911  	ops->dump = nft_target_dump;
912  	ops->validate = nft_target_validate;
913  	ops->data = target;
914  	ops->reduce = NFT_REDUCE_READONLY;
915  
916  	if (family == NFPROTO_BRIDGE)
917  		ops->eval = nft_target_eval_bridge;
918  	else
919  		ops->eval = nft_target_eval_xt;
920  
921  	return ops;
922  err:
923  	module_put(target->me);
924  	return ERR_PTR(err);
925  }
926  
nft_target_release_ops(const struct nft_expr_ops * ops)927  static void nft_target_release_ops(const struct nft_expr_ops *ops)
928  {
929  	struct xt_target *target = ops->data;
930  
931  	module_put(target->me);
932  	kfree(ops);
933  }
934  
935  static struct nft_expr_type nft_target_type __read_mostly = {
936  	.name		= "target",
937  	.select_ops	= nft_target_select_ops,
938  	.release_ops	= nft_target_release_ops,
939  	.policy		= nft_target_policy,
940  	.maxattr	= NFTA_TARGET_MAX,
941  	.owner		= THIS_MODULE,
942  };
943  
nft_compat_module_init(void)944  static int __init nft_compat_module_init(void)
945  {
946  	int ret;
947  
948  	ret = nft_register_expr(&nft_match_type);
949  	if (ret < 0)
950  		return ret;
951  
952  	ret = nft_register_expr(&nft_target_type);
953  	if (ret < 0)
954  		goto err_match;
955  
956  	ret = nfnetlink_subsys_register(&nfnl_compat_subsys);
957  	if (ret < 0) {
958  		pr_err("nft_compat: cannot register with nfnetlink.\n");
959  		goto err_target;
960  	}
961  
962  	return ret;
963  err_target:
964  	nft_unregister_expr(&nft_target_type);
965  err_match:
966  	nft_unregister_expr(&nft_match_type);
967  	return ret;
968  }
969  
nft_compat_module_exit(void)970  static void __exit nft_compat_module_exit(void)
971  {
972  	nfnetlink_subsys_unregister(&nfnl_compat_subsys);
973  	nft_unregister_expr(&nft_target_type);
974  	nft_unregister_expr(&nft_match_type);
975  }
976  
977  MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFT_COMPAT);
978  
979  module_init(nft_compat_module_init);
980  module_exit(nft_compat_module_exit);
981  
982  MODULE_LICENSE("GPL");
983  MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
984  MODULE_ALIAS_NFT_EXPR("match");
985  MODULE_ALIAS_NFT_EXPR("target");
986  MODULE_DESCRIPTION("x_tables over nftables support");
987