From 767b86a1e1710ee2067d9ab59bfda0911eeb1ea5 Mon Sep 17 00:00:00 2001 From: Bill Ticehurst Date: Wed, 18 Apr 2018 11:55:35 -0700 Subject: [PATCH 1/2] test: add test for loading read-only modules Adds a test-case to cover loading modules the user does not have permission to write to. Covers issue logged in #20112 --- test/parallel/test-module-readonly.js | 46 +++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 test/parallel/test-module-readonly.js diff --git a/test/parallel/test-module-readonly.js b/test/parallel/test-module-readonly.js new file mode 100644 index 00000000000000..d41ebdcc0ca7bd --- /dev/null +++ b/test/parallel/test-module-readonly.js @@ -0,0 +1,46 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); +const cp = require('child_process'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +if (common.isWindows) { + // Create readOnlyMod.js and set to read only + const readOnlyMod = path.join(tmpdir.path, 'readOnlyMod'); + const readOnlyModRelative = path.relative(__dirname, readOnlyMod); + const readOnlyModFullPath = readOnlyMod + '.js'; + + fs.writeFileSync(readOnlyModFullPath, 'module.exports = 42;'); + // Removed any inherited ACEs, and any explicitly granted ACEs for the + // current user + cp.execSync('icacls.exe "' + readOnlyModFullPath + + '" /inheritance:r /remove "%USERNAME%"'); + + // Grant the current user read & execute only + cp.execSync('icacls.exe "' + readOnlyModFullPath + + '" /grant "%USERNAME%":RX'); + + let except = null; + try { + // Attempt to load the module. Will fail if write access is required + require(readOnlyModRelative); + } catch (err) { + except = err; + } + + // Remove the expliclty granted rights, and reenable inheritance + cp.execSync('icacls.exe "' + readOnlyModFullPath + + '" /remove "%USERNAME%" /inheritance:e'); + // Delete the test module (note: tmpdir should get cleaned anyway) + fs.unlinkSync(readOnlyModFullPath); + + assert.ifError(except); +} else { + // TODO: Similar checks on *nix-like systems (e.g using chmod or the like) + common.skip('test only runs on Windows'); +} From ccab982a6d3e951c7eeb0186d20a1379cfe0952e Mon Sep 17 00:00:00 2001 From: Bill Ticehurst Date: Wed, 18 Apr 2018 13:54:25 -0700 Subject: [PATCH 2/2] test: updated formatting per feedback --- test/parallel/test-module-readonly.js | 70 ++++++++++++++------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/test/parallel/test-module-readonly.js b/test/parallel/test-module-readonly.js index d41ebdcc0ca7bd..fa12471a37c31b 100644 --- a/test/parallel/test-module-readonly.js +++ b/test/parallel/test-module-readonly.js @@ -1,6 +1,12 @@ 'use strict'; const common = require('../common'); + +if (!common.isWindows) { + // TODO: Similar checks on *nix-like systems (e.g using chmod or the like) + common.skip('test only runs on Windows'); +} + const assert = require('assert'); const fs = require('fs'); const path = require('path'); @@ -9,38 +15,34 @@ const cp = require('child_process'); const tmpdir = require('../common/tmpdir'); tmpdir.refresh(); -if (common.isWindows) { - // Create readOnlyMod.js and set to read only - const readOnlyMod = path.join(tmpdir.path, 'readOnlyMod'); - const readOnlyModRelative = path.relative(__dirname, readOnlyMod); - const readOnlyModFullPath = readOnlyMod + '.js'; - - fs.writeFileSync(readOnlyModFullPath, 'module.exports = 42;'); - // Removed any inherited ACEs, and any explicitly granted ACEs for the - // current user - cp.execSync('icacls.exe "' + readOnlyModFullPath + - '" /inheritance:r /remove "%USERNAME%"'); - - // Grant the current user read & execute only - cp.execSync('icacls.exe "' + readOnlyModFullPath + - '" /grant "%USERNAME%":RX'); - - let except = null; - try { - // Attempt to load the module. Will fail if write access is required - require(readOnlyModRelative); - } catch (err) { - except = err; - } - - // Remove the expliclty granted rights, and reenable inheritance - cp.execSync('icacls.exe "' + readOnlyModFullPath + - '" /remove "%USERNAME%" /inheritance:e'); - // Delete the test module (note: tmpdir should get cleaned anyway) - fs.unlinkSync(readOnlyModFullPath); - - assert.ifError(except); -} else { - // TODO: Similar checks on *nix-like systems (e.g using chmod or the like) - common.skip('test only runs on Windows'); +// Create readOnlyMod.js and set to read only +const readOnlyMod = path.join(tmpdir.path, 'readOnlyMod'); +const readOnlyModRelative = path.relative(__dirname, readOnlyMod); +const readOnlyModFullPath = `${readOnlyMod}.js`; + +fs.writeFileSync(readOnlyModFullPath, 'module.exports = 42;'); + +// Removed any inherited ACEs, and any explicitly granted ACEs for the +// current user +cp.execSync( + `icacls.exe "${readOnlyModFullPath}" /inheritance:r /remove "%USERNAME%"`); + +// Grant the current user read & execute only +cp.execSync(`icacls.exe "${readOnlyModFullPath}" /grant "%USERNAME%":RX`); + +let except = null; +try { + // Attempt to load the module. Will fail if write access is required + require(readOnlyModRelative); +} catch (err) { + except = err; } + +// Remove the expliclty granted rights, and reenable inheritance +cp.execSync( + `icacls.exe "${readOnlyModFullPath}" /remove "%USERNAME%" /inheritance:e`); + +// Delete the test module (note: tmpdir should get cleaned anyway) +fs.unlinkSync(readOnlyModFullPath); + +assert.ifError(except);