racket
racket copied to clipboard
sandbox with default configuration can no longer load `2htdp/image`
Origionaly from https://groups.google.com/forum/?fromgroups#!searchin/racket-users/libobj%7Csort:relevance/racket-users/W_-4aN7kPyI/cwgwz2xIBAAJ
Two small example of this:
(make-module-evaluator `(module m racket (require 2htdp/image)))
(make-evaluator 'racket #:requires '(2htdp/image))
These errors with one of the following, depending on the machine.
file-or-directory-modify-seconds: `read' access denied for
/Users/florence/Library/Preferences/org.racket-lang.prefs.rktd
file-exists?: `exists' access denied for libobj.so
file-exists?: `exists' access denied for libobj.dylib
file-exists?: `exists' access denied for libpng16.so.16
I'm not sure when this broke, but it worked on 6.2.1 (When using the handin server at least).
I also have not been able to find workaround by setting sandbox-path-permissions, other than setting 'read for "/".
Any suggestions for fixing this would be great, since I don't want to have to provide global read access. @mflatt or @rfindler or @LeifAndersen, have you run the handin server with something to fix this?
cc @ccshan
In debugging this, I've seen the following results:
- The following paths working:
(sandbox-path-permissions
(list*
(list 'exists "/lib64")
(list 'exists "/usr/lib64")
(list 'exists (current-directory))
(list 'exists "/System")
(sandbox-path-permissions)))
Note that this is Linux, there is no /System (the actual path needed was part of the macOS Framework). Also, variations on (current-directory) didn't work.
- That submissions sometimes work, and sometimes don't. It appears non-deterministic. That's even with
(list 'read "/")in the permissions.
~~The "non-determinism" appears to be that the first time it works, then it doesn't, until we restart the server or change the configuration somehow, and then it works one time again.~~
The "non-determinism" was that putting the code in the "checker" file for the handin server at the top-level didn't work the second time. So that's a non-issue.
I think the underlying design bug here is that ffi-lib looks for shared libraries relative to the current directory which seems like a bad idea to me. One way forward is to add an option to ffi-lib; if it's not too much of a backward-compatibility issue, we could disable the use of the current directory by default, but we may have to fall back to explicitly specifying an option everywhere in our libraries.
But if I understand the problem correctly, adding (list 'exists (current-directory)) to sandbox-path-permissions would be enough. Is there a platform or example where you need the additional paths? Do I understand correctly that non-determinsm issues have been resolved?
I think a new option that enables us to fix this for just 2htdp/image and 2htdp/universe would make a big difference, since those two are often run in a sandbox for the handin server (that's my use case).
Just adding (list 'exists (current-directory)) is indeed sufficient.
The non-determinism problem was just mutable state being reset, and not a bug.
One other question -- would changing to not use (current-directory) mean that other directories would need to be allowed?
Adding just (list 'exists (current-directory)) doesn't fix the problem for me. But i maybe I'm running from a different directory? (I'm on mac, so I'm getting the org.racket-lang.prefs.rktd version of the error).
For what it's worth, @samth and I figured out a set of paths to grant exists permission to by setting the environment variable LD_DEBUG=libs
@florence The org.racket-lang.prefs.rktd issue is a different one. Make sure that the racket/gui loaded on startup, so that there's no attempt to start it in a sandbox. (Otherwise, more things will go wrong than the org.racket-lang.prefs.rktd error.)
@ccshan It turns out that just (current-directory) should be sufficient.
Another idea: ffi-lib could cheat and install a no-op security guard while checking for a file's existence in the current directory. After all, if you can use ffi-lib, then the security-guard checks are really doing anything, and they're happening in an unlikely fallback.
@mflatt Ah right! w/ that fixed (list 'exists (current-directory)) also fixes the problem for me.
The cheating idea sounds good to me.
Since this repository was merged back in racket/racket, I'm transferring this issue there.
This issue has been mentioned on Racket Discussions. There might be relevant details there:
https://racket.discourse.group/t/read-access-denied-for/1834/12
This should be addressed (or partially addressed) by https://github.com/racket/snip/pull/11