1'use strict'; 2 3const common = require('../common'); 4const { spawn, spawnSync } = require('node:child_process'); 5const { createInterface } = require('node:readline'); 6const assert = require('node:assert'); 7 8if (!common.hasCrypto) 9 common.skip('missing crypto'); 10if (!common.isLinux) 11 common.skip('linux only'); 12if (common.isAsan) 13 common.skip('strace does not work well with address sanitizer builds'); 14if (spawnSync('strace').error !== undefined) { 15 common.skip('missing strace'); 16} 17 18{ 19 const allowedOpenCalls = new Set([ 20 '/etc/ssl/openssl.cnf', 21 ]); 22 const strace = spawn('strace', [ 23 '-f', '-ff', 24 '-e', 'trace=open,openat', 25 '-s', '512', 26 '-D', process.execPath, '-e', 'require("crypto")', 27 ]); 28 29 // stderr is the default for strace 30 const rl = createInterface({ input: strace.stderr }); 31 rl.on('line', (line) => { 32 if (!line.startsWith('open')) { 33 return; 34 } 35 36 const file = line.match(/"(.*?)"/)[1]; 37 // skip .so reading attempt 38 if (file.match(/.+\.so(\.?)/) !== null) { 39 return; 40 } 41 // skip /proc/* 42 if (file.match(/\/proc\/.+/) !== null) { 43 return; 44 } 45 46 assert(allowedOpenCalls.delete(file), `${file} is not in the list of allowed openat calls`); 47 }); 48 const debugOutput = []; 49 strace.stderr.setEncoding('utf8'); 50 strace.stderr.on('data', (chunk) => { 51 debugOutput.push(chunk.toString()); 52 }); 53 strace.on('error', common.mustNotCall()); 54 strace.on('exit', common.mustCall((code) => { 55 assert.strictEqual(code, 0, debugOutput); 56 const missingKeys = Array.from(allowedOpenCalls.keys()); 57 if (missingKeys.length) { 58 assert.fail(`The following openat call are missing: ${missingKeys.join(',')}`); 59 } 60 })); 61} 62