spago icon indicating copy to clipboard operation
spago copied to clipboard

Spago hangs forever when run inside macOS sandbox

Open nmattia opened this issue 4 years ago • 7 comments

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 /:

Screenshot 2021-07-14 at 19 01 20

Any idea what may be causing this?

nmattia avatar Jul 14 '21 17:07 nmattia

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-verbose flag and post the log here, so we can see what it has to say about this
  • set the $XDG_CACHE_HOME to 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.

f-f avatar Jul 14 '21 18:07 f-f

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 avatar Jul 14 '21 19:07 nmattia

Screenshot 2021-07-14 at 21 22 21

nmattia avatar Jul 14 '21 19:07 nmattia

@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_HOME to something inside the local dir, since that's what governs the location of Spago's global cache, which is where the metadata is put.

f-f avatar Jul 14 '21 20:07 f-f

@nmattia have you tried my last suggestion?

f-f avatar Jul 20 '21 11:07 f-f

@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!

nmattia avatar Jul 26 '21 14:07 nmattia

I think we could add a simple check for takeDirectory directory == directory, and throw an error linking to this issue when that happens.

f-f avatar Dec 01 '21 14:12 f-f

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

f-f avatar Sep 20 '23 16:09 f-f