* [PATCH v4] netfilter: conntrack: clamp timeouts to INT_MAX
@ 2017-11-15 23:01 Jay Elliott
2017-11-27 23:24 ` Pablo Neira Ayuso
0 siblings, 1 reply; 4+ messages in thread
From: Jay Elliott @ 2017-11-15 23:01 UTC (permalink / raw)
To: pablo; +Cc: Jay Elliott, fw, netfilter-devel
When the conntracking code multiplies a timeout by HZ, it can overflow
from positive to negative; this causes it to instantly expire. To
protect against this the multiplication is done in 64-bit so we can
prevent it from exceeding INT_MAX.
Signed-off-by: Jay Elliott <jelliott@arista.com>
---
net/netfilter/nf_conntrack_netlink.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index de4053d..41db7e3 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1560,9 +1560,11 @@ static int ctnetlink_change_helper(struct nf_conn *ct,
static int ctnetlink_change_timeout(struct nf_conn *ct,
const struct nlattr * const cda[])
{
- u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
+ u64 timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
- ct->timeout = nfct_time_stamp + timeout * HZ;
+ if (timeout > INT_MAX)
+ timeout = INT_MAX;
+ ct->timeout = nfct_time_stamp + (u32)timeout;
if (test_bit(IPS_DYING_BIT, &ct->status))
return -ETIME;
@@ -1762,6 +1764,7 @@ static int change_seq_adj(struct nf_ct_seqadj *seq,
int err = -EINVAL;
struct nf_conntrack_helper *helper;
struct nf_conn_tstamp *tstamp;
+ u64 timeout;
ct = nf_conntrack_alloc(net, zone, otuple, rtuple, GFP_ATOMIC);
if (IS_ERR(ct))
@@ -1770,7 +1773,10 @@ static int change_seq_adj(struct nf_ct_seqadj *seq,
if (!cda[CTA_TIMEOUT])
goto err1;
- ct->timeout = nfct_time_stamp + ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
+ timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
+ if (timeout > INT_MAX)
+ timeout = INT_MAX;
+ ct->timeout = (u32)timeout + nfct_time_stamp;
rcu_read_lock();
if (cda[CTA_HELP]) {
--
1.8.1.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v4] netfilter: conntrack: clamp timeouts to INT_MAX
2017-11-15 23:01 [PATCH v4] netfilter: conntrack: clamp timeouts to INT_MAX Jay Elliott
@ 2017-11-27 23:24 ` Pablo Neira Ayuso
2017-11-28 0:12 ` Florian Westphal
0 siblings, 1 reply; 4+ messages in thread
From: Pablo Neira Ayuso @ 2017-11-27 23:24 UTC (permalink / raw)
To: Jay Elliott; +Cc: fw, netfilter-devel
On Wed, Nov 15, 2017 at 03:01:13PM -0800, Jay Elliott wrote:
> When the conntracking code multiplies a timeout by HZ, it can overflow
> from positive to negative; this causes it to instantly expire. To
> protect against this the multiplication is done in 64-bit so we can
> prevent it from exceeding INT_MAX.
This is something you must be observing via conntrack utility or
conntrackd?
> Signed-off-by: Jay Elliott <jelliott@arista.com>
> ---
> net/netfilter/nf_conntrack_netlink.c | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
> index de4053d..41db7e3 100644
> --- a/net/netfilter/nf_conntrack_netlink.c
> +++ b/net/netfilter/nf_conntrack_netlink.c
> @@ -1560,9 +1560,11 @@ static int ctnetlink_change_helper(struct nf_conn *ct,
> static int ctnetlink_change_timeout(struct nf_conn *ct,
> const struct nlattr * const cda[])
> {
> - u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
> + u64 timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
>
> - ct->timeout = nfct_time_stamp + timeout * HZ;
> + if (timeout > INT_MAX)
> + timeout = INT_MAX;
> + ct->timeout = nfct_time_stamp + (u32)timeout;
>
> if (test_bit(IPS_DYING_BIT, &ct->status))
> return -ETIME;
> @@ -1762,6 +1764,7 @@ static int change_seq_adj(struct nf_ct_seqadj *seq,
> int err = -EINVAL;
> struct nf_conntrack_helper *helper;
> struct nf_conn_tstamp *tstamp;
> + u64 timeout;
>
> ct = nf_conntrack_alloc(net, zone, otuple, rtuple, GFP_ATOMIC);
> if (IS_ERR(ct))
> @@ -1770,7 +1773,10 @@ static int change_seq_adj(struct nf_ct_seqadj *seq,
> if (!cda[CTA_TIMEOUT])
> goto err1;
>
> - ct->timeout = nfct_time_stamp + ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
> + timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
> + if (timeout > INT_MAX)
> + timeout = INT_MAX;
> + ct->timeout = (u32)timeout + nfct_time_stamp;
>
> rcu_read_lock();
> if (cda[CTA_HELP]) {
> --
> 1.8.1.4
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v4] netfilter: conntrack: clamp timeouts to INT_MAX
2017-11-27 23:24 ` Pablo Neira Ayuso
@ 2017-11-28 0:12 ` Florian Westphal
2017-11-28 0:14 ` Pablo Neira Ayuso
0 siblings, 1 reply; 4+ messages in thread
From: Florian Westphal @ 2017-11-28 0:12 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: Jay Elliott, fw, netfilter-devel
Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Wed, Nov 15, 2017 at 03:01:13PM -0800, Jay Elliott wrote:
> > When the conntracking code multiplies a timeout by HZ, it can overflow
> > from positive to negative; this causes it to instantly expire. To
> > protect against this the multiplication is done in 64-bit so we can
> > prevent it from exceeding INT_MAX.
>
> This is something you must be observing via conntrack utility or
> conntrackd?
nf_ct_is_expired() will consider a ct as expired if the delta
between current time and the (future) timeout is > 2**31.
This triggers when ctnetlink configures a timeout larger than 2**31.
The patch looks correct to me.
Acked-by: Florian Westphal <fw@strlen.de>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v4] netfilter: conntrack: clamp timeouts to INT_MAX
2017-11-28 0:12 ` Florian Westphal
@ 2017-11-28 0:14 ` Pablo Neira Ayuso
0 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2017-11-28 0:14 UTC (permalink / raw)
To: Florian Westphal; +Cc: Jay Elliott, netfilter-devel
On Tue, Nov 28, 2017 at 01:12:44AM +0100, Florian Westphal wrote:
> Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> > On Wed, Nov 15, 2017 at 03:01:13PM -0800, Jay Elliott wrote:
> > > When the conntracking code multiplies a timeout by HZ, it can overflow
> > > from positive to negative; this causes it to instantly expire. To
> > > protect against this the multiplication is done in 64-bit so we can
> > > prevent it from exceeding INT_MAX.
> >
> > This is something you must be observing via conntrack utility or
> > conntrackd?
>
> nf_ct_is_expired() will consider a ct as expired if the delta
> between current time and the (future) timeout is > 2**31.
>
> This triggers when ctnetlink configures a timeout larger than 2**31.
>
> The patch looks correct to me.
>
> Acked-by: Florian Westphal <fw@strlen.de>
I'll pass this to net instead, this is likely breaking conntrackd.
Thanks.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-11-28 0:15 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-11-15 23:01 [PATCH v4] netfilter: conntrack: clamp timeouts to INT_MAX Jay Elliott
2017-11-27 23:24 ` Pablo Neira Ayuso
2017-11-28 0:12 ` Florian Westphal
2017-11-28 0:14 ` Pablo Neira Ayuso
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).