netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nf] netfilter: conntrack: avoid integer overflow when resizing
@ 2016-04-23 23:18 Florian Westphal
  2016-04-29  9:59 ` Pablo Neira Ayuso
  0 siblings, 1 reply; 4+ messages in thread
From: Florian Westphal @ 2016-04-23 23:18 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

Can overflow so we might allocate very small table when bucket count is
high on a 32bit platform.

Note: resize is only possible from init_netns.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 net/netfilter/nf_conntrack_core.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 2bbb962..11daca5 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1563,8 +1563,15 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
 	unsigned int nr_slots, i;
 	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));
 	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);
 	hash = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO,
 					get_order(sz));
-- 
2.7.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH nf] netfilter: conntrack: avoid integer overflow when resizing
  2016-04-23 23:18 [PATCH nf] netfilter: conntrack: avoid integer overflow when resizing Florian Westphal
@ 2016-04-29  9:59 ` Pablo Neira Ayuso
  2016-05-01 19:48   ` Florian Westphal
  0 siblings, 1 reply; 4+ messages in thread
From: Pablo Neira Ayuso @ 2016-04-29  9:59 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Sun, Apr 24, 2016 at 01:18:21AM +0200, Florian Westphal wrote:
> Can overflow so we might allocate very small table when bucket count is
> high on a 32bit platform.
> 
> Note: resize is only possible from init_netns.
> 
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
>  net/netfilter/nf_conntrack_core.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
> index 2bbb962..11daca5 100644
> --- a/net/netfilter/nf_conntrack_core.c
> +++ b/net/netfilter/nf_conntrack_core.c
> @@ -1563,8 +1563,15 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
>  	unsigned int nr_slots, i;
>  	size_t sz;
>  
> +	if (*sizep > (UINT_MAX / sizeof(struct hlist_nulls_head)))
> +		return NULL;

*sizep gets initially set to the number of buckets.

>  	BUILD_BUG_ON(sizeof(struct hlist_nulls_head) != sizeof(struct hlist_head));
>  	nr_slots = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_nulls_head));

Then, this value is divided by the number of hlist heads that fit into
a page.

> +
> +	if (nr_slots > (UINT_MAX / sizeof(struct hlist_nulls_head)))
> +		return NULL;

So, isn't is enough with this sole check? I might be missing anything.

> +
>  	sz = nr_slots * sizeof(struct hlist_nulls_head);
>  	hash = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO,
>  					get_order(sz));
> -- 
> 2.7.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH nf] netfilter: conntrack: avoid integer overflow when resizing
  2016-04-29  9:59 ` Pablo Neira Ayuso
@ 2016-05-01 19:48   ` Florian Westphal
  2016-05-03 22:45     ` Pablo Neira Ayuso
  0 siblings, 1 reply; 4+ messages in thread
From: Florian Westphal @ 2016-05-01 19:48 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Florian Westphal, netfilter-devel

Pablo Neira Ayuso <pablo@netfilter.org> wrote:

[ Sorry for late reply ]

> On Sun, Apr 24, 2016 at 01:18:21AM +0200, Florian Westphal wrote:
> > Can overflow so we might allocate very small table when bucket count is
> > high on a 32bit platform.
> > 
> > Note: resize is only possible from init_netns.
> > 
> > Signed-off-by: Florian Westphal <fw@strlen.de>
> > ---
> >  net/netfilter/nf_conntrack_core.c | 7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
> > index 2bbb962..11daca5 100644
> > --- a/net/netfilter/nf_conntrack_core.c
> > +++ b/net/netfilter/nf_conntrack_core.c
> > @@ -1563,8 +1563,15 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
> >  	unsigned int nr_slots, i;
> >  	size_t sz;
> >  
> > +	if (*sizep > (UINT_MAX / sizeof(struct hlist_nulls_head)))
> > +		return NULL;
> 
> *sizep gets initially set to the number of buckets.

Yes.

> >  	BUILD_BUG_ON(sizeof(struct hlist_nulls_head) != sizeof(struct hlist_head));
> >  	nr_slots = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_nulls_head));
> 
> Then, this value is divided by the number of hlist heads that fit into
> a page.

