aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netfilter/nf_tables.h22
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c3
-rw-r--r--net/netfilter/nf_tables_api.c61
-rw-r--r--net/netfilter/nft_compat.c14
4 files changed, 65 insertions, 35 deletions
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 9eaaa7884586..decb9a095ae7 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -119,6 +119,22 @@ int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
119 const struct nft_data *data, 119 const struct nft_data *data,
120 enum nft_data_types type); 120 enum nft_data_types type);
121 121
122
123/**
124 * struct nft_userdata - user defined data associated with an object
125 *
126 * @len: length of the data
127 * @data: content
128 *
129 * The presence of user data is indicated in an object specific fashion,
130 * so a length of zero can't occur and the value "len" indicates data
131 * of length len + 1.
132 */
133struct nft_userdata {
134 u8 len;
135 unsigned char data[0];
136};
137
122/** 138/**
123 * struct nft_set_elem - generic representation of set elements 139 * struct nft_set_elem - generic representation of set elements
124 * 140 *
@@ -380,7 +396,7 @@ static inline void *nft_expr_priv(const struct nft_expr *expr)
380 * @handle: rule handle 396 * @handle: rule handle
381 * @genmask: generation mask 397 * @genmask: generation mask
382 * @dlen: length of expression data 398 * @dlen: length of expression data
383 * @ulen: length of user data (used for comments) 399 * @udata: user data is appended to the rule
384 * @data: expression data 400 * @data: expression data
385 */ 401 */
386struct nft_rule { 402struct nft_rule {
@@ -388,7 +404,7 @@ struct nft_rule {
388 u64 handle:42, 404 u64 handle:42,
389 genmask:2, 405 genmask:2,
390 dlen:12, 406 dlen:12,
391 ulen:8; 407 udata:1;
392 unsigned char data[] 408 unsigned char data[]
393 __attribute__((aligned(__alignof__(struct nft_expr)))); 409 __attribute__((aligned(__alignof__(struct nft_expr))));
394}; 410};
@@ -476,7 +492,7 @@ static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule)
476 return (struct nft_expr *)&rule->data[rule->dlen]; 492 return (struct nft_expr *)&rule->data[rule->dlen];
477} 493}
478 494
479static inline void *nft_userdata(const struct nft_rule *rule) 495static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule)
480{ 496{
481 return (void *)&rule->data[rule->dlen]; 497 return (void *)&rule->data[rule->dlen];
482} 498}
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index c47ffd7a0a70..d93ceeb3ef04 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -896,6 +896,8 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
896 IP_VS_DBG(2, "BACKUP, add new conn. failed\n"); 896 IP_VS_DBG(2, "BACKUP, add new conn. failed\n");
897 return; 897 return;
898 } 898 }
899 if (!(flags & IP_VS_CONN_F_TEMPLATE))
900 kfree(param->pe_data);
899 } 901 }
900 902
901 if (opt) 903 if (opt)
@@ -1169,6 +1171,7 @@ static inline int ip_vs_proc_sync_conn(struct net *net, __u8 *p, __u8 *msg_end)
1169 (opt_flags & IPVS_OPT_F_SEQ_DATA ? &opt : NULL) 1171 (opt_flags & IPVS_OPT_F_SEQ_DATA ? &opt : NULL)
1170 ); 1172 );
1171#endif 1173#endif
1174 ip_vs_pe_put(param.pe);
1172 return 0; 1175 return 0;
1173 /* Error exit */ 1176 /* Error exit */
1174out: 1177out:
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 199fd0f27b0e..6ab777912237 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -227,7 +227,7 @@ nft_rule_deactivate_next(struct net *net, struct nft_rule *rule)
227 227
228static inline void nft_rule_clear(struct net *net, struct nft_rule *rule) 228static inline void nft_rule_clear(struct net *net, struct nft_rule *rule)
229{ 229{
230 rule->genmask = 0; 230 rule->genmask &= ~(1 << gencursor_next(net));
231} 231}
232 232
233static int 233static int
@@ -1711,9 +1711,12 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
1711 } 1711 }
1712 nla_nest_end(skb, list); 1712 nla_nest_end(skb, list);
1713 1713
1714 if (rule->ulen && 1714 if (rule->udata) {
1715 nla_put(skb, NFTA_RULE_USERDATA, rule->ulen, nft_userdata(rule))) 1715 struct nft_userdata *udata = nft_userdata(rule);
1716 goto nla_put_failure; 1716 if (nla_put(skb, NFTA_RULE_USERDATA, udata->len + 1,
1717 udata->data) < 0)
1718 goto nla_put_failure;
1719 }
1717 1720
1718 nlmsg_end(skb, nlh); 1721 nlmsg_end(skb, nlh);
1719 return 0; 1722 return 0;
@@ -1896,11 +1899,12 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
1896 struct nft_table *table; 1899 struct nft_table *table;
1897 struct nft_chain *chain; 1900 struct nft_chain *chain;
1898 struct nft_rule *rule, *old_rule = NULL; 1901 struct nft_rule *rule, *old_rule = NULL;
1902 struct nft_userdata *udata;
1899 struct nft_trans *trans = NULL; 1903 struct nft_trans *trans = NULL;
1900 struct nft_expr *expr; 1904 struct nft_expr *expr;
1901 struct nft_ctx ctx; 1905 struct nft_ctx ctx;
1902 struct nlattr *tmp; 1906 struct nlattr *tmp;
1903 unsigned int size, i, n, ulen = 0; 1907 unsigned int size, i, n, ulen = 0, usize = 0;
1904 int err, rem; 1908 int err, rem;
1905 bool create; 1909 bool create;
1906 u64 handle, pos_handle; 1910 u64 handle, pos_handle;
@@ -1968,12 +1972,19 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
1968 n++; 1972 n++;
1969 } 1973 }
1970 } 1974 }
1975 /* Check for overflow of dlen field */
1976 err = -EFBIG;
1977 if (size >= 1 << 12)
1978 goto err1;
1971 1979
1972 if (nla[NFTA_RULE_USERDATA]) 1980 if (nla[NFTA_RULE_USERDATA]) {
1973 ulen = nla_len(nla[NFTA_RULE_USERDATA]); 1981 ulen = nla_len(nla[NFTA_RULE_USERDATA]);
1982 if (ulen > 0)
1983 usize = sizeof(struct nft_userdata) + ulen;
1984 }
1974 1985
1975 err = -ENOMEM; 1986 err = -ENOMEM;
1976 rule = kzalloc(sizeof(*rule) + size + ulen, GFP_KERNEL); 1987 rule = kzalloc(sizeof(*rule) + size + usize, GFP_KERNEL);
1977 if (rule == NULL) 1988 if (rule == NULL)
1978 goto err1; 1989 goto err1;
1979 1990
@@ -1981,10 +1992,13 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
1981 1992
1982 rule->handle = handle; 1993 rule->handle = handle;
1983 rule->dlen = size; 1994 rule->dlen = size;
1984 rule->ulen = ulen; 1995 rule->udata = ulen ? 1 : 0;
1985 1996
1986 if (ulen) 1997 if (ulen) {
1987 nla_memcpy(nft_userdata(rule), nla[NFTA_RULE_USERDATA], ulen); 1998 udata = nft_userdata(rule);
1999 udata->len = ulen - 1;
2000 nla_memcpy(udata->data, nla[NFTA_RULE_USERDATA], ulen);
2001 }
1988 2002
1989 expr = nft_expr_first(rule); 2003 expr = nft_expr_first(rule);
1990 for (i = 0; i < n; i++) { 2004 for (i = 0; i < n; i++) {
@@ -2031,12 +2045,6 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
2031 2045
2032err3: 2046err3:
2033 list_del_rcu(&rule->list); 2047 list_del_rcu(&rule->list);
2034 if (trans) {
2035 list_del_rcu(&nft_trans_rule(trans)->list);
2036 nft_rule_clear(net, nft_trans_rule(trans));
2037 nft_trans_destroy(trans);
2038 chain->use++;
2039