sandbox.scm 34 KB

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