Commit 92a03eb0 authored by David S. Miller's avatar David S. Miller

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf

Pablo Neira Ayuso says:

====================
Netfilter/IPVS fixes for net

The following patchset contains Netfilter/IPVS fixes for your net tree.
they are:

1) Fix leak in the error path of nft_expr_init(), from Liping Zhang.

2) Tracing from nf_tables cannot be disabled, also from Zhang.

3) Fix an integer overflow on 32bit archs when setting the number of
   hashtable buckets, from Florian Westphal.

4) Fix configuration of ipvs sync in backup mode with IPv6 address,
   from Quentin Armitage via Simon Horman.

5) Fix incorrect timeout calculation in nft_ct NFT_CT_EXPIRATION,
   from Florian Westphal.

6) Skip clash resolution in conntrack insertion races if NAT is in
   place.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ce9a4f31 590b52e1
...@@ -284,6 +284,14 @@ static inline bool nf_is_loopback_packet(const struct sk_buff *skb) ...@@ -284,6 +284,14 @@ static inline bool nf_is_loopback_packet(const struct sk_buff *skb)
return skb->dev && skb->skb_iif && skb->dev->flags & IFF_LOOPBACK; return skb->dev && skb->skb_iif && skb->dev->flags & IFF_LOOPBACK;
} }
/* jiffies until ct expires, 0 if already expired */
static inline unsigned long nf_ct_expires(const struct nf_conn *ct)
{
long timeout = (long)ct->timeout.expires - (long)jiffies;
return timeout > 0 ? timeout : 0;
}
struct kernel_param; struct kernel_param;
int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp); int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp);
......
...@@ -1545,7 +1545,8 @@ static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id) ...@@ -1545,7 +1545,8 @@ static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id)
/* /*
* Set up receiving multicast socket over UDP * Set up receiving multicast socket over UDP
*/ */
static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id) static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id,
int ifindex)
{ {
/* multicast addr */ /* multicast addr */
union ipvs_sockaddr mcast_addr; union ipvs_sockaddr mcast_addr;
...@@ -1566,6 +1567,7 @@ static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id) ...@@ -1566,6 +1567,7 @@ static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id)
set_sock_size(sock->sk, 0, result); set_sock_size(sock->sk, 0, result);
get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id); get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id);
sock->sk->sk_bound_dev_if = ifindex;
result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen); result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen);
if (result < 0) { if (result < 0) {
pr_err("Error binding to the multicast addr\n"); pr_err("Error binding to the multicast addr\n");
...@@ -1868,7 +1870,7 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c, ...@@ -1868,7 +1870,7 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
if (state == IP_VS_STATE_MASTER) if (state == IP_VS_STATE_MASTER)
sock = make_send_sock(ipvs, id); sock = make_send_sock(ipvs, id);
else else
sock = make_receive_sock(ipvs, id); sock = make_receive_sock(ipvs, id, dev->ifindex);
if (IS_ERR(sock)) { if (IS_ERR(sock)) {
result = PTR_ERR(sock); result = PTR_ERR(sock);
goto outtinfo; goto outtinfo;
......
...@@ -646,6 +646,7 @@ static int nf_ct_resolve_clash(struct net *net, struct sk_buff *skb, ...@@ -646,6 +646,7 @@ static int nf_ct_resolve_clash(struct net *net, struct sk_buff *skb,
l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
if (l4proto->allow_clash && if (l4proto->allow_clash &&
!nfct_nat(ct) &&
!nf_ct_is_dying(ct) && !nf_ct_is_dying(ct) &&
atomic_inc_not_zero(&ct->ct_general.use)) { atomic_inc_not_zero(&ct->ct_general.use)) {
nf_ct_acct_merge(ct, ctinfo, (struct nf_conn *)skb->nfct); nf_ct_acct_merge(ct, ctinfo, (struct nf_conn *)skb->nfct);
...@@ -1601,8 +1602,15 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls) ...@@ -1601,8 +1602,15 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
unsigned int nr_slots, i; unsigned int nr_slots, i;
size_t sz; size_t sz;
if (*sizep > (UINT_MAX / sizeof(struct hlist_nulls_head)))
return NULL;
BUILD_BUG_ON(sizeof(struct hlist_nulls_head) != sizeof(struct hlist_head)); BUILD_BUG_ON(sizeof(struct hlist_nulls_head) != sizeof(struct hlist_head));
nr_slots = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_nulls_head)); nr_slots = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_nulls_head));
if (nr_slots > (UINT_MAX / sizeof(struct hlist_nulls_head)))
return NULL;
sz = nr_slots * sizeof(struct hlist_nulls_head); sz = nr_slots * sizeof(struct hlist_nulls_head);
hash = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO, hash = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO,
get_order(sz)); get_order(sz));
......
...@@ -1724,9 +1724,11 @@ struct nft_expr *nft_expr_init(const struct nft_ctx *ctx, ...@@ -1724,9 +1724,11 @@ struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
err = nf_tables_newexpr(ctx, &info, expr); err = nf_tables_newexpr(ctx, &info, expr);
if (err < 0) if (err < 0)
goto err2; goto err3;
return expr; return expr;
err3:
kfree(expr);
err2: err2:
module_put(info.ops->type->owner); module_put(info.ops->type->owner);
err1: err1:
......
...@@ -54,7 +54,6 @@ static void nft_ct_get_eval(const struct nft_expr *expr, ...@@ -54,7 +54,6 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
const struct nf_conn_help *help; const struct nf_conn_help *help;
const struct nf_conntrack_tuple *tuple; const struct nf_conntrack_tuple *tuple;
const struct nf_conntrack_helper *helper; const struct nf_conntrack_helper *helper;
long diff;
unsigned int state; unsigned int state;
ct = nf_ct_get(pkt->skb, &ctinfo); ct = nf_ct_get(pkt->skb, &ctinfo);
...@@ -94,10 +93,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr, ...@@ -94,10 +93,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
return; return;
#endif #endif
case NFT_CT_EXPIRATION: case NFT_CT_EXPIRATION:
diff = (long)jiffies - (long)ct->timeout.expires; *dest = jiffies_to_msecs(nf_ct_expires(ct));
if (diff < 0)
diff = 0;
*dest = jiffies_to_msecs(diff);
return; return;
case NFT_CT_HELPER: case NFT_CT_HELPER:
if (ct->master == NULL) if (ct->master == NULL)
......
...@@ -227,7 +227,7 @@ void nft_meta_set_eval(const struct nft_expr *expr, ...@@ -227,7 +227,7 @@ void nft_meta_set_eval(const struct nft_expr *expr,
skb->pkt_type = value; skb->pkt_type = value;
break; break;
case NFT_META_NFTRACE: case NFT_META_NFTRACE:
skb->nf_trace = 1; skb->nf_trace = !!value;
break; break;
default: default:
WARN_ON(1); WARN_ON(1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment