Skip to content

Commit 154d53c

Browse files
fix(state): gateway starts when WSL chmod returns EROFS (#108258)
* fix(state): tolerate guarded EROFS chmod failures * fix(state): keep EROFS mode handling fail-closed --------- Co-authored-by: Peter Steinberger <[email protected]> Co-authored-by: Peter Steinberger <[email protected]>
1 parent 5c97107 commit 154d53c

2 files changed

Lines changed: 26 additions & 0 deletions

File tree

src/infra/private-mode.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ function canIgnorePrivateChmodError(target: string, code: string | undefined): b
4141
if (code && CHMOD_UNSUPPORTED_CODES.has(code)) {
4242
return true;
4343
}
44+
if (code === "EROFS") {
45+
// WSL can report EROFS for chmod on an already-private path. Never waive
46+
// broad permissions for this anomalous code.
47+
return hasRestrictivePermissions(target);
48+
}
4449
if (code !== "EPERM") {
4550
return false;
4651
}

src/state/openclaw-state-db.permissions.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,27 @@ describe("state database permission hardening without chmod support", () => {
9393
expect(database.db.isOpen).toBe(true);
9494
});
9595

96+
it("opens when EROFS leaves existing permissions restrictive", () => {
97+
stateDir = fs.mkdtempSync(join(tmpdir(), "openclaw-state-chmod-"));
98+
openOpenClawStateDatabase({ env: { OPENCLAW_STATE_DIR: stateDir } });
99+
closeOpenClawStateDatabaseForTest();
100+
chmodFailHook.error = chmodError("EROFS");
101+
102+
const database = openOpenClawStateDatabase({ env: { OPENCLAW_STATE_DIR: stateDir } });
103+
104+
expect(database.db.isOpen).toBe(true);
105+
});
106+
107+
it("rethrows EROFS when existing permissions are too broad", () => {
108+
stateDir = fs.mkdtempSync(join(tmpdir(), "openclaw-state-chmod-"));
109+
fs.chmodSync(stateDir, 0o755);
110+
chmodFailHook.error = chmodError("EROFS");
111+
112+
expect(() => openOpenClawStateDatabase({ env: { OPENCLAW_STATE_DIR: stateDir } })).toThrow(
113+
/EROFS/,
114+
);
115+
});
116+
96117
it("opens when the filesystem probe also rejects chmod with EPERM", () => {
97118
stateDir = fs.mkdtempSync(join(tmpdir(), "openclaw-state-chmod-"));
98119
fs.chmodSync(stateDir, 0o755);

0 commit comments

Comments
 (0)