spago
spago copied to clipboard
Spago hangs forever when run inside macOS sandbox
When running spago inside a sandboxed environment, spago seems to get stuck. Here's a repro script:
#!/usr/bin/env bash
echo entering TMP dir
cd $(mktemp -d)
echo "downloading spago to $PWD"
curl -L https://github.com/purescript/spago/releases/download/0.20.3/macOS.tar.gz -o spago.tar.gz
echo extracting spago
tar -xvzf spago.tar.gz
cat > profile.sb <<EOF
(version 1)
(allow default)
(deny network*)
(deny file*)
(allow file-read* (subpath "/System/Library"))
(allow file-read* (subpath "/usr/lib"))
(allow file-read* (subpath "/usr/bin"))
(allow file-write* (subpath "$PWD"))
EOF
echo written profile.sb:
cat ./profile.sb
echo running spago init:
/usr/bin/sandbox-exec -f ./profile.sb ./spago init
This downloads spago and then runs it without giving it access to anything but the local directory (more or less). When looking at the console, it looks like spago gets stuck in a (hot) infinite loop trying to read the metadata of /:
Any idea what may be causing this?
What's your macOS version?
In any case here's the implementation for getMetadata - I have no idea why this would get stuck in a loop since there should be fallbacks for every operation that could fail.
Maybe it's due to the fact that the location for the metadata file is assumed /? Though that's not possible, since the metadata is at metadataV1.json:
https://github.com/purescript/spago/blob/c465a41fb9939f883e083ac9ad5293aafe9cda4d/src/Spago/GlobalCache.hs#L99
A few things you could try:
- run spago with the
--very-verboseflag and post the log here, so we can see what it has to say about this - set the
$XDG_CACHE_HOMEto something inside the local dir (like.spago, but that should already be the current fallback), since that's what governs the location of Spago's global cache, which is where the metadata is put.
Hi, thanks for the quick reply! Looks like it's trying to create /, and probably failing, then retrying:
2021-07-14 19:20:47.340845: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.340865: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.340884: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.340903: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.340923: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.340942: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.340962: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.340982: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341000: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341019: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341038: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341057: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341076: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341102: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341122: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341141: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341314: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341338: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341360: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341380: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341418: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341438: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
2021-07-14 19:20:47.341457: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
^C2021-07-14 19:20:47.341476: [debug] Directory "/" does not exist, creating...
@(src/Spago/Prelude.hs:285:20)
@nmattia great, thanks for the log! It looks like the issue is this recursive call: https://github.com/purescript/spago/blob/c465a41fb9939f883e083ac9ad5293aafe9cda4d/src/Spago/Prelude.hs#L225
In usual conditions that walks up to the parent of the current directory and never fails in this terrible way because, well, / always exists.
I believe we could get out of this by checking that the argument of the recursive call is different from the current one, and killing the process if that's the case.
Though the user-side fix to keep Spago working is what I suggested above:
set the
$XDG_CACHE_HOMEto something inside the local dir, since that's what governs the location of Spago's global cache, which is where the metadata is put.
@nmattia have you tried my last suggestion?
@f-f I was on holiday, I just came back! I'll let you know as soon as I find some more time to play with Spago. Thanks for the help already!
I think we could add a simple check for takeDirectory directory == directory, and throw an error linking to this issue when that happens.
I think the new Spago can't hit this, so I'll close for now, but let's reopen if we figure out this is ever the case