This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.

### 3038. `polymorphic_allocator::allocate` should not allow integer overflow to create vulnerabilities

Section: 20.12.3.3 [mem.poly.allocator.mem] Status: C++20 Submitter: Billy O'Neal III Opened: 2017-11-16 Last modified: 2021-02-25

Priority: 2

View all other issues in [mem.poly.allocator.mem].

View all issues with C++20 status.

Discussion:

At the moment `polymorphic_allocator` is specified to do `sizeof(T) * n` directly; this may allow an attacker to cause this calculation to overflow, resulting in `allocate()` not meeting its postcondition of returning a buffer suitable to store `n` copies of `T`; this is a common bug described in CWE-190.

Making this into a saturating multiply should be sufficient to avoid this problem; any `memory_resource` underneath `polymorphic_allocator` is going to have to throw `bad_alloc` (or another exception) for a request of `SIZE_MAX`.

(There's also a minor editorial thing here that Returns should be Effects)

[2018-06 Rapperswil Thursday issues processing]

Consensus was that the overflow should be detected and an exception thrown rather than leaving that to the underlying memory resource. Billy to reword, and then get feedback on the reflector. Status to Open.

Previous resolution [SUPERSEDED]:

> Wording relative to N4700.

> 1. Edit 20.12.3.3 [mem.poly.allocator.mem] as indicated:

>    >     Tp* allocate(size_t n);

>    > > -1- Returns Effects: Equivalent to

>    > > >     return static_cast<Tp*>(memory_rsrc->allocate(SIZE_MAX / sizeof(Tp) < n ? SIZE_MAX : n * sizeof(Tp), alignof(Tp)));

[2018-08-23 Batavia Issues processing]

Status to Tentatively Ready with updated wording

Previous resolution [SUPERSEDED]:

> Wording relative to N4762.

> 1. Edit 20.12.3.3 [mem.poly.allocator.mem] as indicated:

>    >     Tp* allocate(size_t n);

>    > > -1- Effects: If `SIZE_MAX / sizeof(Tp) < n`, throws `length_error`, then E equivalent to:

>    > > >     return static_cast<Tp*>(memory_rsrc->allocate(n * sizeof(Tp), alignof(Tp)));

[2018-11, Adopted in San Diego]

Proposed resolution:

Wording relative to N4762.

1. Edit 20.12.3.3 [mem.poly.allocator.mem] as indicated:

   >     Tp* allocate(size_t n);

   > > -1- Effects: If `SIZE_MAX / sizeof(Tp) < n`, throws `length_error`. Otherwise E equivalent to:

   > > >     return static_cast<Tp*>(memory_rsrc->allocate(n * sizeof(Tp), alignof(Tp)));