git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Cc: Eric Sunshine <sunshine@sunshineco.com>,
	Junio C Hamano <gitster@pobox.com>
Subject: [PATCH 02/21] add helpers for detecting size_t overflow
Date: Fri, 19 Feb 2016 06:21:19 -0500	[thread overview]
Message-ID: <20160219112119.GB9319@sigill.intra.peff.net> (raw)
In-Reply-To: <20160219111941.GA31906@sigill.intra.peff.net>

Performing computations on size_t variables that we feed to
xmalloc and friends can be dangerous, as an integer overflow
can cause us to allocate a much smaller chunk than we
realized.

We already have unsigned_add_overflows(), but let's add
unsigned_mult_overflows() to that. Furthermore, rather than
have each site manually check and die on overflow, we can
provide some helpers that will:

  - promote the arguments to size_t, so that we know we are
    doing our computation in the same size of integer that
    will ultimately be fed to xmalloc

  - check and die on overflow

  - return the result so that computations can be done in
    the parameter list of xmalloc.

These functions are a lot uglier to use than normal
arithmetic operators (you have to do "st_add(foo, bar)"
instead of "foo + bar"). To at least limit the damage, we
also provide multi-valued versions. So rather than:

  st_add(st_add(a, b), st_add(c, d));

you can write:

  st_add4(a, b, c, d);

This isn't nearly as elegant as a varargs function, but it's
a lot harder to get it wrong. You don't have to remember to
add a sentinel value at the end, and the compiler will
complain if you get the number of arguments wrong. This
patch adds only the numbered variants required to convert
the current code base; we can easily add more later if
needed.

Signed-off-by: Jeff King <peff@peff.net>
---
 git-compat-util.h | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/git-compat-util.h b/git-compat-util.h
index 693a336..0c65033 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -96,6 +96,14 @@
 #define unsigned_add_overflows(a, b) \
     ((b) > maximum_unsigned_value_of_type(a) - (a))
 
+/*
+ * Returns true if the multiplication of "a" and "b" will
+ * overflow. The types of "a" and "b" must match and must be unsigned.
+ * Note that this macro evaluates "a" twice!
+ */
+#define unsigned_mult_overflows(a, b) \
+    ((a) && (b) > maximum_unsigned_value_of_type(a) / (a))
+
 #ifdef __GNUC__
 #define TYPEOF(x) (__typeof__(x))
 #else
@@ -713,6 +721,32 @@ extern void release_pack_memory(size_t);
 typedef void (*try_to_free_t)(size_t);
 extern try_to_free_t set_try_to_free_routine(try_to_free_t);
 
+static inline size_t st_add(size_t a, size_t b)
+{
+	if (unsigned_add_overflows(a, b))
+		die("size_t overflow: %"PRIuMAX" + %"PRIuMAX,
+		    (uintmax_t)a, (uintmax_t)b);
+	return a + b;
+}
+#define st_add3(a,b,c)   st_add((a),st_add((b),(c)))
+#define st_add4(a,b,c,d) st_add((a),st_add3((b),(c),(d)))
+
+static inline size_t st_mult(size_t a, size_t b)
+{
+	if (unsigned_mult_overflows(a, b))
+		die("size_t overflow: %"PRIuMAX" * %"PRIuMAX,
+		    (uintmax_t)a, (uintmax_t)b);
+	return a * b;
+}
+
+static inline size_t st_sub(size_t a, size_t b)
+{
+	if (a < b)
+		die("size_t underflow: %"PRIuMAX" - %"PRIuMAX,
+		    (uintmax_t)a, (uintmax_t)b);
+	return a - b;
+}
+
 #ifdef HAVE_ALLOCA_H
 # include <alloca.h>
 # define xalloca(size)      (alloca(size))
-- 
2.7.1.577.gfed91b8

  parent reply	other threads:[~2016-02-19 11:21 UTC|newest]

