Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: guard inspector console using process var #15008

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/internal/bootstrap_node.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,10 +327,10 @@
}

function setupInspector(originalConsole, wrappedConsole, Module) {
const { addCommandLineAPI, consoleCall } = process.binding('inspector');
if (!consoleCall) {
if (!process.config.variables.v8_enable_inspector) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depending on process.config is dangerous because there are userland modules that completely replace it. During bootstrap it should be safe but problems still could come up.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it ever becomes an issue, we could cache it before user code runs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or use process.binding('config') as a stable alternative.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jasnell @cjihrig Thanks, I had not thought about that being an issue and I'm trying to understand how this might happen.

Using process.binding('config') will give access to the builtin module config, but as far as I can tell the information from config.gypi is provided as a native module (via node_js2c). The process object is then configured with that information in setupConfig which is called by node_bootstrap.js start function.

setupConfig deletes the config from the _source and then sets these properties on the process object. Since it deletes the _source this function cannot be called multiple times, for example if it did not we could have done the same thing again.

What I'm having some difficulties understand is that how could a userland module be able to replace this at this stage. Would someone be able to shed some light on this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Userland code might not be able to replace process.config by this stage, I haven't tested it. What I do know is that we've had issues depending on process.config in later stages elsewhere in the code and we if we are going to use it here then we need to be certain that it won't be a problem. If there is no userland code that can be run before bootstrap gets to this point, then it should be ok.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still very early in the bootstrap process and I do not think it is possible to change it at that stage. To be on the safe side we could just add a test for it though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jasnell @BridgeAR Sounds good, I'll add a test for this. Thanks

return;
}
const { addCommandLineAPI, consoleCall } = process.binding('inspector');
// Setup inspector command line API
const { makeRequireFunction } = NativeModule.require('internal/module');
const path = NativeModule.require('path');
Expand Down
5 changes: 5 additions & 0 deletions test/fixtures/overwrite-config-preload-module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict'
const common = require('../common');
common.skipIfInspectorDisabled();

process.config = {};
41 changes: 41 additions & 0 deletions test/sequential/test-inspector-overwrite-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Flags: --require ./test/fixtures/overwrite-config-preload-module.js
'use strict';

// This test ensures that overwriting a process configuration
// value does not affect code in bootstrap_node.js. Specifically this tests
// that the inspector console functions are bound even though
// overwrite-config-preload-module.js overwrote the process.config variable.

// We cannot do a check for the inspector because the configuration variables
// were reset/removed by overwrite-config-preload-module.js.
/* eslint-disable inspector-check */

const common = require('../common');
const assert = require('assert');
const inspector = require('inspector');
const msg = 'Test inspector logging';
let asserted = false;

async function testConsoleLog() {
const session = new inspector.Session();
session.connect();
session.on('inspectorNotification', (data) => {
if (data.method === 'Runtime.consoleAPICalled') {
assert.strictEqual(data.params.args.length, 1);
assert.strictEqual(data.params.args[0].value, msg);
asserted = true;
}
});
session.post('Runtime.enable');
console.log(msg);
session.disconnect();
}

common.crashOnUnhandledRejection();

async function runTests() {
await testConsoleLog();
assert.ok(asserted, 'log statement did not reach the inspector');
}

runTests();