<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3038: polymorphic_allocator::allocate should not allow integer overflow to create vulnerabilities</title>
<meta property="og:title" content="Issue 3038: polymorphic_allocator::allocate should not allow integer overflow to create vulnerabilities">
<meta property="og:description" content="C++ library issue. Status: C++20">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3038.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++20">C++20</a> status.</em></p>
<h3 id="3038"><a href="lwg-defects.html#3038">3038</a>. <code>polymorphic_allocator::allocate</code> should not allow integer overflow to create vulnerabilities</h3>
<p><b>Section:</b> 20.5.3.3 <a href="https://wg21.link/mem.poly.allocator.mem">[mem.poly.allocator.mem]</a> <b>Status:</b> <a href="lwg-active.html#C++20">C++20</a>
 <b>Submitter:</b> Billy O'Neal III <b>Opened:</b> 2017-11-16 <b>Last modified:</b> 2021-02-25</p>
<p><b>Priority: </b>2
</p>
<p><b>View all other</b> <a href="lwg-index.html#mem.poly.allocator.mem">issues</a> in [mem.poly.allocator.mem].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++20">C++20</a> status.</p>
<p><b>Discussion:</b></p>
<p>
At the moment <code>polymorphic_allocator</code> is specified to do <code>sizeof(T) * n</code> directly; this may allow an attacker 
to cause this calculation to overflow, resulting in <code>allocate()</code> not meeting its postcondition of returning a buffer 
suitable to store <code>n</code> copies of <code>T</code>; this is a common bug described in 
<a href="http://cwe.mitre.org/data/definitions/190.html">CWE-190</a>.
<p/>
Making this into a saturating multiply should be sufficient to avoid this problem; any <code>memory_resource</code> 
underneath <code>polymorphic_allocator</code> is going to have to throw <code>bad_alloc</code> (or another exception) for a request 
of <code>SIZE_MAX</code>.
<p/>
(There's also a minor editorial thing here that <i>Returns</i> should be <i>Effects</i>)
</p>

<p><i>[2018-06 Rapperswil Thursday issues processing]</i></p>

<p>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.</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>
Wording relative to <a href="https://wg21.link/n4700">N4700</a>.
</p>

<ol>
<li>
<p>
Edit 20.5.3.3 <a href="https://wg21.link/mem.poly.allocator.mem">[mem.poly.allocator.mem]</a> as indicated:
</p>
<blockquote>
<pre>
Tp* allocate(size_t n);
</pre>
<blockquote>
<p>
-1- <i><del>Returns</del><ins>Effects</ins>:</i> Equivalent to
</p>
<blockquote>
<pre>
return static_cast&lt;Tp*&gt;(memory_rsrc-&gt;allocate(<ins>SIZE_MAX / sizeof(Tp) &lt; n ? SIZE_MAX :</ins> n * sizeof(Tp), alignof(Tp)));
</pre>
</blockquote>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2018-08-23 Batavia Issues processing]</i></p>

<p>Status to Tentatively Ready with updated wording</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>
Wording relative to <a href="https://wg21.link/n4762">N4762</a>.
</p>

<ol>
<li>
<p>
Edit 20.5.3.3 <a href="https://wg21.link/mem.poly.allocator.mem">[mem.poly.allocator.mem]</a> as indicated:
</p>
<blockquote>
<pre>
Tp* allocate(size_t n);
</pre>
<blockquote>
<p>
-1- <i>Effects: </i><ins>If <code>SIZE_MAX / sizeof(Tp) &lt; n</code>, throws <code>length_error</code>, then</ins> <del>E</del><ins>e</ins>quivalent to:
</p>
<blockquote>
<pre>
return static_cast&lt;Tp*&gt;(memory_rsrc-&gt;allocate(n * sizeof(Tp), alignof(Tp)));
</pre>
</blockquote>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>


<p><i>[2018-11, Adopted in San Diego]</i></p>



<p id="res-3038"><b>Proposed resolution:</b></p>
<p>
Wording relative to <a href="https://wg21.link/n4762">N4762</a>.
</p>

<ol>
<li>
<p>
Edit 20.5.3.3 <a href="https://wg21.link/mem.poly.allocator.mem">[mem.poly.allocator.mem]</a> as indicated:
</p>
<blockquote>
<pre>
Tp* allocate(size_t n);
</pre>
<blockquote>
<p>
-1- <i>Effects: </i><ins>If <code>SIZE_MAX / sizeof(Tp) &lt; n</code>, throws <code>length_error</code>. Otherwise</ins> <del>E</del><ins>e</ins>quivalent to:
</p>
<blockquote>
<pre>
return static_cast&lt;Tp*&gt;(memory_rsrc-&gt;allocate(n * sizeof(Tp), alignof(Tp)));
</pre>
</blockquote>
</blockquote>
</blockquote>
</li>
</ol>





</body>
</html>