Thread overview: 93+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-15 21:45 [PATCH 0/18] hardening allocations against integer overflow Jeff King
2016-02-15 21:49 ` [PATCH 01/18] add helpers for detecting size_t overflow Jeff King
2016-02-15 21:49 ` [PATCH 02/18] tree-diff: catch integer overflow in combine_diff_path allocation Jeff King
2016-02-15 21:50 ` [PATCH 03/18] harden REALLOC_ARRAY and xcalloc against size_t overflow Jeff King
2016-02-15 21:50 ` [PATCH 04/18] add helpers for allocating flex-array structs Jeff King
2016-02-16  1:47   ` Eric Sunshine
2016-02-16  2:52     ` Jeff King
2016-02-15 21:51 ` [PATCH 05/18] convert trivial cases to ALLOC_ARRAY Jeff King
2016-02-16  4:22   ` Eric Sunshine
2016-02-16  4:23     ` Jeff King
2016-02-16  4:32       ` Eric Sunshine
2016-02-16  5:46         ` Jeff King
2016-02-15 21:52 ` [PATCH 06/18] use xmallocz to avoid size arithmetic Jeff King
2016-02-15 21:52 ` [PATCH 07/18] convert trivial cases to FLEX_ARRAY macros Jeff King
2016-02-16  2:17   ` Eric Sunshine
2016-02-16  3:15     ` Jeff King
2016-02-16  3:26       ` Jeff King
2016-02-16  3:36         ` Jeff King
2016-02-16  4:18           ` Eric Sunshine
2016-02-16  4:22             ` Jeff King
2016-02-16  4:10       ` Eric Sunshine
2016-02-15 21:53 ` [PATCH 08/18] use st_add and st_mult for allocation size computation Jeff King
2016-02-16  5:47   ` Eric Sunshine
2016-02-15 21:53 ` [PATCH 09/18] write_untracked_extension: use FLEX_ALLOC helper Jeff King
2016-02-15 21:54 ` [PATCH 10/18] fast-import: simplify allocation in start_packfile Jeff King
2016-02-15 21:54 ` [PATCH 11/18] fetch-pack: simplify add_sought_entry Jeff King
2016-02-15 21:55 ` [PATCH 12/18] test-path-utils: fix normalize_path_copy output buffer size Jeff King
2016-02-15 21:56 ` [PATCH 13/18] sequencer: simplify memory allocation of get_message Jeff King
2016-02-16  6:05   ` Eric Sunshine
2016-02-15 21:56 ` [PATCH 14/18] git-compat-util: drop mempcpy compat code Jeff King
2016-02-16  6:05   ` Eric Sunshine
2016-02-15 21:56 ` [PATCH 15/18] transport_anonymize_url: use xstrfmt Jeff King
2016-02-15 21:56 ` [PATCH 16/18] diff_populate_gitlink: use a strbuf Jeff King
2016-02-15 21:57 ` [PATCH 17/18] convert ewah/bitmap code to use xmalloc Jeff King
2016-02-15 21:57 ` [PATCH 18/18] ewah: convert to REALLOC_ARRAY, etc Jeff King
2016-02-15 22:02 ` [PATCH 0/18] hardening allocations against integer overflow Jeff King
2016-02-19 11:19 ` [PATCH v2 0/21] " Jeff King
2016-02-19 11:21   ` [PATCH 01/21] reflog_expire_cfg: NUL-terminate pattern field Jeff King
2016-02-19 11:21   ` Jeff King [this message]
2016-02-19 11:21   ` [PATCH 03/21] tree-diff: catch integer overflow in combine_diff_path allocation Jeff King
2016-02-19 11:22   ` [PATCH 04/21] harden REALLOC_ARRAY and xcalloc against size_t overflow Jeff King
2016-02-20 21:32     ` René Scharfe
2016-02-21 23:30       ` Jeff King
2016-02-19 11:22   ` [PATCH 05/21] add helpers for allocating flex-array structs Jeff King
2016-02-19 11:23   ` [PATCH 06/21] convert manual allocations to argv_array Jeff King
2016-02-20  8:07     ` Eric Sunshine
2016-02-20  8:10       ` Jeff King
2016-02-20  8:29         ` Eric Sunshine
2016-02-20  8:34           ` Jeff King
2016-02-20  8:39             ` Eric Sunshine
2016-02-20  8:57               ` Jeff King
2016-02-20  9:04                 ` Eric Sunshine
2016-02-19 11:23   ` [PATCH 07/21] convert trivial cases to ALLOC_ARRAY Jeff King
2016-02-19 11:23   ` [PATCH 08/21] use xmallocz to avoid size arithmetic Jeff King
2016-02-19 11:23   ` [PATCH 09/21] convert trivial cases to FLEX_ARRAY macros Jeff King
2016-02-19 11:23   ` [PATCH 10/21] use st_add and st_mult for allocation size computation Jeff King
2016-02-19 11:24   ` [PATCH 11/21] prepare_{git,shell}_cmd: use argv_array Jeff King
2016-02-19 11:24   ` [PATCH 12/21] write_untracked_extension: use FLEX_ALLOC helper Jeff King
2016-02-19 11:24   ` [PATCH 13/21] fast-import: simplify allocation in start_packfile Jeff King
2016-02-19 17:48     ` Junio C Hamano
2016-02-19 19:12       ` Jeff King
2016-02-19 11:24   ` [PATCH 14/21] fetch-pack: simplify add_sought_entry Jeff King
2016-02-19 11:24   ` [PATCH 15/21] test-path-utils: fix normalize_path_copy output buffer size Jeff King
2016-02-19 11:25   ` [PATCH 16/21] sequencer: simplify memory allocation of get_message Jeff King
2016-02-19 11:25   ` [PATCH 17/21] git-compat-util: drop mempcpy compat code Jeff King
2016-02-19 11:25   ` [PATCH 18/21] transport_anonymize_url: use xstrfmt Jeff King
2016-02-19 11:25   ` [PATCH 19/21] diff_populate_gitlink: use a strbuf Jeff King
2016-02-19 11:25   ` [PATCH 20/21] convert ewah/bitmap code to use xmalloc Jeff King
2016-02-19 11:25   ` [PATCH 21/21] ewah: convert to REALLOC_ARRAY, etc Jeff King
2016-02-22 22:41   ` [PATCH v3 0/22] hardening allocations against integer overflow Jeff King
2016-02-22 22:43     ` [PATCH v3 01/22] reflog_expire_cfg: NUL-terminate pattern field Jeff King
2016-02-22 22:43     ` [PATCH v3 02/22] add helpers for detecting size_t overflow Jeff King
2016-02-22 22:43     ` [PATCH v3 03/22] tree-diff: catch integer overflow in combine_diff_path allocation Jeff King
2016-02-22 22:43     ` [PATCH v3 04/22] harden REALLOC_ARRAY and xcalloc against size_t overflow Jeff King
2016-02-22 22:43     ` [PATCH v3 05/22] add helpers for allocating flex-array structs Jeff King
2016-02-22 22:44     ` [PATCH v3 06/22] argv-array: add detach function Jeff King
2016-02-22 22:44     ` [PATCH v3 07/22] convert manual allocations to argv_array Jeff King
2016-02-22 22:44     ` [PATCH v3 08/22] convert trivial cases to ALLOC_ARRAY Jeff King
2016-02-22 22:44     ` [PATCH v3 09/22] use xmallocz to avoid size arithmetic Jeff King
2016-02-22 22:44     ` [PATCH v3 10/22] convert trivial cases to FLEX_ARRAY macros Jeff King
2016-02-22 22:44     ` [PATCH v3 11/22] use st_add and st_mult for allocation size computation Jeff King
2016-02-22 22:44     ` [PATCH v3 12/22] prepare_{git,shell}_cmd: use argv_array Jeff King
2016-02-22 22:44     ` [PATCH v3 13/22] write_untracked_extension: use FLEX_ALLOC helper Jeff King
2016-02-22 22:44     ` [PATCH v3 14/22] fast-import: simplify allocation in start_packfile Jeff King
2016-02-22 22:44     ` [PATCH v3 15/22] fetch-pack: simplify add_sought_entry Jeff King
2016-02-22 22:44     ` [PATCH v3 16/22] test-path-utils: fix normalize_path_copy output buffer size Jeff King
2016-02-22 22:44     ` [PATCH v3 17/22] sequencer: simplify memory allocation of get_message Jeff King
2016-02-22 22:45     ` [PATCH v3 18/22] git-compat-util: drop mempcpy compat code Jeff King
2016-02-22 22:45     ` [PATCH v3 19/22] transport_anonymize_url: use xstrfmt Jeff King
2016-02-22 22:45     ` [PATCH v3 20/22] diff_populate_gitlink: use a strbuf Jeff King
2016-02-22 22:45     ` [PATCH v3 21/22] convert ewah/bitmap code to use xmalloc Jeff King
2016-02-22 22:45     ` [PATCH v3 22/22] ewah: convert to REALLOC_ARRAY, etc Jeff King
2016-02-22 23:08     ` [PATCH v3 0/22] hardening allocations against integer overflow Junio C Hamano

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=20160219112119.GB9319@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=sunshine@sunshineco.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 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).