Closed rebolbot closed 8 years ago
Submitted by: meijeru
We are obviously in the semantics area here; I extended the "internal context object" (which I presume is physically identical to the body) with a simple integer just to prove my point. It could have been a more complicated value, and let's not forget that in REBOL all data is code... Also, the piece of code GET IN SELF 'B could have used a variable instead of a lit-word 'B!
Let me be clear: I do not put this forward as a programming method, but it could be a security loophole, couldn't it?
Submitted by: BrianH
It is hard to make into a security hole if the module code is written securely. However, module security is currently incomplete, waiting on the PROTECT and UNPROTECT tickets #1014, #1015, #1141, #1142 and #1143. Until those bugs are fixed and enhancements made, we can't make modules truly secure.
The question is whether we really want to make an exception that would allow internal contexts of modules to be used as data structures? Do gotchas like the above (mostly in R2-style code since R3 has get-paths and GET path!) outweigh the potential benefits? That should be decided.
Btw, the internal context object is only rarely similar to the module body, only in trivial cases. For most real world cases it isn't close.
Submitted by: meijeru
As far as I understand, the context of a module (as yielded by BIND?) is an object composed of the first level set-words of the module body bound to the values they have. How can this be different from the module-body except as far as typing is concerned?
I would imagine that BODY-OF M == BODY-OF BIND? IN M 'A
Submitted by: BrianH
Object and module specs are made up of code that initializes them. Only in trivial circumstances does that code resemble pairs of set-words and values. BODY-OF doesn't really return the body of either an object or a module - that information is no longer referenced by objects and modules after their initialization. Instead, it is overloaded to return a block of word/value pairs, the result of that initialization code but not the code itself, or even a copy of it.
Don't let the name of BODY-OF fool you: It only returns (an unbound copy of) the body of functions and closures. For the other types it fakes it.
Submitted by: meijeru
I still have some difficulty undestanding all this. In part this may be because you refer to implementation details that I can't know because they cannot be divulged, and because of terminology (perhaps related to these implementation details).
When you say "code" do you mean e.g. C-code? And is the context object also faked (or at least created by BIND? on demand)?
Submitted by: BrianH
I mean REBOL code (of the DO dialect). The closest thing to a function body (which is what BODY-OF was named for) that an object has is the block passed to MAKE object!, which is treated as REBOL code. Which is also the closest thing an object has to a spec, for now, though modules actually have specs (the header). There is no CODE-OF function because the resulting object or module doesn't keep a reference to that code block after the object or module is created.
So the BODY-OF function generates a block of set-word/value pairs when applied to modules or objects, since that is the most useful thing it can return. But that is not the code of the object or module; the code is lost unless you keep a reference to it yourself.
The module's context object isn't faked, it's an internal reference.
Submitted by: meijeru
I understand the notion of "code" now; it is the fact that BODY-OF CONTEXT [A: 1 + 2] shows up as [A: 3]. The body block of a module is operated on by DO inside SYSTEM/INTRINSIC/MAKE-MODULE, I notice, just before the result is returned. But that does not take away that the correspondence between the module's words and their values, which is what I would call the body, during its lifetime, is none other than the context object -- what else could it be? And since one can operate on the context object, one can indirectly operate on the module body (in the sense of the actual words and values of the module during its lifetime). It is true that this operation, e.g. the extension I showed, is not impacting on the result of IMPORT if it takes place after IMPORT has been invoked. But modules are not only used via IMPORT, the documentation mentions explicitly that you can use them as a sort of object as well.
Submitted by: BrianH
I also think it is reasonable to prohibit extension of the module's internal context object in MAKE-MODULE (especially since that is REBOL code that can be replaced at runtime if need be) - the comments were just a semantic note. We just can't do it until the protection bugs listed above are fixed.
Submitted by: Carl
In R3 the purpose of a module is to provide an "official" mechanism of grouping related code and data. It is a wrapper for writing better "code in the large". In R2, we used the unofficial mechanism: objects. In R3, modules make this mechanism official, and we've added some "helpers" to make it more generally useful.
There is no claim at this time that R3 modules are secure or protected in any way from other code. That would be a separate project, and it is not included in 3.0.0.
With that in mind, this ticket is not a bug and is therefore dismissed.
Submitted by: meijeru
This is a revival of part of the discussion in #896. It is possible (if not desirable) to extend the body of a module after its creation and binding, adding new set-words via the object yielded by BIND? Altough BrianH said in the comments to the earlier ticket that these words would not be available to the module code, this is not true thanks to SELF.
CC - Data [ Version: alpha 97 Type: Issue Platform: All Category: Security Reproduce: Always Fixed-in:none ]