Files
nodejs4/max_header_size.patch
Adam Majer 57718cd79b * cli: add --max-http-header-size flag (max_header_size.patch)
+ add maxHeaderSize property (max_header_size.patch)
      (CVE-2018-12121.patch - CVE-2018-12121, bsc#1117626)
    + A timeout of 40 seconds now applies to servers receiving
      HTTP headers. This value can be adjusted with
      server.headersTimeout. Where headers are not completely
      received within this period, the socket is destroyed on
      the next received chunk. In conjunction with
      server.setTimeout(), this aids in protecting against
      excessive resource retention and possible Denial of Service.
      (CVE-2018-12122.patch - CVE-2018-12122, bsc#1117627)
      (CVE-2018-12116.patch - CVE-2018-12116, bsc#1117630)
    (CVE-2018-12123.patch - CVE-2018-12123, bnc#1117629)

OBS-URL: https://build.opensuse.org/package/show/devel:languages:nodejs/nodejs4?expand=0&rev=101
2019-01-09 14:07:18 +00:00

699 lines
23 KiB
Diff

Ported from:
From 59f83d689641d5030743ee4f3e453e754843e188 Mon Sep 17 00:00:00 2001
From: cjihrig <cjihrig@gmail.com>
Date: Thu, 29 Nov 2018 17:29:53 -0500
Subject: [PATCH] deps: cherry-pick http_parser_set_max_header_size
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit adds http_parser_set_max_header_size() to the
http-parser for overriding the compile time maximum HTTP
header size.
Backport-PR-URL: https://github.com/nodejs/node/pull/25173
PR-URL: https://github.com/nodejs/node/pull/24811
Fixes: https://github.com/nodejs/node/issues/24692
Refs: https://github.com/nodejs/http-parser/pull/453
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
From c0c4de71f0fb7b55804a9d2110dded0493fc7c3e Mon Sep 17 00:00:00 2001
From: cjihrig <cjihrig@gmail.com>
Date: Wed, 5 Dec 2018 19:59:12 -0500
Subject: [PATCH] http: add maxHeaderSize property
This commit exposes the value of --max-http-header-size
as a property of the http module.
Backport-PR-URL: https://github.com/nodejs/node/pull/25218
PR-URL: https://github.com/nodejs/node/pull/24860
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Shelley Vohr <codebytere@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
From f233b160c9b8d5126b4e4845d1661c718d14d39f Mon Sep 17 00:00:00 2001
From: cjihrig <cjihrig@gmail.com>
Date: Mon, 3 Dec 2018 12:27:46 -0500
Subject: [PATCH] cli: add --max-http-header-size flag
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Allow the maximum size of HTTP headers to be overridden from
the command line.
Backport-PR-URL: https://github.com/nodejs/node/pull/25173
co-authored-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs/node/pull/24811
Fixes: https://github.com/nodejs/node/issues/24692
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
From 8a3e0c069747cb6a7e1889de92304856224fee72 Mon Sep 17 00:00:00 2001
From: Matteo Collina <hello@matteocollina.com>
Date: Fri, 14 Dec 2018 12:30:01 +0100
Subject: [PATCH] http: fix regression of binary upgrade response body
See: https://github.com/nodejs/node/issues/24958
PR-URL: https://github.com/nodejs/node/pull/25036
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Index: node-v4.9.1/deps/http_parser/http_parser.c
===================================================================
--- node-v4.9.1.orig/deps/http_parser/http_parser.c
+++ node-v4.9.1/deps/http_parser/http_parser.c
@@ -25,6 +25,8 @@
#include <string.h>
#include <limits.h>
+static uint32_t max_header_size = HTTP_MAX_HEADER_SIZE;
+
#ifndef ULLONG_MAX
# define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */
#endif
@@ -137,20 +139,20 @@ do {
} while (0)
/* Don't allow the total size of the HTTP headers (including the status
- * line) to exceed HTTP_MAX_HEADER_SIZE. This check is here to protect
+ * line) to exceed max_header_size. This check is here to protect
* embedders against denial-of-service attacks where the attacker feeds
* us a never-ending header that the embedder keeps buffering.
*
* This check is arguably the responsibility of embedders but we're doing
* it on the embedder's behalf because most won't bother and this way we
- * make the web a little safer. HTTP_MAX_HEADER_SIZE is still far bigger
+ * make the web a little safer. max_header_size is still far bigger
* than any reasonable request or response so this should never affect
* day-to-day operation.
*/
#define COUNT_HEADER_SIZE(V) \
do { \
parser->nread += (V); \
- if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) { \
+ if (UNLIKELY(parser->nread > max_header_size)) { \
SET_ERRNO(HPE_HEADER_OVERFLOW); \
goto error; \
} \
@@ -1471,7 +1473,7 @@ reexecute:
const char* p_lf;
size_t limit = data + len - p;
- limit = MIN(limit, HTTP_MAX_HEADER_SIZE);
+ limit = MIN(limit, max_header_size);
p_cr = (const char*) memchr(p, CR, limit);
p_lf = (const char*) memchr(p, LF, limit);
@@ -2438,3 +2440,8 @@ http_parser_version(void) {
HTTP_PARSER_VERSION_MINOR * 0x00100 |
HTTP_PARSER_VERSION_PATCH * 0x00001;
}
+
+void
+http_parser_set_max_header_size(uint32_t size) {
+ max_header_size = size;
+}
Index: node-v4.9.1/deps/http_parser/http_parser.h
===================================================================
--- node-v4.9.1.orig/deps/http_parser/http_parser.h
+++ node-v4.9.1/deps/http_parser/http_parser.h
@@ -427,6 +427,9 @@ void http_parser_pause(http_parser *pars
/* Checks if this is the final chunk of the body. */
int http_body_is_final(const http_parser *parser);
+/* Change the maximum header size provided at compile time. */
+void http_parser_set_max_header_size(uint32_t size);
+
#ifdef __cplusplus
}
#endif
Index: node-v4.9.1/doc/api/http.md
===================================================================
--- node-v4.9.1.orig/doc/api/http.md
+++ node-v4.9.1/doc/api/http.md
@@ -1330,6 +1330,16 @@ added: v0.5.9
Global instance of Agent which is used as the default for all http client
requests.
+## http.maxHeaderSize
+<!-- YAML
+added: REPLACEME
+-->
+
+* {number}
+
+Read-only property specifying the maximum allowed size of HTTP headers in bytes.
+Defaults to 8KB. Configurable using the [`--max-http-header-size`][] CLI option.
+
## http.request(options[, callback])
<!-- YAML
added: v0.3.6
@@ -1439,6 +1449,7 @@ There are a few special headers that sho
* Sending an Authorization header will override using the `auth` option
to compute basic authentication.
+[`--max-http-header-size`]: cli.html#cli_max_http_header_size_size
[`'checkContinue'`]: #http_event_checkcontinue
[`'listening'`]: net.html#net_event_listening
[`'response'`]: #http_event_response
Index: node-v4.9.1/lib/http.js
===================================================================
--- node-v4.9.1.orig/lib/http.js
+++ node-v4.9.1/lib/http.js
@@ -19,6 +19,8 @@ const server = require('_http_server');
exports.ServerResponse = server.ServerResponse;
exports.STATUS_CODES = server.STATUS_CODES;
+let maxHeaderSize;
+
const agent = require('_http_agent');
const Agent = exports.Agent = agent.Agent;
@@ -92,8 +94,21 @@ Client.prototype.request = function(meth
return c;
};
+
exports.Client = internalUtil.deprecate(Client, 'http.Client is deprecated.');
exports.createClient = internalUtil.deprecate(function(port, host) {
return new Client(port, host);
}, 'http.createClient is deprecated. Use http.request instead.');
+
+Object.defineProperty(module.exports, 'maxHeaderSize', {
+ configurable: true,
+ enumerable: true,
+ get() {
+ if (maxHeaderSize === undefined) {
+ maxHeaderSize = process.binding('config').maxHTTPHeaderSize;
+ }
+
+ return maxHeaderSize;
+ }
+});
Index: node-v4.9.1/test/parallel/test-http-max-header-size.js
===================================================================
--- /dev/null
+++ node-v4.9.1/test/parallel/test-http-max-header-size.js
@@ -0,0 +1,11 @@
+'use strict';
+
+require('../common');
+const assert = require('assert');
+const spawnSync = require('child_process').spawnSync;
+const http = require('http');
+
+assert.strictEqual(http.maxHeaderSize, 8 * 1024);
+const child = spawnSync(process.execPath, ['--max-http-header-size=10', '-p',
+ 'require("http").maxHeaderSize']);
+assert.strictEqual(+child.stdout.toString().trim(), 10);
Index: node-v4.9.1/doc/api/cli.md
===================================================================
--- node-v4.9.1.orig/doc/api/cli.md
+++ node-v4.9.1/doc/api/cli.md
@@ -177,6 +177,12 @@ added: v0.11.15
Specify ICU data load path. (overrides `NODE_ICU_DATA`)
+### `--max-http-header-size=size`
+<!-- YAML
+added: REPLACEME
+-->
+
+Specify the maximum size, in bytes, of HTTP headers. Defaults to 8KB.
## Environment Variables
Index: node-v4.9.1/doc/node.1
===================================================================
--- node-v4.9.1.orig/doc/node.1
+++ node-v4.9.1/doc/node.1
@@ -92,6 +92,10 @@ Preload the specified module at startup.
rules. \fImodule\fR may be either a path to a file, or a node module name.
.TP
+.BR \-\-max\-http\-header-size \fI=size\fR
+Specify the maximum size of HTTP headers in bytes. Defaults to 8KB.
+
+.TP
.BR \-\-no\-deprecation
Silence deprecation warnings.
Index: node-v4.9.1/src/node_config.cc
===================================================================
--- node-v4.9.1.orig/src/node_config.cc
+++ node-v4.9.1/src/node_config.cc
@@ -9,6 +9,7 @@ namespace node {
using v8::Context;
using v8::Local;
+using v8::Number;
using v8::Object;
using v8::Value;
using v8::ReadOnly;
@@ -25,13 +26,25 @@ using v8::ReadOnly;
True(env->isolate()), ReadOnly).FromJust(); \
} while (0)
+#define READONLY_PROPERTY(obj, name, value) \
+ do { \
+ obj->DefineOwnProperty(env->context(), \
+ FIXED_ONE_BYTE_STRING(env->isolate(), name), \
+ value, ReadOnly).FromJust(); \
+ } while (0)
+
void InitConfig(Local<Object> target,
Local<Value> unused,
Local<Context> context) {
-#ifdef NODE_FIPS_MODE
Environment* env = Environment::GetCurrent(context);
+#ifdef NODE_FIPS_MODE
READONLY_BOOLEAN_PROPERTY("fipsMode");
#endif
+
+ READONLY_PROPERTY(target,
+ "maxHTTPHeaderSize",
+ Number::New(env->isolate(), max_http_header_size));
+
}
} // namespace node
Index: node-v4.9.1/src/node_http_parser.cc
===================================================================
--- node-v4.9.1.orig/src/node_http_parser.cc
+++ node-v4.9.1/src/node_http_parser.cc
@@ -611,8 +611,6 @@ class Parser : public AsyncWrap {
size_t nparsed =
http_parser_execute(&parser_, &settings, data, len);
- enum http_errno err = HTTP_PARSER_ERRNO(&parser_);
-
Save();
// Unassign the 'buffer_' variable
@@ -627,7 +625,9 @@ class Parser : public AsyncWrap {
Local<Integer> nparsed_obj = Integer::New(env()->isolate(), nparsed);
// If there was a parse error in one of the callbacks
// TODO(bnoordhuis) What if there is an error on EOF?
- if ((!parser_.upgrade && nparsed != len) || err != HPE_OK) {
+ if (!parser_.upgrade && nparsed != len) {
+ enum http_errno err = HTTP_PARSER_ERRNO(&parser_);
+
Local<Value> e = Exception::Error(env()->parse_error_string());
Local<Object> obj = e->ToObject(env()->isolate());
obj->Set(env()->bytes_parsed_string(), nparsed_obj);
@@ -723,6 +723,9 @@ const struct http_parser_settings Parser
nullptr // on_chunk_complete
};
+void InitMaxHttpHeaderSizeOnce() {
+ http_parser_set_max_header_size(max_http_header_size);
+}
void InitHttpParser(Local<Object> target,
Local<Value> unused,
@@ -767,6 +770,8 @@ void InitHttpParser(Local<Object> target
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "HTTPParser"),
t->GetFunction());
+ static uv_once_t init_once = UV_ONCE_INIT;
+ uv_once(&init_once, InitMaxHttpHeaderSizeOnce);
}
} // namespace node
Index: node-v4.9.1/test/sequential/test-http-max-http-headers.js
===================================================================
--- node-v4.9.1.orig/test/sequential/test-http-max-http-headers.js
+++ node-v4.9.1/test/sequential/test-http-max-http-headers.js
@@ -1,10 +1,17 @@
'use strict';
+// Flags: --expose_internals
const assert = require('assert');
const common = require('../common');
const http = require('http');
const net = require('net');
-const MAX = 8 * 1024; // 8KB
+const MAX = +(process.argv[2] || 8 * 1024); // Command line option, or 8KB.
+
+assert(process.binding('config').maxHTTPHeaderSize,
+ 'The option should exist on process.binding(\'config\')');
+
+console.log('pid is', process.pid);
+console.log('max header size is', process.binding('config').maxHTTPHeaderSize);
// Verify that we cannot receive more than 8KB of headers.
@@ -28,19 +35,15 @@ function fillHeaders(headers, currentSiz
headers += 'a'.repeat(MAX - headers.length - 3);
// Generate valid headers
if (valid) {
- // TODO(mcollina): understand why -9 is needed instead of -1
- headers = headers.slice(0, -9);
+ // TODO(mcollina): understand why -32 is needed instead of -1
+ headers = headers.slice(0, -32);
}
return headers + '\r\n\r\n';
}
-const timeout = common.platformTimeout(10);
-
function writeHeaders(socket, headers) {
const array = [];
-
- // this is off from 1024 so that \r\n does not get split
- const chunkSize = 1000;
+ const chunkSize = 100;
let last = 0;
for (let i = 0; i < headers.length / chunkSize; i++) {
@@ -55,19 +58,25 @@ function writeHeaders(socket, headers) {
next();
function next() {
- if (socket.write(array.shift())) {
- if (array.length === 0) {
- socket.end();
- } else {
- setTimeout(next, timeout);
- }
+ if (socket.destroyed) {
+ console.log('socket was destroyed early, data left to write:',
+ array.join('').length);
+ return;
+ }
+
+ const chunk = array.shift();
+
+ if (chunk) {
+ console.log('writing chunk of size', chunk.length);
+ socket.write(chunk, next);
} else {
- socket.once('drain', next);
+ socket.end();
}
}
}
function test1() {
+ console.log('test1');
let headers =
'HTTP/1.1 200 OK\r\n' +
'Content-Length: 0\r\n' +
@@ -82,6 +91,9 @@ function test1() {
writeHeaders(sock, headers);
sock.resume();
});
+
+ // The socket might error but that's ok
+ sock.on('error', () => {});
});
server.listen(0, common.mustCall(() => {
@@ -90,17 +102,17 @@ function test1() {
client.on('error', common.mustCall((err) => {
assert.strictEqual(err.code, 'HPE_HEADER_OVERFLOW');
- server.close();
- setImmediate(test2);
+ server.close(test2);
}));
}));
}
const test2 = common.mustCall(() => {
+ console.log('test2');
let headers =
'GET / HTTP/1.1\r\n' +
'Host: localhost\r\n' +
- 'Agent: node\r\n' +
+ 'Agent: nod2\r\n' +
'X-CRASH: ';
// /, Host, localhost, Agent, node, X-CRASH, a...
@@ -109,7 +121,7 @@ const test2 = common.mustCall(() => {
const server = http.createServer(common.mustNotCall());
- server.on('clientError', common.mustCall((err) => {
+ server.once('clientError', common.mustCall((err) => {
assert.strictEqual(err.code, 'HPE_HEADER_OVERFLOW');
}));
@@ -121,34 +133,46 @@ const test2 = common.mustCall(() => {
});
finished(client, common.mustCall((err) => {
- server.close();
- setImmediate(test3);
+ server.close(test3);
}));
}));
});
const test3 = common.mustCall(() => {
+ console.log('test3');
let headers =
'GET / HTTP/1.1\r\n' +
'Host: localhost\r\n' +
- 'Agent: node\r\n' +
+ 'Agent: nod3\r\n' +
'X-CRASH: ';
// /, Host, localhost, Agent, node, X-CRASH, a...
const currentSize = 1 + 4 + 9 + 5 + 4 + 7;
headers = fillHeaders(headers, currentSize, true);
+ console.log('writing', headers.length);
+
const server = http.createServer(common.mustCall((req, res) => {
- res.end('hello world');
- setImmediate(server.close.bind(server));
+ res.end('hello from test3 server');
+ server.close();
}));
+ server.on('clientError', (err) => {
+ console.log(err.code);
+ if (err.code === 'HPE_HEADER_OVERFLOW') {
+ console.log(err.rawPacket.toString('hex'));
+ }
+ });
+ server.on('clientError', common.mustNotCall());
+
server.listen(0, common.mustCall(() => {
const client = net.connect(server.address().port);
client.on('connect', () => {
writeHeaders(client, headers);
client.resume();
});
+
+ client.pipe(process.stdout);
}));
});
Index: node-v4.9.1/test/sequential/test-set-http-max-http-headers.js
===================================================================
--- /dev/null
+++ node-v4.9.1/test/sequential/test-set-http-max-http-headers.js
@@ -0,0 +1,104 @@
+'use strict';
+
+const common = require('../common');
+const assert = require('assert');
+const spawn = require('child_process').spawn;
+const path = require('path');
+const testName = path.join(__dirname, 'test-http-max-http-headers.js');
+
+const timeout = common.platformTimeout(100);
+
+const tests = [];
+
+function test(fn) {
+ tests.push(fn);
+}
+
+test(function(cb) {
+ console.log('running subtest expecting failure');
+
+ // Validate that the test fails if the max header size is too small.
+ const args = ['--expose-internals',
+ '--max-http-header-size=1024',
+ testName];
+ const cp = spawn(process.execPath, args, { stdio: 'inherit' });
+
+ cp.on('close', common.mustCall((code, signal) => {
+ assert.strictEqual(code, 1);
+ assert.strictEqual(signal, null);
+ cb();
+ }));
+});
+
+test(function(cb) {
+ console.log('running subtest expecting success');
+
+ const env = Object.assign({}, process.env, {
+ NODE_DEBUG: 'http'
+ });
+
+ // Validate that the test fails if the max header size is too small.
+ // Validate that the test now passes if the same limit becomes large enough.
+ const args = ['--expose-internals',
+ '--max-http-header-size=1024',
+ testName,
+ '1024'];
+ const cp = spawn(process.execPath, args, {
+ env,
+ stdio: 'inherit'
+ });
+
+ cp.on('close', common.mustCall((code, signal) => {
+ assert.strictEqual(code, 0);
+ assert.strictEqual(signal, null);
+ cb();
+ }));
+});
+
+// Next, repeat the same checks using NODE_OPTIONS if it is supported.
+if (process.config.variables.node_without_node_options) {
+ const env = Object.assign({}, process.env, {
+ NODE_OPTIONS: '--max-http-header-size=1024'
+ });
+
+ test(function(cb) {
+ console.log('running subtest expecting failure');
+
+ // Validate that the test fails if the max header size is too small.
+ const args = ['--expose-internals', testName];
+ const cp = spawn(process.execPath, args, { env, stdio: 'inherit' });
+
+ cp.on('close', common.mustCall((code, signal) => {
+ assert.strictEqual(code, 1);
+ assert.strictEqual(signal, null);
+ cb();
+ }));
+ });
+
+ test(function(cb) {
+ // Validate that the test now passes if the same limit
+ // becomes large enough.
+ const args = ['--expose-internals', testName, '1024'];
+ const cp = spawn(process.execPath, args, { env, stdio: 'inherit' });
+
+ cp.on('close', common.mustCall((code, signal) => {
+ assert.strictEqual(code, 0);
+ assert.strictEqual(signal, null);
+ cb();
+ }));
+ });
+}
+
+function runTest() {
+ const fn = tests.shift();
+
+ if (!fn) {
+ return;
+ }
+
+ fn(() => {
+ setTimeout(runTest, timeout);
+ });
+}
+
+runTest();
Index: node-v4.9.1/src/node_internals.h
===================================================================
--- node-v4.9.1.orig/src/node_internals.h
+++ node-v4.9.1/src/node_internals.h
@@ -30,6 +30,9 @@ struct sockaddr;
namespace node {
+// Set in node.cc by ParseArgs when --max-http-header-size is used
+extern uint64_t max_http_header_size;
+
// Forward declaration
class Environment;
Index: node-v4.9.1/src/node.cc
===================================================================
--- node-v4.9.1.orig/src/node.cc
+++ node-v4.9.1/src/node.cc
@@ -161,6 +161,8 @@ unsigned int reverted = 0;
static const char* icu_data_dir = nullptr;
#endif
+uint64_t max_http_header_size = 8 * 1024;
+
// used by C++ modules as well
bool no_deprecation = false;
@@ -3409,6 +3411,8 @@ static void PrintHelp() {
" --trace-deprecation show stack traces on deprecations\n"
" --throw-deprecation throw an exception anytime a deprecated "
"function is used\n"
+ " --max-http-header-size Specify the maximum size of HTTP\n"
+ " headers in bytes. Defaults to 8KB.\n"
" --trace-sync-io show stack trace when use of sync IO\n"
" is detected after the first tick\n"
" --track-heap-objects track heap object allocations for heap "
@@ -3558,6 +3562,8 @@ static void ParseArgs(int* argc,
short_circuit = true;
} else if (strcmp(arg, "--zero-fill-buffers") == 0) {
zero_fill_all_buffers = true;
+ } else if (strncmp(arg, "--max-http-header-size=", 23) == 0) {
+ max_http_header_size = atoi(arg + 23);
} else if (strcmp(arg, "--v8-options") == 0) {
new_v8_argv[new_v8_argc] = "--help";
new_v8_argc += 1;
Index: node-v4.9.1/test/common.js
===================================================================
--- node-v4.9.1.orig/test/common.js
+++ node-v4.9.1/test/common.js
@@ -410,6 +410,26 @@ exports.mustCall = function(fn, expected
};
};
+exports.getCallSite = function getCallSite(top) {
+ const originalStackFormatter = Error.prepareStackTrace;
+ Error.prepareStackTrace = (err, stack) =>
+ `${stack[0].getFileName()}:${stack[0].getLineNumber()}`;
+ const err = new Error();
+ Error.captureStackTrace(err, top);
+ // with the V8 Error API, the stack is not formatted until it is accessed
+ err.stack;
+ Error.prepareStackTrace = originalStackFormatter;
+ return err.stack;
+};
+
+exports.mustNotCall = function(msg) {
+ const callSite = exports.getCallSite(exports.mustNotCall);
+ return function mustNotCall() {
+ assert.fail(
+ `${msg || 'function should not have been called'} at ${callSite}`);
+ };
+};
+
var etcServicesFileName = path.join('/etc', 'services');
if (exports.isWindows) {
etcServicesFileName = path.join(process.env.SystemRoot, 'System32', 'drivers',