File CVE-2020-11080.patch of Package nodejs8.15384

commit 881c244a4e1b857d883cd105cd035a1fd6ed3fa6
Author: James M Snell <jasnell@gmail.com>
Date:   Mon Apr 27 10:47:58 2020 -0700

    http2: implement support for max settings entries
    
    Adds the maxSettings option to limit the number of settings
    entries allowed per SETTINGS frame. Default 32
    
    Signed-off-by: James M Snell <jasnell@gmail.com>
    
    Fixes: https://hackerone.com/reports/446662
    CVE-ID: CVE-2020-11080
    PR-URL: https://github.com/nodejs-private/node-private/pull/204
    Backport-PR-URL: https://github.com/nodejs-private/node-private/pull/207
    Reviewed-By: Beth Griggs <Bethany.Griggs@uk.ibm.com>
    Reviewed-By: Sam Roberts <vieuxtech@gmail.com>

Index: node-v8.17.0/doc/api/http2.md
===================================================================
--- node-v8.17.0.orig/doc/api/http2.md
+++ node-v8.17.0/doc/api/http2.md
@@ -1885,6 +1885,9 @@ error will be thrown.
 <!-- YAML
 added: v8.4.0
 changes:
+  - version: REPLACEME
+    pr-url: https://github.com/nodejs-private/node-private/pull/204
+    description: Added `maxSettings` option with a default of 32.
   - version: v8.9.3
     pr-url: https://github.com/nodejs/node/pull/17105
     description: Added the `maxOutstandingPings` option with a default limit of
@@ -1902,6 +1905,8 @@ changes:
 * `options` {Object}
   * `maxDeflateDynamicTableSize` {number} Sets the maximum dynamic table size
     for deflating header fields. **Default:** `4Kib`.
+  * `maxSettings` {number} Sets the maximum number of settings entries per
+    `SETTINGS` frame. The minimum value allowed is `1`. **Default:** `32`.
   * `maxSessionMemory`{number} Sets the maximum memory that the `Http2Session`
     is permitted to use. The value is expressed in terms of number of megabytes,
     e.g. `1` equal 1 megabyte. The minimum value allowed is `1`.
@@ -1995,6 +2000,9 @@ server.listen(80);
 <!-- YAML
 added: v8.4.0
 changes:
+  - version: REPLACEME
+    pr-url: https://github.com/nodejs-private/node-private/pull/204
+    description: Added `maxSettings` option with a default of 32.
   - version: v8.13.0
     pr-url: https://github.com/nodejs/node/pull/22956
     description: Added the `origins` option to automatically send an `ORIGIN`
@@ -2016,6 +2024,8 @@ changes:
     **Default:** `false`.
   * `maxDeflateDynamicTableSize` {number} Sets the maximum dynamic table size
     for deflating header fields. **Default:** `4Kib`.
+  * `maxSettings` {number} Sets the maximum number of settings entries per
+    `SETTINGS` frame. The minimum value allowed is `1`. **Default:** `32`.
   * `maxSessionMemory`{number} Sets the maximum memory that the `Http2Session`
     is permitted to use. The value is expressed in terms of number of megabytes,
     e.g. `1` equal 1 megabyte. The minimum value allowed is `1`. This is a
@@ -2097,6 +2107,9 @@ server.listen(80);
 <!-- YAML
 added: v8.4.0
 changes:
+  - version: REPLACEME
+    pr-url: https://github.com/nodejs-private/node-private/pull/204
+    description: Added `maxSettings` option with a default of 32.
   - version: v8.9.3
     pr-url: https://github.com/nodejs/node/pull/17105
     description: Added the `maxOutstandingPings` option with a default limit of
@@ -2111,6 +2124,8 @@ changes:
 * `options` {Object}
   * `maxDeflateDynamicTableSize` {number} Sets the maximum dynamic table size
     for deflating header fields. **Default:** `4Kib`.
+  * `maxSettings` {number} Sets the maximum number of settings entries per
+    `SETTINGS` frame. The minimum value allowed is `1`. **Default:** `32`.
   * `maxSessionMemory`{number} Sets the maximum memory that the `Http2Session`
     is permitted to use. The value is expressed in terms of number of megabytes,
     e.g. `1` equal 1 megabyte. The minimum value allowed is `1`.
Index: node-v8.17.0/lib/internal/http2/util.js
===================================================================
--- node-v8.17.0.orig/lib/internal/http2/util.js
+++ node-v8.17.0/lib/internal/http2/util.js
@@ -176,7 +176,8 @@ const IDX_OPTIONS_MAX_HEADER_LIST_PAIRS
 const IDX_OPTIONS_MAX_OUTSTANDING_PINGS = 6;
 const IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS = 7;
 const IDX_OPTIONS_MAX_SESSION_MEMORY = 8;
-const IDX_OPTIONS_FLAGS = 9;
+const IDX_OPTIONS_MAX_SETTINGS = 9;
+const IDX_OPTIONS_FLAGS = 10;
 
 function updateOptionsBuffer(options) {
   var flags = 0;
@@ -225,6 +226,11 @@ function updateOptionsBuffer(options) {
     optionsBuffer[IDX_OPTIONS_MAX_SESSION_MEMORY] =
       Math.max(1, options.maxSessionMemory);
   }
+  if (typeof options.maxSettings === 'number') {
+    flags |= (1 << IDX_OPTIONS_MAX_SETTINGS);
+    optionsBuffer[IDX_OPTIONS_MAX_SETTINGS] =
+      Math.max(1, options.maxSettings);
+  }
   optionsBuffer[IDX_OPTIONS_FLAGS] = flags;
 }
 