No, its rounded up to a multiple of PAGE/hlist heads, so for very large
values of *sizep nr_slots would be 0.

> > +	if (nr_slots > (UINT_MAX / sizeof(struct hlist_nulls_head)))
> > +		return NULL;

Alternative would be to change this to:

if (nr_slots == 0 || nr_slots > (UINT_MAX / sizeof(struct hlist_nulls_head)))
	return NULL;

Or, add this check:

if (nr_slots < roundup(1, PAGE_SIZE / sizeof(struct hlist_nulls_head))
    nr_slots = roundup(1, PAGE_SIZE / sizeof(struct hlist_nulls_head)))

I wasn't sure if its better to fail or if we should just pretend a sane
value was given.

Let me know what you think and I'll submit a v2.

[ Its not a big deal, but eventually I'd like to make the sysctl
  writeable so users can just increase that, no need to use this obscure
  module parameter/sysfs param ... ]

Cheers,
Florian

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH nf] netfilter: conntrack: avoid integer overflow when resizing
  2016-05-01 19:48   ` Florian Westphal
@ 2016-05-03 22:45     ` Pablo Neira Ayuso
  0 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2016-05-03 22:45 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Sun, May 01, 2016 at 09:48:34PM +0200, Florian Westphal wrote:
> Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> 
> [ Sorry for late reply ]
> 
> > On Sun, Apr 24, 2016 at 01:18:21AM +0200, Florian Westphal wrote:
> > > Can overflow so we might allocate very small table when bucket count is
> > > high on a 32bit platform.
> > > 
> > > Note: resize is only possible from init_netns.
> > > 
> > > Signed-off-by: Florian Westphal <fw@strlen.de>
> > > ---
> > >  net/netfilter/nf_conntrack_core.c | 7 +++++++
> > >  1 file changed, 7 insertions(+)
> > > 
> > > diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
> > > index 2bbb962..11daca5 100644
> > > --- a/net/netfilter/nf_conntrack_core.c
> > > +++ b/net/netfilter/nf_conntrack_core.c
> > > @@ -1563,8 +1563,15 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
> > >  	unsigned int nr_slots, i;
> > >  	size_t sz;
> > >  
> > > +	if (*sizep > (UINT_MAX / sizeof(struct hlist_nulls_head)))
> > > +		return NULL;
> > 
> > *sizep gets initially set to the number of buckets.
> 
> Yes.
> 
> > >  	BUILD_BUG_ON(sizeof(struct hlist_nulls_head) != sizeof(struct hlist_head));
> > >  	nr_slots = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_nulls_head));
> > 
> > Then, this value is divided by the number of hlist heads that fit into
> > a page.
> 
> No, its rounded up to a multiple of PAGE/hlist heads, so for very large
> values of *sizep nr_slots would be 0.
> 
> > > +	if (nr_slots > (UINT_MAX / sizeof(struct hlist_nulls_head)))
> > > +		return NULL;
> 
> Alternative would be to change this to:
> 
> if (nr_slots == 0 || nr_slots > (UINT_MAX / sizeof(struct hlist_nulls_head)))
> 	return NULL;
> 
> Or, add this check:
> 
> if (nr_slots < roundup(1, PAGE_SIZE / sizeof(struct hlist_nulls_head))
>     nr_slots = roundup(1, PAGE_SIZE / sizeof(struct hlist_nulls_head)))
> 
> I wasn't sure if its better to fail or if we should just pretend a sane
> value was given.

I prefer an explicit failure, so the user knows that what is asking
for is not supported, rather than masking the problem.

> Let me know what you think and I'll submit a v2.
> 
> [ Its not a big deal, but eventually I'd like to make the sysctl
>   writeable so users can just increase that, no need to use this obscure
>   module parameter/sysfs param ... ]

Sounds good to me.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-05-03 22:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-23 23:18 [PATCH nf] netfilter: conntrack: avoid integer overflow when resizing Florian Westphal
2016-04-29  9:59 ` Pablo Neira Ayuso
2016-05-01 19:48   ` Florian Westphal
2016-05-03 22:45     ` 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).