diff options
author | fw <fw@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-05 17:48:46 +0000 |
---|---|---|
committer | fw <fw@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-05 17:48:46 +0000 |
commit | 5fd168b60a241917f30526c8f5b87945e2a94b31 (patch) | |
tree | 9a13f9e7ac82123b90ffc03ec641ccc88a9e23ce /libstdc++-v3/libsupc++ | |
parent | dfd1bdace6e4d4aed998fe47ae60ad9dab4b8afc (diff) | |
download | gcc-5fd168b60a241917f30526c8f5b87945e2a94b31.tar.gz |
Detect overflow in size calculations in __cxa_vec_new{2,3}
2012-11-03 Florian Weimer <fweimer@redhat.com>
* libsupc++/vec.cc (compute_size): New.
(__cxa_vec_new2, __cxa_vec_new3): Use it.
* testsuite/18_support/cxa_vec.cc: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193174 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/libsupc++')
-rw-r--r-- | libstdc++-v3/libsupc++/vec.cc | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/libstdc++-v3/libsupc++/vec.cc b/libstdc++-v3/libsupc++/vec.cc index 700c5ef431d..f9afd39df9b 100644 --- a/libstdc++-v3/libsupc++/vec.cc +++ b/libstdc++-v3/libsupc++/vec.cc @@ -1,7 +1,6 @@ // New abi Support -*- C++ -*- -// Copyright (C) 2000, 2001, 2003, 2004, 2009, 2011 -// Free Software Foundation, Inc. +// Copyright (C) 2000-2012 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -59,6 +58,19 @@ namespace __cxxabiv1 globals->caughtExceptions = p->nextException; globals->uncaughtExceptions += 1; } + + // Compute the total size with overflow checking. + std::size_t compute_size(std::size_t element_count, + std::size_t element_size, + std::size_t padding_size) + { + if (element_size && element_count > std::size_t(-1) / element_size) + throw std::bad_alloc(); + std::size_t size = element_count * element_size; + if (size + padding_size < size) + throw std::bad_alloc(); + return size + padding_size; + } } // Allocate and construct array. @@ -83,7 +95,8 @@ namespace __cxxabiv1 void *(*alloc) (std::size_t), void (*dealloc) (void *)) { - std::size_t size = element_count * element_size + padding_size; + std::size_t size + = compute_size(element_count, element_size, padding_size); char *base = static_cast <char *> (alloc (size)); if (!base) return base; @@ -124,7 +137,8 @@ namespace __cxxabiv1 void *(*alloc) (std::size_t), void (*dealloc) (void *, std::size_t)) { - std::size_t size = element_count * element_size + padding_size; + std::size_t size + = compute_size(element_count, element_size, padding_size); char *base = static_cast<char *>(alloc (size)); if (!base) return base; |