sandbox.scm 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402
  1. ;;; Sandboxed evaluation of Scheme code
  2. ;;; Copyright (C) 2017, 2018 Free Software Foundation, Inc.
  3. ;;;; This library is free software; you can redistribute it and/or
  4. ;;;; modify it under the terms of the GNU Lesser General Public
  5. ;;;; License as published by the Free Software Foundation; either
  6. ;;;; version 3 of the License, or (at your option) any later version.
  7. ;;;;
  8. ;;;; This library is distributed in the hope that it will be useful,
  9. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. ;;;; Lesser General Public License for more details.
  12. ;;;;
  13. ;;;; You should have received a copy of the GNU Lesser General Public
  14. ;;;; License along with this library; if not, write to the Free Software
  15. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. ;;; Commentary:
  17. ;;;
  18. ;;; Code:
  19. (define-module (ice-9 sandbox)
  20. #:use-module (ice-9 control)
  21. #:use-module (ice-9 match)
  22. #:use-module ((ice-9 threads) #:select (current-thread))
  23. #:use-module (system vm vm)
  24. #:export (call-with-time-limit
  25. call-with-allocation-limit
  26. call-with-time-and-allocation-limits
  27. eval-in-sandbox
  28. make-sandbox-module
  29. alist-bindings
  30. array-bindings
  31. bit-bindings
  32. bitvector-bindings
  33. char-bindings
  34. char-set-bindings
  35. clock-bindings
  36. core-bindings
  37. error-bindings
  38. fluid-bindings
  39. hash-bindings
  40. iteration-bindings
  41. keyword-bindings
  42. list-bindings
  43. macro-bindings
  44. nil-bindings
  45. number-bindings
  46. pair-bindings
  47. predicate-bindings
  48. procedure-bindings
  49. promise-bindings
  50. prompt-bindings
  51. regexp-bindings
  52. sort-bindings
  53. srfi-4-bindings
  54. string-bindings
  55. symbol-bindings
  56. unspecified-bindings
  57. variable-bindings
  58. vector-bindings
  59. version-bindings
  60. mutating-alist-bindings
  61. mutating-array-bindings
  62. mutating-bitvector-bindings
  63. mutating-fluid-bindings
  64. mutating-hash-bindings
  65. mutating-list-bindings
  66. mutating-pair-bindings
  67. mutating-sort-bindings
  68. mutating-srfi-4-bindings
  69. mutating-string-bindings
  70. mutating-variable-bindings
  71. mutating-vector-bindings
  72. all-pure-bindings
  73. all-pure-and-impure-bindings))
  74. (define (call-with-time-limit limit thunk limit-reached)
  75. "Call @var{thunk}, but cancel it if @var{limit} seconds of wall-clock
  76. time have elapsed. If the computation is cancelled, call
  77. @var{limit-reached} in tail position. @var{thunk} must not disable
  78. interrupts or prevent an abort via a @code{dynamic-wind} unwind
  79. handler."
  80. ;; FIXME: use separate thread instead of sigalrm. If rounded limit is
  81. ;; <= 0, make it 1 usec to signal immediately.
  82. (let ((limit-usecs (max (inexact->exact (round (* limit 1e6))) 1))
  83. (prev-sigalarm-handler #f)
  84. (tag (make-prompt-tag)))
  85. (call-with-prompt tag
  86. (lambda ()
  87. (dynamic-wind
  88. (lambda ()
  89. (set! prev-sigalarm-handler
  90. (sigaction SIGALRM (lambda (sig)
  91. ;; If signal handling is delayed
  92. ;; until after prompt, no worries;
  93. ;; the success path won the race.
  94. (false-if-exception
  95. (abort-to-prompt tag)))))
  96. (setitimer ITIMER_REAL 0 0 0 limit-usecs))
  97. thunk
  98. (lambda ()
  99. (setitimer ITIMER_REAL 0 0 0 0)
  100. (match prev-sigalarm-handler
  101. ((handler . flags)
  102. (sigaction SIGALRM handler flags))))))
  103. (lambda (k)
  104. (limit-reached)))))
  105. (define (call-with-allocation-limit limit thunk limit-reached)
  106. "Call @var{thunk}, but cancel it if @var{limit} bytes have been
  107. allocated. If the computation is cancelled, call @var{limit-reached} in
  108. tail position. @var{thunk} must not disable interrupts or prevent an
  109. abort via a @code{dynamic-wind} unwind handler.
  110. This limit applies to both stack and heap allocation. The computation
  111. will not be aborted before @var{limit} bytes have been allocated, but
  112. for the heap allocation limit, the check may be postponed until the next
  113. garbage collection.
  114. Note that as a current shortcoming, the heap size limit applies to all
  115. threads; concurrent allocation by other unrelated threads counts towards
  116. the allocation limit."
  117. (define (bytes-allocated) (assq-ref (gc-stats) 'heap-total-allocated))
  118. (let ((zero (bytes-allocated))
  119. (tag (make-prompt-tag))
  120. (thread (current-thread)))
  121. (define (check-allocation)
  122. (when (< limit (- (bytes-allocated) zero))
  123. (system-async-mark (lambda ()
  124. (false-if-exception (abort-to-prompt tag)))
  125. thread)))
  126. (call-with-prompt tag
  127. (lambda ()
  128. (dynamic-wind
  129. (lambda ()
  130. (add-hook! after-gc-hook check-allocation))
  131. (lambda ()
  132. (call-with-stack-overflow-handler
  133. ;; The limit is in "words", which used to be 4 or 8 but now
  134. ;; is always 8 bytes.
  135. (max (floor/ limit 8) 1)
  136. thunk
  137. (lambda () (abort-to-prompt tag))))
  138. (lambda ()
  139. (remove-hook! after-gc-hook check-allocation))))
  140. (lambda (k)
  141. (limit-reached)))))
  142. (define (call-with-time-and-allocation-limits time-limit allocation-limit
  143. thunk)
  144. "Invoke @var{thunk} in a dynamic extent in which its execution is
  145. limited to @var{time-limit} seconds of wall-clock time, and its
  146. allocation to @var{allocation-limit} bytes. @var{thunk} must not
  147. disable interrupts or prevent an abort via a @code{dynamic-wind} unwind
  148. handler.
  149. If successful, return all values produced by invoking @var{thunk}. Any
  150. uncaught exception thrown by the thunk will propagate out. If the time
  151. or allocation limit is exceeded, an exception will be thrown to the
  152. @code{limit-exceeded} key."
  153. (call-with-time-limit
  154. time-limit
  155. (lambda ()
  156. (call-with-allocation-limit
  157. allocation-limit
  158. thunk
  159. (lambda ()
  160. (scm-error 'limit-exceeded "with-resource-limits"
  161. "Allocation limit exceeded" '() #f))))
  162. (lambda ()
  163. (scm-error 'limit-exceeded "with-resource-limits"
  164. "Time limit exceeded" '() #f))))
  165. (define (sever-module! m)
  166. "Remove @var{m} from its container module."
  167. (match (module-name m)
  168. ((head ... tail)
  169. (let ((parent (resolve-module head #f)))
  170. (unless (eq? m (module-ref-submodule parent tail))
  171. (error "can't sever module?"))
  172. (hashq-remove! (module-submodules parent) tail)))))
  173. ;; bindings := module-binding-list ...
  174. ;; module-binding-list := interface-name import ...
  175. ;; import := name | (exported-name . imported-name)
  176. ;; name := symbol
  177. (define (make-sandbox-module bindings)
  178. "Return a fresh module that only contains @var{bindings}.
  179. The @var{bindings} should be given as a list of import sets. One import
  180. set is a list whose car names an interface, like @code{(ice-9 q)}, and
  181. whose cdr is a list of imports. An import is either a bare symbol or a
  182. pair of @code{(@var{out} . @var{in})}, where @var{out} and @var{in} are
  183. both symbols and denote the name under which a binding is exported from
  184. the module, and the name under which to make the binding available,
  185. respectively."
  186. (let ((m (make-fresh-user-module)))
  187. (purify-module! m)
  188. (module-use-interfaces! m
  189. (map (match-lambda
  190. ((mod-name . bindings)
  191. (resolve-interface mod-name
  192. #:select bindings)))
  193. bindings))
  194. m))
  195. (define* (eval-in-sandbox exp #:key
  196. (time-limit 0.1)
  197. (allocation-limit #e10e6)
  198. (bindings all-pure-bindings)
  199. (module (make-sandbox-module bindings))
  200. (sever-module? #t))
  201. "Evaluate the Scheme expression @var{exp} within an isolated
  202. \"sandbox\". Limit its execution to @var{time-limit} seconds of
  203. wall-clock time, and limit its allocation to @var{allocation-limit}
  204. bytes.
  205. The evaluation will occur in @var{module}, which defaults to the result
  206. of calling @code{make-sandbox-module} on @var{bindings}, which itself
  207. defaults to @code{all-pure-bindings}. This is the core of the
  208. sandbox: creating a scope for the expression that is @dfn{safe}.
  209. A safe sandbox module has two characteristics. Firstly, it will not
  210. allow the expression being evaluated to avoid being cancelled due to
  211. time or allocation limits. This ensures that the expression terminates
  212. in a timely fashion.
  213. Secondly, a safe sandbox module will prevent the evaluation from
  214. receiving information from previous evaluations, or from affecting
  215. future evaluations. All combinations of binding sets exported by
  216. @code{(ice-9 sandbox)} form safe sandbox modules.
  217. The @var{bindings} should be given as a list of import sets. One import
  218. set is a list whose car names an interface, like @code{(ice-9 q)}, and
  219. whose cdr is a list of imports. An import is either a bare symbol or a
  220. pair of @code{(@var{out} . @var{in})}, where @var{out} and @var{in} are
  221. both symbols and denote the name under which a binding is exported from
  222. the module, and the name under which to make the binding available,
  223. respectively. Note that @var{bindings} is only used as an input to the
  224. default initializer for the @var{module} argument; if you pass
  225. @code{#:module}, @var{bindings} is unused. If @var{sever-module?} is
  226. true (the default), the module will be unlinked from the global module
  227. tree after the evaluation returns, to allow @var{mod} to be
  228. garbage-collected.
  229. If successful, return all values produced by @var{exp}. Any uncaught
  230. exception thrown by the expression will propagate out. If the time or
  231. allocation limit is exceeded, an exception will be thrown to the
  232. @code{limit-exceeded} key."
  233. (dynamic-wind
  234. (lambda () #t)
  235. (lambda ()
  236. (call-with-time-and-allocation-limits
  237. time-limit allocation-limit
  238. (lambda ()
  239. (eval exp module))))
  240. (lambda () (when sever-module? (sever-module! module)))))
  241. ;; An evaluation-sandboxing facility is safe if:
  242. ;;
  243. ;; (1) every evaluation will terminate in a timely manner
  244. ;;
  245. ;; (2) no evaluation can affect future evaluations
  246. ;;
  247. ;; For (1), we impose a user-controllable time limit on the evaluation,
  248. ;; in wall-clock time. When that limit is reached, Guile schedules an
  249. ;; asynchronous interrupt in the sandbox that aborts the computation.
  250. ;; For this to work, the sandboxed evaluation must not disable
  251. ;; interrupts, and it must not prevent timely aborts via malicious "out"
  252. ;; guards in dynamic-wind thunks.
  253. ;;
  254. ;; The sandbox also has an allocation limit that uses a similar cancel
  255. ;; mechanism, but this limit is less precise as it only runs at
  256. ;; garbage-collection time.
  257. ;;
  258. ;; The sandbox sets the allocation limit as the stack limit as well.
  259. ;;
  260. ;; For (2), the only way an evaluation can affect future evaluations is
  261. ;; if it causes a side-effect outside its sandbox. That side effect
  262. ;; could change the way the host or future sandboxed evaluations
  263. ;; operate, or it could leak information to future evaluations.
  264. ;;
  265. ;; One means of information leakage would be the file system. Although
  266. ;; one can imagine "safe" ways to access a file system, in practice we
  267. ;; just prevent all access to this and other operating system facilities
  268. ;; by not exposing the Guile primitives that access the file system,
  269. ;; connect to networking hosts, etc. If we chose our set of bindings
  270. ;; correctly and it is impossible to access host values other than those
  271. ;; given to the evaluation, then we have succeeded in granting only a
  272. ;; limited set of capabilities to the guest.
  273. ;;
  274. ;; To prevent information leakage we also limit other information about
  275. ;; the host, like its hostname or the Guile build information.
  276. ;;
  277. ;; The guest must also not have the capability to mutate a location used
  278. ;; by the host or by future sandboxed evaluations. Either you expose no
  279. ;; primitives to the evaluation that can mutate locations, or you expose
  280. ;; no mutable locations. In this sandbox we opt for a combination of
  281. ;; the two, though the selection of bindings is up to the user. "set!"
  282. ;; is always excluded, as Guile doesn't have a nice way to prevent set!
  283. ;; on imported bindings. But variable-set! is included, as no set of
  284. ;; bindings from this module includes a variable or a capability to a
  285. ;; variable. It's possible though to build sandbox modules with no
  286. ;; mutating primitives. As far as we know, all possible combinations of
  287. ;; the binding sets listed below are safe.
  288. ;;
  289. (define core-bindings
  290. '(((guile)
  291. else => _ ...
  292. and
  293. begin
  294. apply
  295. call-with-values
  296. values
  297. case
  298. case-lambda
  299. case-lambda*
  300. cond
  301. define
  302. define*
  303. define-values
  304. do
  305. if
  306. lambda
  307. lambda*
  308. let
  309. let*
  310. letrec
  311. letrec*
  312. or
  313. quasiquote
  314. quote
  315. ;; Can't allow mutation to globals.
  316. ;; set!
  317. unless
  318. unquote
  319. unquote-splicing
  320. when
  321. while
  322. λ)))
  323. (define macro-bindings
  324. '(((guile)
  325. bound-identifier=?
  326. ;; Although these have "current" in their name, they are lexically
  327. ;; scoped, not dynamically scoped.
  328. current-filename
  329. current-source-location
  330. datum->syntax
  331. define-macro
  332. define-syntax
  333. define-syntax-parameter
  334. define-syntax-rule
  335. defmacro
  336. free-identifier=?
  337. generate-temporaries
  338. gensym
  339. identifier-syntax
  340. identifier?
  341. let-syntax
  342. letrec-syntax
  343. macroexpand
  344. macroexpanded?
  345. quasisyntax
  346. start-stack
  347. syntax
  348. syntax->datum
  349. syntax-case
  350. syntax-error
  351. syntax-parameterize
  352. syntax-rules
  353. syntax-source
  354. syntax-violation
  355. unsyntax
  356. unsyntax-splicing
  357. with-ellipsis
  358. with-syntax
  359. make-variable-transformer)))
  360. (define iteration-bindings
  361. '(((guile)
  362. compose
  363. for-each
  364. identity
  365. iota
  366. map
  367. map-in-order
  368. const
  369. noop)))
  370. (define clock-bindings
  371. '(((guile)
  372. get-internal-real-time
  373. internal-time-units-per-second
  374. sleep
  375. usleep)))
  376. (define procedure-bindings
  377. '(((guile)
  378. procedure-documentation
  379. procedure-minimum-arity
  380. procedure-name
  381. procedure?
  382. thunk?)))
  383. (define version-bindings
  384. '(((guile)
  385. effective-version
  386. major-version
  387. micro-version
  388. minor-version
  389. version
  390. version-matches?)))
  391. (define nil-bindings
  392. '(((guile)
  393. nil?)))
  394. (define unspecified-bindings
  395. '(((guile)
  396. unspecified?
  397. *unspecified*)))
  398. (define predicate-bindings
  399. '(((guile)
  400. ->bool
  401. and-map
  402. and=>
  403. boolean?
  404. eq?
  405. equal?
  406. eqv?
  407. negate
  408. not
  409. or-map)))
  410. ;; The current ports (current-input-port et al) are dynamically scoped,
  411. ;; which is a footgun from a sandboxing perspective. It's too easy for
  412. ;; a procedure that is the result of a sandboxed evaluation to be later
  413. ;; invoked in a different context and thereby be implicitly granted
  414. ;; capabilities to whatever port is then current. This is compounded by
  415. ;; the fact that most Scheme i/o primitives allow the port to be omitted
  416. ;; and thereby default to whatever's current. For now, sadly, we avoid
  417. ;; exposing any i/o primitive to the sandbox.
  418. #;
  419. (define i/o-bindings
  420. '(((guile)
  421. display
  422. eof-object?
  423. force-output
  424. format
  425. make-soft-port
  426. newline
  427. read
  428. simple-format
  429. write
  430. write-char)
  431. ((ice-9 ports)
  432. %make-void-port
  433. char-ready?
  434. ;; Note that these are mutable parameters.
  435. current-error-port
  436. current-input-port
  437. current-output-port
  438. current-warning-port
  439. drain-input
  440. eof-object?
  441. file-position
  442. force-output
  443. ftell
  444. input-port?
  445. output-port?
  446. peek-char
  447. port-closed?
  448. port-column
  449. port-conversion-strategy
  450. port-encoding
  451. port-filename
  452. port-line
  453. port-mode
  454. port?
  455. read-char
  456. the-eof-object
  457. ;; We don't provide open-output-string because it needs
  458. ;; get-output-string, and get-output-string provides a generic
  459. ;; capability on any output string port. For consistency then we
  460. ;; don't provide open-input-string either; call-with-input-string
  461. ;; is sufficient.
  462. call-with-input-string
  463. call-with-output-string
  464. with-error-to-port
  465. with-error-to-string
  466. with-input-from-port
  467. with-input-from-string
  468. with-output-to-port
  469. with-output-to-string)))
  470. ;; If two evaluations are called with the same input port, unread-char
  471. ;; and unread-string can use a port as a mutable channel to pass
  472. ;; information from one to the other.
  473. #;
  474. (define mutating-i/o-bindings
  475. '(((guile)
  476. set-port-encoding!)
  477. ((ice-9 ports)
  478. close-input-port
  479. close-output-port
  480. close-port
  481. file-set-position
  482. seek
  483. set-port-column!
  484. set-port-conversion-strategy!
  485. set-port-encoding!
  486. set-port-filename!
  487. set-port-line!
  488. setvbuf
  489. unread-char
  490. unread-string)))
  491. (define error-bindings
  492. '(((guile)
  493. error
  494. throw
  495. with-throw-handler
  496. catch
  497. ;; false-if-exception can cause i/o if the #:warning arg is passed.
  498. ;; false-if-exception
  499. ;; See notes on i/o-bindings.
  500. ;; peek
  501. ;; pk
  502. ;; print-exception
  503. ;; warn
  504. strerror
  505. scm-error
  506. )))
  507. ;; FIXME: Currently we can't expose anything that works on the current
  508. ;; module to the sandbox. It could be that the sandboxed evaluation
  509. ;; returns a procedure, and that procedure may later be invoked in a
  510. ;; different context with a different current-module and it is unlikely
  511. ;; that the later caller will consider themselves as granting a
  512. ;; capability on whatever module is then current. Likewise export (and
  513. ;; by extension, define-public and the like) also operate on the current
  514. ;; module.
  515. ;;
  516. ;; It could be that we could expose a statically scoped eval to the
  517. ;; sandbox.
  518. #;
  519. (define eval-bindings
  520. '(((guile)
  521. current-module
  522. module-name
  523. module?
  524. define-once
  525. define-private
  526. define-public
  527. defined?
  528. export
  529. defmacro-public
  530. ;; FIXME: single-arg eval?
  531. eval
  532. primitive-eval
  533. eval-string
  534. self-evaluating?
  535. ;; Can we?
  536. set-current-module)))
  537. (define sort-bindings
  538. '(((guile)
  539. sort
  540. sorted?
  541. stable-sort
  542. sort-list)))
  543. ;; These can only form part of a safe binding set if no mutable pair or
  544. ;; vector is exposed to the sandbox.
  545. (define mutating-sort-bindings
  546. '(((guile)
  547. sort!
  548. stable-sort!
  549. sort-list!
  550. restricted-vector-sort!)))
  551. (define regexp-bindings
  552. '(((guile)
  553. make-regexp
  554. regexp-exec
  555. regexp/basic
  556. regexp/extended
  557. regexp/icase
  558. regexp/newline
  559. regexp/notbol
  560. regexp/noteol
  561. regexp?)))
  562. (define alist-bindings
  563. '(((guile)
  564. acons
  565. assoc
  566. assoc-ref
  567. assq
  568. assq-ref
  569. assv
  570. assv-ref
  571. sloppy-assoc
  572. sloppy-assq
  573. sloppy-assv)))
  574. ;; These can only form part of a safe binding set if no mutable pair
  575. ;; is exposed to the sandbox. Unfortunately all charsets in Guile are
  576. ;; mutable, currently, including the built-in charsets, so we can't
  577. ;; expose these primitives.
  578. (define mutating-alist-bindings
  579. '(((guile)
  580. assoc-remove!
  581. assoc-set!
  582. assq-remove!
  583. assq-set!
  584. assv-remove!
  585. assv-set!)))
  586. (define number-bindings
  587. '(((guile)
  588. *
  589. +
  590. -
  591. /
  592. 1+
  593. 1-
  594. <
  595. <=
  596. =
  597. >
  598. >=
  599. abs
  600. acos
  601. acosh
  602. angle
  603. asin
  604. asinh
  605. atan
  606. atanh
  607. ceiling
  608. ceiling-quotient
  609. ceiling-remainder
  610. ceiling/
  611. centered-quotient
  612. centered-remainder
  613. centered/
  614. complex?
  615. cos
  616. cosh
  617. denominator
  618. euclidean-quotient
  619. euclidean-remainder
  620. euclidean/
  621. even?
  622. exact->inexact
  623. exact-integer-sqrt
  624. exact-integer?
  625. exact?
  626. exp
  627. expt
  628. finite?
  629. floor
  630. floor-quotient
  631. floor-remainder
  632. floor/
  633. gcd
  634. imag-part
  635. inf
  636. inf?
  637. integer-expt
  638. integer-length
  639. integer?
  640. lcm
  641. log
  642. log10
  643. magnitude
  644. make-polar
  645. make-rectangular
  646. max
  647. min
  648. modulo
  649. modulo-expt
  650. most-negative-fixnum
  651. most-positive-fixnum
  652. nan
  653. nan?
  654. negative?
  655. numerator
  656. odd?
  657. positive?
  658. quotient
  659. rational?
  660. rationalize
  661. real-part
  662. real?
  663. remainder
  664. round
  665. round-quotient
  666. round-remainder
  667. round/
  668. sin
  669. sinh
  670. sqrt
  671. tan
  672. tanh
  673. truncate
  674. truncate-quotient
  675. truncate-remainder
  676. truncate/
  677. zero?
  678. number?
  679. number->string
  680. string->number)))
  681. (define char-set-bindings
  682. '(((guile)
  683. ->char-set
  684. char-set
  685. char-set->list
  686. char-set->string
  687. char-set-adjoin
  688. char-set-any
  689. char-set-complement
  690. char-set-contains?
  691. char-set-copy
  692. char-set-count
  693. char-set-cursor
  694. char-set-cursor-next
  695. char-set-delete
  696. char-set-diff+intersection
  697. char-set-difference
  698. char-set-every
  699. char-set-filter
  700. char-set-fold
  701. char-set-for-each
  702. char-set-hash
  703. char-set-intersection
  704. char-set-map
  705. char-set-ref
  706. char-set-size
  707. char-set-unfold
  708. char-set-union
  709. char-set-xor
  710. char-set:ascii
  711. char-set:blank
  712. char-set:designated
  713. char-set:digit
  714. char-set:empty
  715. char-set:full
  716. char-set:graphic
  717. char-set:hex-digit
  718. char-set:iso-control
  719. char-set:letter
  720. char-set:letter+digit
  721. char-set:lower-case
  722. char-set:printing
  723. char-set:punctuation
  724. char-set:symbol
  725. char-set:title-case
  726. char-set:upper-case
  727. char-set:whitespace
  728. char-set<=
  729. char-set=
  730. char-set?
  731. end-of-char-set?
  732. list->char-set
  733. string->char-set
  734. ucs-range->char-set)))
  735. ;; These can only form part of a safe binding set if no mutable char-set
  736. ;; is exposed to the sandbox. Unfortunately all charsets in Guile are
  737. ;; mutable, currently, including the built-in charsets, so we can't
  738. ;; expose these primitives.
  739. #;
  740. (define mutating-char-set-bindings
  741. '(((guile)
  742. char-set-adjoin!
  743. char-set-complement!
  744. char-set-delete!
  745. char-set-diff+intersection!
  746. char-set-difference!
  747. char-set-filter!
  748. char-set-intersection!
  749. char-set-unfold!
  750. char-set-union!
  751. char-set-xor!
  752. list->char-set!
  753. string->char-set!
  754. ucs-range->char-set!)))
  755. (define array-bindings
  756. '(((guile)
  757. array->list
  758. array-cell-ref
  759. array-contents
  760. array-dimensions
  761. array-equal?
  762. array-for-each
  763. array-in-bounds?
  764. array-length
  765. array-rank
  766. array-ref
  767. array-shape
  768. array-slice
  769. array-slice-for-each
  770. array-slice-for-each-in-order
  771. array-type
  772. array-type-code
  773. array?
  774. list->array
  775. list->typed-array
  776. make-array
  777. make-shared-array
  778. make-typed-array
  779. shared-array-increments
  780. shared-array-offset
  781. shared-array-root
  782. transpose-array
  783. typed-array?)))
  784. ;; These can only form part of a safe binding set if no mutable vector,
  785. ;; bitvector, bytevector, srfi-4 vector, or array is exposed to the
  786. ;; sandbox.
  787. (define mutating-array-bindings
  788. '(((guile)
  789. array-cell-set!
  790. array-copy!
  791. array-copy-in-order!
  792. array-fill!
  793. array-index-map!
  794. array-map!
  795. array-map-in-order!
  796. array-set!)))
  797. (define hash-bindings
  798. '(((guile)
  799. doubly-weak-hash-table?
  800. hash
  801. hash-count
  802. hash-fold
  803. hash-for-each
  804. hash-for-each-handle
  805. hash-get-handle
  806. hash-map->list
  807. hash-ref
  808. hash-table?
  809. hashq
  810. hashq-get-handle
  811. hashq-ref
  812. hashv
  813. hashv-get-handle
  814. hashv-ref
  815. hashx-get-handle
  816. hashx-ref
  817. make-doubly-weak-hash-table
  818. make-hash-table
  819. make-weak-key-hash-table
  820. make-weak-value-hash-table
  821. weak-key-hash-table?
  822. weak-value-hash-table?)))
  823. ;; These can only form part of a safe binding set if no hash table is
  824. ;; exposed to the sandbox.
  825. (define mutating-hash-bindings
  826. '(((guile)
  827. hash-clear!
  828. hash-create-handle!
  829. hash-remove!
  830. hash-set!
  831. hashq-create-handle!
  832. hashq-remove!
  833. hashq-set!
  834. hashv-create-handle!
  835. hashv-remove!
  836. hashv-set!
  837. hashx-create-handle!
  838. hashx-remove!
  839. hashx-set!)))
  840. (define variable-bindings
  841. '(((guile)
  842. make-undefined-variable
  843. make-variable
  844. variable-bound?
  845. variable-ref
  846. variable?)))
  847. ;; These can only form part of a safe binding set if no mutable variable
  848. ;; is exposed to the sandbox; this applies particularly to variables
  849. ;; that are module bindings.
  850. (define mutating-variable-bindings
  851. '(((guile)
  852. variable-set!
  853. variable-unset!)))
  854. (define string-bindings
  855. '(((guile)
  856. absolute-file-name?
  857. file-name-separator-string
  858. file-name-separator?
  859. in-vicinity
  860. basename
  861. dirname
  862. list->string
  863. make-string
  864. object->string
  865. reverse-list->string
  866. string
  867. string->list
  868. string-any
  869. string-any-c-code
  870. string-append
  871. string-append/shared
  872. string-capitalize
  873. string-ci<
  874. string-ci<=
  875. string-ci<=?
  876. string-ci<>
  877. string-ci<?
  878. string-ci=
  879. string-ci=?
  880. string-ci>
  881. string-ci>=
  882. string-ci>=?
  883. string-ci>?
  884. string-compare
  885. string-compare-ci
  886. string-concatenate
  887. string-concatenate-reverse
  888. string-concatenate-reverse/shared
  889. string-concatenate/shared
  890. string-contains
  891. string-contains-ci
  892. string-copy
  893. string-count
  894. string-delete
  895. string-downcase
  896. string-drop
  897. string-drop-right
  898. string-every
  899. string-every-c-code
  900. string-filter
  901. string-fold
  902. string-fold-right
  903. string-for-each
  904. string-for-each-index
  905. string-hash
  906. string-hash-ci
  907. string-index
  908. string-index-right
  909. string-join
  910. string-length
  911. string-map
  912. string-normalize-nfc
  913. string-normalize-nfd
  914. string-normalize-nfkc
  915. string-normalize-nfkd
  916. string-null?
  917. string-pad
  918. string-pad-right
  919. string-prefix-ci?
  920. string-prefix-length
  921. string-prefix-length-ci
  922. string-prefix?
  923. string-ref
  924. string-replace
  925. string-reverse
  926. string-rindex
  927. string-skip
  928. string-skip-right
  929. string-split
  930. string-suffix-ci?
  931. string-suffix-length
  932. string-suffix-length-ci
  933. string-suffix?
  934. string-tabulate
  935. string-take
  936. string-take-right
  937. string-titlecase
  938. string-tokenize
  939. string-trim
  940. string-trim-both
  941. string-trim-right
  942. string-unfold
  943. string-unfold-right
  944. string-upcase
  945. string-utf8-length
  946. string<
  947. string<=
  948. string<=?
  949. string<>
  950. string<?
  951. string=
  952. string=?
  953. string>
  954. string>=
  955. string>=?
  956. string>?
  957. string?
  958. substring
  959. substring/copy
  960. substring/read-only
  961. substring/shared
  962. xsubstring)))
  963. ;; These can only form part of a safe binding set if no mutable string
  964. ;; is exposed to the sandbox.
  965. (define mutating-string-bindings
  966. '(((guile)
  967. string-capitalize!
  968. string-copy!
  969. string-downcase!
  970. string-fill!
  971. string-map!
  972. string-reverse!
  973. string-set!
  974. string-titlecase!
  975. string-upcase!
  976. string-xcopy!
  977. substring-fill!
  978. substring-move!)))
  979. (define symbol-bindings
  980. '(((guile)
  981. string->symbol
  982. string-ci->symbol
  983. symbol->string
  984. list->symbol
  985. make-symbol
  986. symbol
  987. symbol-append
  988. symbol-hash
  989. symbol-interned?
  990. symbol?)))
  991. (define keyword-bindings
  992. '(((guile)
  993. keyword?
  994. keyword->symbol
  995. symbol->keyword)))
  996. ;; These can only form part of a safe binding set if no valid prompt tag
  997. ;; is ever exposed to the sandbox, or can be constructed by the sandbox.
  998. (define prompt-bindings
  999. '(((guile)
  1000. abort-to-prompt
  1001. abort-to-prompt*
  1002. call-with-prompt
  1003. make-prompt-tag)))
  1004. (define bit-bindings
  1005. '(((guile)
  1006. ash
  1007. round-ash
  1008. logand
  1009. logcount
  1010. logior
  1011. lognot
  1012. logtest
  1013. logxor
  1014. logbit?)))
  1015. (define bitvector-bindings
  1016. '(((guile)
  1017. bitvector-count
  1018. bitvector-position
  1019. bitvector-count-bits
  1020. bit-extract
  1021. bitvector
  1022. bitvector->list
  1023. bitvector-length
  1024. bitvector-bit-set?
  1025. bitvector-bit-clear?
  1026. bitvector?
  1027. list->bitvector
  1028. make-bitvector)))
  1029. ;; These can only form part of a safe binding set if no mutable
  1030. ;; bitvector is exposed to the sandbox.
  1031. (define mutating-bitvector-bindings
  1032. '(((guile)
  1033. bitvector-clear-bit!
  1034. bitvector-clear-bits!
  1035. bitvector-set-all-bits!
  1036. bitvector-clear-all-bits!
  1037. bitvector-flip-all-bits!
  1038. bitvector-set-bit!
  1039. bitvector-set-bits!)))
  1040. (define fluid-bindings
  1041. '(((guile)
  1042. fluid-bound?
  1043. fluid-ref
  1044. ;; fluid-ref* could escape the sandbox and is not allowed.
  1045. fluid-thread-local?
  1046. fluid?
  1047. make-fluid
  1048. make-thread-local-fluid
  1049. make-unbound-fluid
  1050. with-fluid*
  1051. with-fluids
  1052. with-fluids*
  1053. make-parameter
  1054. parameter?
  1055. parameterize)))
  1056. ;; These can only form part of a safe binding set if no fluid is
  1057. ;; directly exposed to the sandbox.
  1058. (define mutating-fluid-bindings
  1059. '(((guile)
  1060. fluid-set!
  1061. fluid-unset!
  1062. fluid->parameter)))
  1063. (define char-bindings
  1064. '(((guile)
  1065. char-alphabetic?
  1066. char-ci<=?
  1067. char-ci<?
  1068. char-ci=?
  1069. char-ci>=?
  1070. char-ci>?
  1071. char-downcase
  1072. char-general-category
  1073. char-is-both?
  1074. char-lower-case?
  1075. char-numeric?
  1076. char-titlecase
  1077. char-upcase
  1078. char-upper-case?
  1079. char-whitespace?
  1080. char<=?
  1081. char<?
  1082. char=?
  1083. char>=?
  1084. char>?
  1085. char?
  1086. char->integer
  1087. integer->char)))
  1088. (define list-bindings
  1089. '(((guile)
  1090. list
  1091. list-cdr-ref
  1092. list-copy
  1093. list-head
  1094. list-index
  1095. list-ref
  1096. list-tail
  1097. list?
  1098. null?
  1099. make-list
  1100. append
  1101. delete
  1102. delq
  1103. delv
  1104. filter
  1105. length
  1106. member
  1107. memq
  1108. memv
  1109. merge
  1110. reverse)))
  1111. ;; These can only form part of a safe binding set if no mutable
  1112. ;; pair is exposed to the sandbox.
  1113. (define mutating-list-bindings
  1114. '(((guile)
  1115. list-cdr-set!
  1116. list-set!
  1117. append!
  1118. delete!
  1119. delete1!
  1120. delq!
  1121. delq1!
  1122. delv!
  1123. delv1!
  1124. filter!
  1125. merge!
  1126. reverse!)))
  1127. (define pair-bindings
  1128. '(((guile)
  1129. last-pair
  1130. pair?
  1131. caaaar
  1132. caaadr
  1133. caaar
  1134. caadar
  1135. caaddr
  1136. caadr
  1137. caar
  1138. cadaar
  1139. cadadr
  1140. cadar
  1141. caddar
  1142. cadddr
  1143. caddr
  1144. cadr
  1145. car
  1146. cdaaar
  1147. cdaadr
  1148. cdaar
  1149. cdadar
  1150. cdaddr
  1151. cdadr
  1152. cdar
  1153. cddaar
  1154. cddadr
  1155. cddar
  1156. cdddar
  1157. cddddr
  1158. cdddr
  1159. cddr
  1160. cdr
  1161. cons
  1162. cons*)))
  1163. ;; These can only form part of a safe binding set if no mutable
  1164. ;; pair is exposed to the sandbox.
  1165. (define mutating-pair-bindings
  1166. '(((guile)
  1167. set-car!
  1168. set-cdr!)))
  1169. (define vector-bindings
  1170. '(((guile)
  1171. list->vector
  1172. make-vector
  1173. vector
  1174. vector->list
  1175. vector-copy
  1176. vector-length
  1177. vector-ref
  1178. vector?)))
  1179. ;; These can only form part of a safe binding set if no mutable
  1180. ;; vector is exposed to the sandbox.
  1181. (define mutating-vector-bindings
  1182. '(((guile)
  1183. vector-fill!
  1184. vector-move-left!
  1185. vector-move-right!
  1186. vector-set!)))
  1187. (define promise-bindings
  1188. '(((guile)
  1189. force
  1190. delay
  1191. make-promise
  1192. promise?)))
  1193. (define srfi-4-bindings
  1194. '(((srfi srfi-4)
  1195. f32vector
  1196. f32vector->list
  1197. f32vector-length
  1198. f32vector-ref
  1199. f32vector?
  1200. f64vector
  1201. f64vector->list
  1202. f64vector-length
  1203. f64vector-ref
  1204. f64vector?
  1205. list->f32vector
  1206. list->f64vector
  1207. list->s16vector
  1208. list->s32vector
  1209. list->s64vector
  1210. list->s8vector
  1211. list->u16vector
  1212. list->u32vector
  1213. list->u64vector
  1214. list->u8vector
  1215. make-f32vector
  1216. make-f64vector
  1217. make-s16vector
  1218. make-s32vector
  1219. make-s64vector
  1220. make-s8vector
  1221. make-u16vector
  1222. make-u32vector
  1223. make-u64vector
  1224. make-u8vector
  1225. s16vector
  1226. s16vector->list
  1227. s16vector-length
  1228. s16vector-ref
  1229. s16vector?
  1230. s32vector
  1231. s32vector->list
  1232. s32vector-length
  1233. s32vector-ref
  1234. s32vector?
  1235. s64vector
  1236. s64vector->list
  1237. s64vector-length
  1238. s64vector-ref
  1239. s64vector?
  1240. s8vector
  1241. s8vector->list
  1242. s8vector-length
  1243. s8vector-ref
  1244. s8vector?
  1245. u16vector
  1246. u16vector->list
  1247. u16vector-length
  1248. u16vector-ref
  1249. u16vector?
  1250. u32vector
  1251. u32vector->list
  1252. u32vector-length
  1253. u32vector-ref
  1254. u32vector?
  1255. u64vector
  1256. u64vector->list
  1257. u64vector-length
  1258. u64vector-ref
  1259. u64vector?
  1260. u8vector
  1261. u8vector->list
  1262. u8vector-length
  1263. u8vector-ref
  1264. u8vector?)))
  1265. ;; These can only form part of a safe binding set if no mutable
  1266. ;; bytevector is exposed to the sandbox.
  1267. (define mutating-srfi-4-bindings
  1268. '(((srfi srfi-4)
  1269. f32vector-set!
  1270. f64vector-set!
  1271. s16vector-set!
  1272. s32vector-set!
  1273. s64vector-set!
  1274. s8vector-set!
  1275. u16vector-set!
  1276. u32vector-set!
  1277. u64vector-set!
  1278. u8vector-set!)))
  1279. (define all-pure-bindings
  1280. (append alist-bindings
  1281. array-bindings
  1282. bit-bindings
  1283. bitvector-bindings
  1284. char-bindings
  1285. char-set-bindings
  1286. clock-bindings
  1287. core-bindings
  1288. error-bindings
  1289. fluid-bindings
  1290. hash-bindings
  1291. iteration-bindings
  1292. keyword-bindings
  1293. list-bindings
  1294. macro-bindings
  1295. nil-bindings
  1296. number-bindings
  1297. pair-bindings
  1298. predicate-bindings
  1299. procedure-bindings
  1300. promise-bindings
  1301. prompt-bindings
  1302. regexp-bindings
  1303. sort-bindings
  1304. srfi-4-bindings
  1305. string-bindings
  1306. symbol-bindings
  1307. unspecified-bindings
  1308. variable-bindings
  1309. vector-bindings
  1310. version-bindings))
  1311. (define all-pure-and-impure-bindings
  1312. (append all-pure-bindings
  1313. mutating-alist-bindings
  1314. mutating-array-bindings
  1315. mutating-bitvector-bindings
  1316. mutating-fluid-bindings
  1317. mutating-hash-bindings
  1318. mutating-list-bindings
  1319. mutating-pair-bindings
  1320. mutating-sort-bindings
  1321. mutating-srfi-4-bindings
  1322. mutating-string-bindings
  1323. mutating-variable-bindings
  1324. mutating-vector-bindings))