mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-07 22:44:16 +00:00
fix(doctor): skip false positive permission warnings for Nix store symlinks (#24901)
On NixOS/Nix-managed installs, config and state directories are symlinks into /nix/store/. Symlinks on Linux always report 0o777 via lstatSync, causing `openclaw doctor` to incorrectly warn about open permissions. Use lstatSync to detect symlinks, resolve the target, and only suppress the warning when the resolved path lives in /nix/store/ (an immutable filesystem). Symlinks to insecure targets still trigger warnings. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -261,8 +261,15 @@ export async function noteStateIntegrity(
|
||||
}
|
||||
if (stateDirExists && process.platform !== "win32") {
|
||||
try {
|
||||
const stat = fs.statSync(stateDir);
|
||||
if ((stat.mode & 0o077) !== 0) {
|
||||
const dirLstat = fs.lstatSync(stateDir);
|
||||
const isDirSymlink = dirLstat.isSymbolicLink();
|
||||
// For symlinks, check the resolved target permissions instead of the
|
||||
// symlink itself (which always reports 777). Skip the warning only when
|
||||
// the target lives in a known immutable store (e.g. /nix/store/).
|
||||
const stat = isDirSymlink ? fs.statSync(stateDir) : dirLstat;
|
||||
const resolvedDir = isDirSymlink ? fs.realpathSync(stateDir) : stateDir;
|
||||
const isImmutableStore = resolvedDir.startsWith("/nix/store/");
|
||||
if (!isImmutableStore && (stat.mode & 0o077) !== 0) {
|
||||
warnings.push(
|
||||
`- State directory permissions are too open (${displayStateDir}). Recommend chmod 700.`,
|
||||
);
|
||||
@@ -282,10 +289,14 @@ export async function noteStateIntegrity(
|
||||
|
||||
if (configPath && existsFile(configPath) && process.platform !== "win32") {
|
||||
try {
|
||||
const linkStat = fs.lstatSync(configPath);
|
||||
const stat = fs.statSync(configPath);
|
||||
const isSymlink = linkStat.isSymbolicLink();
|
||||
if (!isSymlink && (stat.mode & 0o077) !== 0) {
|
||||
const configLstat = fs.lstatSync(configPath);
|
||||
const isSymlink = configLstat.isSymbolicLink();
|
||||
// For symlinks, check the resolved target permissions. Skip the warning
|
||||
// only when the target lives in an immutable store (e.g. /nix/store/).
|
||||
const stat = isSymlink ? fs.statSync(configPath) : configLstat;
|
||||
const resolvedConfig = isSymlink ? fs.realpathSync(configPath) : configPath;
|
||||
const isImmutableConfig = resolvedConfig.startsWith("/nix/store/");
|
||||
if (!isImmutableConfig && (stat.mode & 0o077) !== 0) {
|
||||
warnings.push(
|
||||
`- Config file is group/world readable (${displayConfigPath ?? configPath}). Recommend chmod 600.`,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user