Index: node-v8.17.0/src/node_http2.cc
===================================================================
--- node-v8.17.0.orig/src/node_http2.cc
+++ node-v8.17.0/src/node_http2.cc
@@ -195,6 +195,12 @@ Http2Options::Http2Options(Environment*
   if (flags & (1 << IDX_OPTIONS_MAX_SESSION_MEMORY)) {
     SetMaxSessionMemory(buffer[IDX_OPTIONS_MAX_SESSION_MEMORY] * 1e6);
   }
+
+  if (flags & (1 << IDX_OPTIONS_MAX_SETTINGS)) {
+    nghttp2_option_set_max_settings(
+        options_,
+        static_cast<size_t>(buffer[IDX_OPTIONS_MAX_SETTINGS]));
+  }
 }
 
 void Http2Session::Http2Settings::Init() {
Index: node-v8.17.0/src/node_http2_state.h
===================================================================
--- node-v8.17.0.orig/src/node_http2_state.h
+++ node-v8.17.0/src/node_http2_state.h
@@ -51,6 +51,7 @@ namespace http2 {
     IDX_OPTIONS_MAX_OUTSTANDING_PINGS,
     IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS,
     IDX_OPTIONS_MAX_SESSION_MEMORY,
+    IDX_OPTIONS_MAX_SETTINGS,
     IDX_OPTIONS_FLAGS
   };
 
Index: node-v8.17.0/test/parallel/test-http2-max-settings.js
===================================================================
--- /dev/null
+++ node-v8.17.0/test/parallel/test-http2-max-settings.js
@@ -0,0 +1,35 @@
+'use strict';
+
+const common = require('../common');
+if (!common.hasCrypto)
+  common.skip('missing crypto');
+
+const http2 = require('http2');
+
+const server = http2.createServer({ maxSettings: 1 });
+
+// TODO(@jasnell): There is still a session event
+// emitted on the server side but it will be destroyed
+// immediately after creation and there will be no
+// stream created.
+server.on('session', common.mustCall((session) => {
+  session.on('stream', common.mustNotCall());
+  session.on('remoteSettings', common.mustNotCall());
+}));
+server.on('stream', common.mustNotCall());
+
+server.listen(0, common.mustCall(() => {
+  // Specify two settings entries when a max of 1 is allowed.
+  // Connection should error immediately.
+  const client = http2.connect(
+    `http://localhost:${server.address().port}`, {
+      settings: {
+        // The actual settings values do not matter.
+        headerTableSize: 1000,
+        enablePush: false,
+      } });
+
+  client.on('error', common.mustCall(() => {
+    server.close();
+  }));
+}));
Index: node-v8.17.0/test/parallel/test-http2-util-update-options-buffer.js
===================================================================
--- node-v8.17.0.orig/test/parallel/test-http2-util-update-options-buffer.js
+++ node-v8.17.0/test/parallel/test-http2-util-update-options-buffer.js
@@ -21,7 +21,8 @@ const IDX_OPTIONS_MAX_HEADER_LIST_PAIRS
 const IDX_OPTIONS_MAX_OUTSTANDING_PINGS = 6;
 const IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS = 7;
 const IDX_OPTIONS_MAX_SESSION_MEMORY = 8;
-const IDX_OPTIONS_FLAGS = 9;
+const IDX_OPTIONS_MAX_SETTINGS = 9;
+const IDX_OPTIONS_FLAGS = 10;
 
 {
   updateOptionsBuffer({
@@ -33,7 +34,8 @@ const IDX_OPTIONS_FLAGS = 9;
     maxHeaderListPairs: 6,
     maxOutstandingPings: 7,
     maxOutstandingSettings: 8,
-    maxSessionMemory: 9
+    maxSessionMemory: 9,
+    maxSettings: 10,
   });
 
   strictEqual(optionsBuffer[IDX_OPTIONS_MAX_DEFLATE_DYNAMIC_TABLE_SIZE], 1);
@@ -45,6 +47,7 @@ const IDX_OPTIONS_FLAGS = 9;
   strictEqual(optionsBuffer[IDX_OPTIONS_MAX_OUTSTANDING_PINGS], 7);
   strictEqual(optionsBuffer[IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS], 8);
   strictEqual(optionsBuffer[IDX_OPTIONS_MAX_SESSION_MEMORY], 9);
+  strictEqual(optionsBuffer[IDX_OPTIONS_MAX_SETTINGS], 10);
 
   const flags = optionsBuffer[IDX_OPTIONS_FLAGS];
 
@@ -56,6 +59,7 @@ const IDX_OPTIONS_FLAGS = 9;
   ok(flags & (1 << IDX_OPTIONS_MAX_HEADER_LIST_PAIRS));
   ok(flags & (1 << IDX_OPTIONS_MAX_OUTSTANDING_PINGS));
   ok(flags & (1 << IDX_OPTIONS_MAX_OUTSTANDING_SETTINGS));
+  ok(flags & (1 << IDX_OPTIONS_MAX_SETTINGS));
 }
 
 {