All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bui Quang Minh <minhquangbui99@gmail.com>
To: Lorenz Bauer <lmb@cloudflare.com>
Cc: Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	"David S . Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	hawk@kernel.org, John Fastabend <john.fastabend@gmail.com>,
	Andrii Nakryiko <andrii@kernel.org>, Martin Lau <kafai@fb.com>,
	Song Liu <songliubraving@fb.com>, Yonghong Song <yhs@fb.com>,
	kpsingh@kernel.org, Jakub Sitnicki <jakub@cloudflare.com>,
	Networking <netdev@vger.kernel.org>, bpf <bpf@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] bpf: Fix integer overflow in argument calculation for bpf_map_area_alloc
Date: Wed, 27 Jan 2021 11:23:41 +0700	[thread overview]
Message-ID: <20210127042341.GA4948@ubuntu> (raw)
In-Reply-To: <CACAyw99bEYWJCSGqfLiJ9Jp5YE1ZsZSiJxb4RFUTwbofipf0dA@mail.gmail.com>

On Tue, Jan 26, 2021 at 09:36:57AM +0000, Lorenz Bauer wrote:
> On Tue, 26 Jan 2021 at 08:26, Bui Quang Minh <minhquangbui99@gmail.com> wrote:
> >
> > In 32-bit architecture, the result of sizeof() is a 32-bit integer so
> > the expression becomes the multiplication between 2 32-bit integer which
> > can potentially leads to integer overflow. As a result,
> > bpf_map_area_alloc() allocates less memory than needed.
> >
> > Fix this by casting 1 operand to u64.
> 
> Some quick thoughts:
> * Should this have a Fixes tag?

Ok, I will add Fixes tag in later version patch.

> * Seems like there are quite a few similar calls scattered around
> (cpumap, etc.). Did you audit these as well?

I spotted another bug after re-auditting. In hashtab, there ares 2 places using
the same calls

	static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
	{
		/* ... snip ... */
		if (htab->n_buckets == 0 ||
		    htab->n_buckets > U32_MAX / sizeof(struct bucket))
			goto free_htab;

		htab->buckets = bpf_map_area_alloc(htab->n_buckets *
						   sizeof(struct bucket),
						   htab->map.numa_node);
	}

This is safe because of the above check.

	static int prealloc_init(struct bpf_htab *htab)
	{
		u32 num_entries = htab->map.max_entries;
		htab->elems = bpf_map_area_alloc(htab->elem_size * num_entries,
						 htab->map.numa_node);
	}

This is not safe since there is no limit check in elem_size.

In cpumap,

	static struct bpf_map *cpu_map_alloc(union bpf_attr *attr)
	{
		cmap->cpu_map = bpf_map_area_alloc(cmap->map.max_entries *
						   sizeof(struct bpf_cpu_map_entry *),
						   cmap->map.numa_node);
	}

I think this is safe because max_entries is not permitted to be larger than NR_CPUS.

In stackmap, there is a place that I'm not very sure about

	static int prealloc_elems_and_freelist(struct bpf_stack_map *smap)
	{
		u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size;
		smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries,
						 smap->map.numa_node);
	}

This is called after another bpf_map_area_alloc in stack_map_alloc(). In the first
bpf_map_area_alloc() the argument is calculated in an u64 variable; so if in the second
one, there is an integer overflow then the first one must be called with size > 4GB. I 
think the first one will probably fail (I am not sure about the actual limit of vmalloc()),
so the second one might not be called.

Overall, I think it is error prone in this pattern, maybe we should use typecasting in all
similar calls or make a comment why we don't use typecasting. As I see typecasting is not so
expensive and we can typecast the sizeof() operand so this change only affect 32-bit
architecture.

> * I'd prefer a calloc style version of bpf_map_area_alloc although
> that might conflict with Fixes tag.

Yes, I think the calloc style will prevent this kind of integer overflow bug.

Thank you,
Quang Minh.


  reply	other threads:[~2021-01-27  5:47 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-26  8:26 [PATCH] bpf: Fix integer overflow in argument calculation for bpf_map_area_alloc Bui Quang Minh
2021-01-26  9:36 ` Lorenz Bauer
2021-01-27  4:23   ` Bui Quang Minh [this message]
2021-01-27  5:09     ` Bui Quang Minh
2021-01-28  0:41     ` Daniel Borkmann
2021-05-17 15:10       ` Bui Quang Minh
  -- strict thread matches above, loose matches on Subject: below --
2021-12-15  2:01 Connor O'Brien
2021-12-15 13:34 ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210127042341.GA4948@ubuntu \
    --to=minhquangbui99@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=hawk@kernel.org \
    --cc=jakub@cloudflare.com \
    --cc=john.fastabend@gmail.com \
    --cc=kafai@fb.com \
    --cc=kpsingh@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lmb@cloudflare.com \
    --cc=netdev@vger.kernel.org \
    --cc=songliubraving@fb.com \
    --cc=yhs@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.