notjack
2018-5-4 12:08:27

The docs for security guards say this:

> A thread’s current security guard is determined by the current-security-guard parameter. Every security guard has a parent, and a parent’s access procedures are called whenever a child’s access procedures are called. Thus, a thread cannot increase its own access arbitrarily by installing a new guard. The initial security guard enforces no access restrictions other than those enforced by the host platform.


notjack
2018-5-4 12:09:52

But the following doesn’t raise any security errors:

#lang racket

(define original-guard (current-security-guard))

(define (read-secret)
  (file->string "/Users/jackfirth/githubtoken"))

(define (security-guard-deny-files guard)
  (define (deny who path actions)
    (error who "not allowed access to files"))
  (make-security-guard guard deny void))

(read-secret)

(define (call/evil proc)
  (parameterize ([current-security-guard original-guard])
    (proc)))

(parameterize
    ([current-security-guard (security-guard-deny-files original-guard)])
  (call/evil read-secret))

notjack
2018-5-4 12:11:59

Am I misunderstanding the purpose of security guards? It seems like installing a security guard guarantees nothing unless a fresh namespace is used too, since any called function could have closed over the original, weaker security guard before you installed the strict one


notjack
2018-5-4 12:15:44

My imaginary use case is a contract on a function that says it can be called in a context where the current security guard disallows access to files; such a contract doesn’t seem enforceable (by installing a security guard during calls to the function) if the function can just replace the strict guard with a lenient one it got from somewhere else


notjack
2018-5-4 12:18:04

do security guards assume that you’re using them with racket/sandbox or something?


samuel.falcon.fdez
2018-5-4 13:04:29

After a lot of poking and reading about thread local storage, I got this moving with these instructions, thank you!

As you say, cooperating with 3m GC is going to be another story, and I’m finding that this is harder than I expected due to my inexperience with Windows as well… I guess patience is the name of the game.


samth
2018-5-4 13:09:02

security guards are intended for protecting eval-like operations (such as eval itself or module loading)


ryanc
2018-5-4 15:53:15

@samth Are you thinking of code inspectors? Security guards are for operations like filesystem and network access.


samth
2018-5-4 15:54:31

I’m aware of that


ryanc
2018-5-4 15:56:19

@notjack I think the docs should say “by creating a new guard” instead of “by installing a new guard”. If your code captures a lenient guard, then it can perform operations under that old guard the way your code does. After all, if it was able to capture a lenient guard, it could have created a thread (with the same lenient guard) and forwarded operations to that other thread (with the initial guard) to perform instead.


notjack
2018-5-4 16:02:41

@ryanc hmmm. that would be an improvement to the docs, though I think they ought to go further and point out the implication that any non-dynamically-created module can circumvent a guard installed after module initialization time, since it could have simply captured (current-security-guard) in a module definition


notjack
2018-5-4 16:03:34

that’s very subtle and totally changes how I’d imagine using them


ryanc
2018-5-4 16:13:41

@notjack Yes, that’s true. There should probably be a mini-guide on security and sandboxing in Racket. For example, if you’re worried about security guards, you should be just as worried about code inspectors.


notjack
2018-5-4 16:15:21

like, I was assuming security guards were for enforcing stuff between two modules - not between two namespaces (I think that’s a correct description)


notjack
2018-5-4 16:16:16

@ryanc I’ve been in a vague state of fear of code inspectors for a long time but don’t actually understand how much power they have, just that they can see into structs sometimes


ryanc
2018-5-4 16:20:36

@notjack the (current-inspector) parameter controls access to structs, but the (current-code-inspector) parameter controls things like whether a module is allowed to use the protected exports of the modules it requires.


notjack
2018-5-4 16:20:53

and that’s related to FFI things right?


notjack
2018-5-4 16:21:27

and unsafe ops


ryanc
2018-5-4 16:22:18

Yes. For example, if you set the current security guard but not the code inspector, then a module might not be able to call open-input-file but it could still use the FFI to call the C library’s open. (And it could unsafely mutate the security guard into one that allows everything, anyway.)


ryanc
2018-5-4 16:23:11

That’s why I think there should be a guide that describes how to turn the individual mechanisms into a security strategy.


notjack
2018-5-4 16:23:25

hmmm. when would it be a good idea to use security guards + code inspectors without just going all the way and using sandboxes?


notjack
2018-5-4 16:24:15

maybe if you’re only using dynamic-require kinds of things instead of full-blown eval?


ryanc
2018-5-4 16:26:26

I think so, yes… or if for some other reason you want to share the same module registry (and module instances) instead of creating a new one.


notjack
2018-5-4 16:29:31

I could see doing it with distributed computation between trusted machines - in that case you might assume everyone’s got the same collections so you can send functions in the form of pointers to module exports that other nodes dynamically require


notjack
2018-5-4 16:29:57

like static pointers in haskell


notjack
2018-5-4 16:31:10

I have absolutely no idea if that’d actually be faster or safer than eval though


leif
2018-5-4 17:25:13

@mflatt Thanks. :slightly_smiling_face:


leif
2018-5-4 17:59:57

Am I the only one that always gets an error when opening a new file in DrRacket?


leif
2018-5-4 18:00:02

Usually something like: instantiate-linklet: mismatch; reference to a variable that has the wrong procedure or structure-type shape; possibly, bytecode file needs re-compile because dependencies changed name: add-relative-requires! exporting instance: "/Users/leif/rsrc/scribble/scribble-lib/scribble/srcdoc.rkt" importing instance: "/Users/leif/rsrc/gui/gui-lib/framework/preferences.rkt" Module Language: invalid language specification in: scratch


leif
2018-5-4 18:00:24

(And I have recompiled)


lexi.lambda
2018-5-4 18:11:52

