Skip to content

Commit 93d5d27

Browse files
committed
fix(linux): pass the sealing key to ns-bundle via the environment
argv is readable by every local user in /proc/<pid>/cmdline; tools without $NS_BUNDLE_KEY_HEX support still get --key-hex.
1 parent 35100cf commit 93d5d27

2 files changed

Lines changed: 48 additions & 8 deletions

File tree

‎lib/services/linux-app-bundle.ts‎

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,23 @@ export class LinuxAppBundler {
9494
args.push("--unpack", glob);
9595
}
9696
}
97+
let env: NodeJS.ProcessEnv | undefined;
9798
if (seal) {
9899
args.push("--seal");
99100
if (options.keyHex) {
100-
args.push("--key-hex", options.keyHex);
101+
// argv is readable by every local user; older tools only take --key-hex
102+
if (await this.readsKeyFromEnv(tool, stage)) {
103+
env = { ...process.env, NS_BUNDLE_KEY_HEX: options.keyHex };
104+
} else {
105+
args.push("--key-hex", options.keyHex);
106+
}
101107
}
102108
}
103109
args.push(...fuseArgs(true));
104110
// the tool only patches the executable once the bundle is written
105111
const pristine = fs.readFileSync(executable);
106112
try {
107-
const result = await this.run(tool, args, stage);
113+
const result = await this.run(tool, args, stage, env);
108114
this.$logger.info(result.stdout.trim());
109115
} catch (e) {
110116
for (const p of [output, unpacked]) {
@@ -128,12 +134,26 @@ export class LinuxAppBundler {
128134
);
129135
}
130136

131-
private async run(command: string, args: string[], cwd: string) {
137+
private async readsKeyFromEnv(tool: string, cwd: string) {
138+
try {
139+
const help = await this.run(tool, ["--help"], cwd);
140+
return help.stdout.includes("NS_BUNDLE_KEY_HEX");
141+
} catch {
142+
return false;
143+
}
144+
}
145+
146+
private async run(
147+
command: string,
148+
args: string[],
149+
cwd: string,
150+
env?: NodeJS.ProcessEnv,
151+
) {
132152
const result = await this.$childProcess.spawnFromEvent(
133153
command,
134154
args,
135155
"close",
136-
{ cwd },
156+
env ? { cwd, env } : { cwd },
137157
{ throwError: false },
138158
);
139159
if (result.exitCode !== 0) {

‎test/services/linux-app-bundle.ts‎

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,24 @@ import { LinuxAppBundler } from "../../lib/services/linux-app-bundle";
66
import * as stubs from "../stubs";
77

88
/** Fakes ns-bundle: `pack` writes the bundle and patches the executable. */
9-
function fakeTool(exitCode = 0) {
9+
function fakeTool(exitCode = 0, keyFromEnv = true) {
1010
const calls: string[][] = [];
11+
const envs: (NodeJS.ProcessEnv | undefined)[] = [];
1112
return {
1213
calls,
13-
spawnFromEvent: async (_command: string, args: string[]) => {
14+
envs,
15+
spawnFromEvent: async (
16+
_command: string,
17+
args: string[],
18+
_event: string,
19+
options: { env?: NodeJS.ProcessEnv },
20+
) => {
21+
if (args[0] === "--help") {
22+
const stdout = keyFromEnv ? "usage ... $NS_BUNDLE_KEY_HEX" : "usage";
23+
return { exitCode: 0, stdout, stderr: "" };
24+
}
1425
calls.push(args);
26+
envs.push(options?.env);
1527
if (exitCode === 0 && args[0] === "pack") {
1628
const output = args[args.indexOf("--output") + 1];
1729
fs.writeFileSync(output, "NSB2");
@@ -83,12 +95,20 @@ describe("linuxAppBundle", () => {
8395
const [args] = proc.calls;
8496
assert.includeMembers(args, [
8597
"--seal",
86-
"--key-hex",
87-
"ab".repeat(32),
8898
"--no-default-unpack",
8999
"data/**",
90100
"inspector=on",
91101
]);
102+
// not on argv, where other local users can read it
103+
assert.notInclude(args, "ab".repeat(32));
104+
assert.equal(proc.envs[0].NS_BUNDLE_KEY_HEX, "ab".repeat(32));
105+
});
106+
107+
it("passes the key on argv to tools without NS_BUNDLE_KEY_HEX", async () => {
108+
const proc = fakeTool(0, false);
109+
await pack(proc, { sourceProtect: true, keyHex: "cd".repeat(32) });
110+
assert.includeMembers(proc.calls[0], ["--key-hex", "cd".repeat(32)]);
111+
assert.isUndefined(proc.envs[0]);
92112
});
93113

94114
it("only sets fuses with bundle: false", async () => {

0 commit comments

Comments
 (0)