@mflatt would it be possible to point me in the direction towards the solution to this issue? or do you think it’s too subtle for me to get all the pieces right? https://github.com/racket/racket/issues/2062


lexi.lambda
2018-5-4 18:15:57

I think it’s pretty clear that some expansion context(s) need def-ctx-scopes to be a box, but I’m not confident enough about when to call accumulate-def-ctx-scopes.


mflatt
2018-5-4 18:43:13

@lexi.lambda I don’t know offhand. I can take a look, but probably not today (and I’m only half-way, probably, in sorting out the other problem you ran into yesterday)


lexi.lambda
2018-5-4 18:44:37

Okay, that’s alright. I just figured I’d ask in case it was something I could deal with to relieve you of some work. If it wouldn’t make it any easier on you, then there isn’t much point, but I’ll definitely look at your fix once you do get to it, whenever that may be.


leif
2018-5-4 19:34:54

@mflatt @ryanc When I start up the macro stepper I’m getting an internal error:

Internal error:
derivation-parser: error on token #3292: <syntax-error, #(struct:exn:fail "expand: namespace mismatch; cannot locate module instance\n  module: #<module-path-index:\"private/lang.rkt\" \"base.rkt\" + 'lang[2010586]>\n  use phase: 0\n  definition phase: 0\n  for identifier: #<syntax:Users/leif/vsrc/idmt/editor/private/lang.rkt:103:64 from-editor>" #<continuation-mark-set>)>

leif
2018-5-4 19:35:05

```


leif
2018-5-4 19:35:11
derivation-parser: error on token #3292: <syntax-error, #(struct:exn:fail "expand: namespace mismatch; cannot locate module instance\n  module: #<module-path-index:\"private/lang.rkt\" \"base.rkt\" + 'lang[2010586]>\n  use phase: 0\n  definition phase: 0\n  for identifier: #<syntax:Users/leif/vsrc/idmt/editor/private/lang.rkt:103:64 from-editor>" #<continuation-mark-set>)>
  context...:
   /Users/leif/rsrc/parser-tools/parser-tools-lib/parser-tools/yacc.rkt:347:16: parsing-loop
   .../more-scheme.rkt:261:28
   /Users/leif/rsrc/macro-debugger/macro-debugger/macro-debugger/view/term-record.rkt:123:4: recache-deriv! method in term-record%
   /Users/leif/rsrc/macro-debugger/macro-debugger/macro-debugger/view/term-record.rkt:63:16: get-deriv-hidden? method in term-record%
   /Users/leif/rsrc/macro-debugger/macro-debugger/macro-debugger/view/stepper.rkt:70:24
   /Users/leif/rsrc/gui/gui-lib/mred/private/wx/common/queue.rkt:428:6
   /Users/leif/rsrc/gui/gui-lib/mred/private/wx/common/queue.rkt:479:32
   /Users/leif/rsrc/gui/gui-lib/mred/private/wx/common/queue.rkt:627:3

leif
2018-5-4 19:35:36

leif
2018-5-4 19:35:42

With this attached debug snippet.


leif
2018-5-4 19:36:26

Would either of you have any idea what the problem here might be?


leif
2018-5-4 19:37:14

For what its worth, I also get an error when expanding without the macro stepper, which is: expand: namespace mismatch; cannot locate module instance module: #<module-path-index:"private/lang.rkt" "base.rkt" + 'lang[6832]> use phase: 0 definition phase: 0 for identifier: #<syntax:private/lang.rkt:103:64 from-editor> compilation context...: /Users/leif/v/idmt/editor/lang.rkt context...: binding->module-instance binding-lookup50 loop /Users/leif/racket/racket/collects/racket/require-transform.rkt:266:2: expand-import /Users/leif/racket/racket/collects/racket/private/reqprov.rkt:266:21: try-next /Users/leif/racket/racket/collects/racket/private/reqprov.rkt:243:2: require apply-transformer-in-context dispatch-transformer41 do-local-expand58 /Users/leif/racket/racket/collects/syntax/wrap-modbeg.rkt:46:4: do-wrapping-module-begin apply-transformer-in-context dispatch-transformer41 loop finish [repeats 3 more times] pass-1-and-2-loop ...


leif
2018-5-4 19:37:33

So there clearly is a bug in my macro, but it also appears that there is an internal macro stepper error as well.


greg
2018-5-4 20:21:10

@leif Your example is 25,000 lines? :slightly_smiling_face:


leif
2018-5-4 20:21:34

@greg lol, nah, that’s the macro stepper’s debug output.


leif
2018-5-4 20:21:55

@mflatt Maybe a simpler question, what does a + in a module-path-index mean, as in: #<module-path-index:"private/lang.rkt" "base.rkt" + 'lang[6832]>.


greg
2018-5-4 20:23:23

@leif Didn’t mean to sound critical. I figured I’d try debug.rkt in Racket 6.10 to see how it worked, there. And wasn’t sure what to do with it. Anyway got a read error due to the #< in the prints of the opaque structs. ¯_(ツ)_/¯


leif
2018-5-4 20:24:53

lol, ya.


leif
2018-5-4 20:25:01

Nah, I didn’t feel criticized.


leif
2018-5-4 20:25:11

Like, if that were a code snippet, it would be useless.


greg
2018-5-4 20:25:13

(Also out of habit I hit C-A-q in Emacs to indent it, and was horrified to see “indenting region x% done…” message and thought I had a racket-mode bug to fix.)


leif
2018-5-4 20:25:25

But nah, its just debug diagnostic data. Which…I have no idea how to interperate. :slightly_smiling_face:


leif
2018-5-4 20:25:36

LOLOLOL


greg
2018-5-4 20:26:18

I am happy to try eval-ing anything. Why I have so many worms.


leif
2018-5-4 20:27:44

(eval ’(totally not a worm))