|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
|
|
Newbie questions about persistenceHi,
I didn't find any solution to the previous problem, but it hasn't been causing too much trouble and I'm trying to learn about persistence now. If you visit "erights.org -> ELib -> Persistence" you just get a load of pages marked "to be written", but there's actually quite a lot of good documentation if you can find it. In particular, I found these links useful: * http://www.erights.org/data/serial/jhu-paper/deconstructing.html * http://www.eros-os.org/pipermail/e-lang/2004-January/009483.html * http://www.erights.org/elib/distrib/captp/index.html There are a number of things which are probably obvious if you know the system, but took me a while to realise. I'll summarise them here for other beginners, and so people can correct the bits I get wrong. The prototype I'm writing has a client/server architecture. A client generally requests objects be created on a server, and the server monitors them. Both the client and server are able to persist their current state. There are multiple clients and servers and quite a lot of sharing goes on between them. Sturdy refs My first mistake was assuming that, since a client can invoke methods on a live ref and can pass the live ref to other clients, it must know the remote object's Swiss number. I therefore assumed that the client should call "makeSturdyRef(farRef)" to be able to reconnect or persist the reference. The CapTP documentation says this about what is sent to the client (in DeliverOnlyOp): "The NewFarDesc encoding must have all the information needed to create such a new Far reference, which is the position the Far reference should be assigned in the Imports table (the same as the position at which Carol is Exported), and the SwissNumber that, together with VatA's VatID, represents Carol's sameness identity. However, the JavaDoc shows that a NewFarDesc actually contains only the Swiss hash (i.e. the identity of the object), not the Swiss number (the ability to call it): http://www.erights.org/javadoc/net/captp/jcomm/NewFarDesc.html I'm not sure whether we're using NewFarDesc or OldFarDesc in practice, though I assume it doesn't make any difference here. My understanding of the situation now is that: * When a live ref is sent to the client, it is assigned a small integer ID (like a Unix file descriptor), which is only valid in the context of that TCP connection. There is a special mechanism for passing these live refs between clients, via the server. * The client cannot get a Swiss number from a live ref. * The server (hosting vat) must always call makeSturdyRef on an object before passing it to another vat if it wants the remote end to be able to persist it or reconnect after the TCP connection is closed. * Calling makeSturdyRef creates a new Swiss base and, from that, a new Swiss number. It adds a mapping from this to the object, in a map it shares with the time machine. It then registers the object with the IdentityMgr (so that clients can connect to it) and creates the actual SturdyRef object with the Swiss number in it. * Calling makeSturdyRef.temp is similar, except that it doesn't add anything to the map shared with the time machine. * The time machine works by saving the object graph starting from the swiss-number-to-object mapping. * Since makeSturdyRef(obj) makes a sturdy ref that lasts forever and is persisted, and throws away the SwissRetainer used to cancel it, refs made this way will accumulate forever. Persistence Starting with the mapping from SwissRetainers to objects (i.e. all persistent exported objects), the time machine serialises the object graph to a file, along with the vat's private key and network address. The format of this serialisation is a subset of E called Data-E. Internally, the time machine uses a "surgeon" to serialise and unserialise object graphs. Objects which should not be serialised, but which will be available when reloading, are called "exits" of the graph, and must be registered with the surgeon first. The system is designed to be able to serialise mutually-suspicious and untrusted objects. No object should be able to revive with more authority than it started with. Some objects in E can be serialised automatically, including numbers, strings, lists, maps, etc. Some objects can be serialised if an appropriate "loader" or "uncaller" is registered with the surgeon. These include files and modules. Many things cannot be serialised by default, including: - facets (obj.method) - caretakers - promises - near problems (bug in minimalUncaller?) Persistence of sturdy refs A sturdy ref can only be serialised if fully resolved (is this a bug?), e.g. ? introducer.onTheAir() ? def surgeon := <elib:serial.makeSurgeon>.withSrcKit("de: ").diverge() ? surgeon.addLoader(introducer, "cap__uriGetter") ? def a ? def b := makeSturdyRef.temp(3) ? bind a := b ? surgeon.serialize(a) # problem: Can't uneval <SturdyRef to 3> ? a == b # value: true ? surgeon.serialize(b) # value: "de: <cap://*qvcmrxvqy66rest6gfzhhxwrjni6nrdq@...:59905/jo6sk4nehnrewzo7bvntfz7rl32f6q2g>" I used this code to work around this: # Uncalls SturdyRefs to <cap:...> def sturdyLoader extends introducer { to optUncall(obj) { return super.optUncall(Ref.resolution(obj)) } } surgeon.addLoader(sturdyLoader, "cap__uriGetter") Persistence of cycles Some cyclic data structures can be persisted, while others can't (is this a bug?). I haven't worked out what the rule is, but I do have some examples: def surgeon := <elib:serial.makeSurgeon>.withSrcKit("de: ").diverge() def roundTrip(obj) { println(`Serializing $obj...`) def data := surgeon.serialize(obj) println(`Serialized as $data`) def obj2 := surgeon.unserialize(data) println(`Unserialized as $obj2`) println("") } def a := [a] roundTrip(a) def b := [a, a] roundTrip(b) This prints: Serializing [<***CYCLE***>]... Serialized as de: def t__0 := [t__0] Unserialized as [<***CYCLE***>] Serializing [[<***CYCLE***>], [<***CYCLE***>]]... Serialized as de: [def t__0 := [t__0], t__0] # problem: <IndexOutOfBoundsException: not found: t__0> This is quite annoying, because a SwissRetainer includes a pointer to its object, in addition to the pointer in the table for which the retainer is a key. Therefore, an object containing a single cycle ends up with the broken double-cycle structure when saved. Persistence of identity Transparent objects can implement __optUncall to allow them to be persisted. This method returns all of the object's authority, proving to the surgeon that it is permitted to be revived with it. However, this also allows anyone else to get an object's authority by calling __optUncall themselves. Therefore, most objects should use __optSealedDispatch to seal the result. There don't seem to be many examples of this (e.g. FileGetter uses "obj instanceof File" instead). I'm having trouble seeing how to use this. Should I add a new loader/uncaller? How is identity handled? e.g if I have a one-shot object, how can I ensure that an object holding it will revive with only one copy of the one-shot object? Similarly for a caretaker. Persistence of functions The result of uncalling an object is usually of the form [makeFoo, "run", [...]], where makeFoo is a top-level function in some module. Is there any way to get the time machine to handle these automatically, without having to add them all as exists manually? My current solution is that every module looks like this: def makeFooInternal(state) { return def foo { to __optUncall() { return [makeFooInternal, "run", [state]] } } } def makeFoo() { def state := ... return makeFooInternal(state) } [ =>makeFoo, =>makeFooInternal ] I then add an uncaller that recognises top-level functions by their name: def modules := [].asMap().diverge() def loader(pkg, name) { if (!modules.maps(pkg)) { modules[pkg] := <import>[pkg] } return modules[pkg][name] } def functionUncaller { to optUncall(obj) { if (Ref.isNear(obj)) { def type := obj.__getAllegedType() def name := type.getFQName().split("$") if (name.size() != 2) { return null } def [pkg, obj] := name return [loader, "run", [pkg, obj]] } } } This seems a bit clumsy. Is there a better way? There are too many functions to add them manually. Thanks, and sorry for all the questions! -- Dr Thomas Leonard IT Innovation Centre 2 Venture Road Southampton Hampshire SO16 7NP Tel: +44 0 23 8076 0834 Fax: +44 0 23 8076 0833 mailto:tal@... http://www.it-innovation.soton.ac.uk _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistenceOn Aug 28, 2009, at 10:27, Thomas Leonard wrote:
> There are a number of things which are probably obvious if you know > the system, but took me a while to realise. I'll summarise them here > for other beginners, and so people can correct the bits I get wrong. ... > Sturdy refs > > My first mistake was assuming that, since a client can invoke methods > on a live ref and can pass the live ref to other clients, it must know > the remote object's Swiss number. I therefore assumed that the client > should call "makeSturdyRef(farRef)" to be able to reconnect or persist > the reference. The second part is true: to be persistent across CapTP connections a reference must be a SturdyRef. > The CapTP documentation says this about what is sent to the client (in > DeliverOnlyOp): > > "The NewFarDesc encoding must have all the information needed to > create such a new Far reference, which is the position the Far > reference should be assigned in the Imports table (the same as the > position at which Carol is Exported), and the SwissNumber that, > together with VatA's VatID, represents Carol's sameness identity. > > However, the JavaDoc shows that a NewFarDesc actually contains only > the Swiss hash (i.e. the identity of the object), not the Swiss number > (the ability to call it): MarkM, could you comment on why this is so? > * When a live ref is sent to the client, it is assigned a small > integer ID (like a Unix file descriptor), which is only valid in the > context of that TCP connection. There is a special mechanism for > passing these live refs between clients, via the server. There is no client or server in CapTP; it is a symmetric protocol. 3- party introductions happen in the same way always. > * The client cannot get a Swiss number from a live ref. Yes. > * The server (hosting vat) must always call makeSturdyRef on an object > before passing it to another vat if it wants the remote end to be > able to persist it or reconnect after the TCP connection is closed. Yes. > * Calling makeSturdyRef creates a new Swiss base and, from that, a new > Swiss number. It adds a mapping from this to the object, in a map it > shares with the time machine. It then registers the object with the > IdentityMgr (so that clients can connect to it) and creates the > actual SturdyRef object with the Swiss number in it. Yes. > * Calling makeSturdyRef.temp is similar, except that it doesn't add > anything to the map shared with the time machine. Yes. > * The time machine works by saving the object graph starting from the > swiss-number-to-object mapping. Yes. > * Since makeSturdyRef(obj) makes a sturdy ref that lasts forever and > is persisted, and throws away the SwissRetainer used to cancel it, > refs made this way will accumulate forever. Not forever, but for the lifetime of the vat. So if the system is such that each Foo has a particular vat it, and only it runs in, it's perfectly fine to do makeSturdyRef(theFoo) after setting up the vat. > Many things cannot be serialised by default, including: > > - facets (obj.method) This is a bug, IMO, and probably due to the lack of availability of the persistence sealer as discussed below. > - caretakers This is a little tricky because it would be in general possible to serialize the caretaker but not the component which decides to revoke it. However, there is an (probably outdated) version of this called makeFancyRevoker in the Den <http://wiki.erights.org/wiki/Den> source code. > - promises In general, this is necessary. A promise becomes something else on some unspecified future event; that event is running code/messages in flight and cannot be serialized. If you have some activity that *can* be serialized (e.g. a promise for the result of a lengthy computation, which can be saved/restarted) then the proxy interface <http://wiki.erights.org/wiki/Proxy> can be used to create a promise which is also serializable (by handleOptSealedDispatch). > - near problems (bug in minimalUncaller?) Do you mean broken references? Could you provide details on this bug? > Persistence of sturdy refs > > A sturdy ref can only be serialised if fully resolved (is this a > bug?), > e.g. > > ? introducer.onTheAir() > ? def surgeon := <elib:serial.makeSurgeon>.withSrcKit("de: > ").diverge() > ? surgeon.addLoader(introducer, "cap__uriGetter") > ? def a > ? def b := makeSturdyRef.temp(3) > ? bind a := b > > ? surgeon.serialize(a) > # problem: Can't uneval <SturdyRef to 3> > > ? a == b > # value: true > > ? surgeon.serialize(b) > # value: "de: <cap://*qvcmrxvqy66rest6gfzhhxwrjni6nrdq@...:59905/jo6sk4nehnrewzo7bvntfz7rl32f6q2g > >" This is a bug; I have committed a fix. If a == b then nothing whatsoever (except for unsafe imports) should behave differently on a and b. Ref.resolution/1 should always be a no- op from the E user's perspective. The bug was that Introducer.optUncall performed an instanceof check without Ref.resolution first. > Persistence of cycles > > Some cyclic data structures can be persisted, while others can't (is > this a bug?). I haven't worked out what the rule is, but I do have > some examples: ... > Serializing [[<***CYCLE***>], [<***CYCLE***>]]... > Serialized as de: [def t__0 := [t__0], t__0] > # problem: <IndexOutOfBoundsException: not found: t__0> > > This is quite annoying, because a SwissRetainer includes a pointer to > its object, in addition to the pointer in the table for which the > retainer is a key. Therefore, an object containing a single cycle ends > up with the broken double-cycle structure when saved. This is a bug. Please send versions, test cases, patches, etc. The relevant code would be in esrc/org/erights/e/elib/serial/, deSubgraphKit, deASTKit, and deSrcKit. Since it mentions "t__0" as opposed to 0, probably deSrcKit. > Persistence of identity > > Transparent objects can implement __optUncall to allow them to be > persisted. This method returns all of the object's authority, proving > to the surgeon that it is permitted to be revived with it. However, > this also allows anyone else to get an object's authority by calling > __optUncall themselves. Yes. > Therefore, most objects should use __optSealedDispatch to seal the > result. There don't seem to be many examples of this (e.g. FileGetter > uses "obj instanceof File" instead). I'm having trouble seeing how to > use this. Should I add a new loader/uncaller? No, you should use the vat-wide persistence sealer, whose unsealer is closely held by the vat persistence system, in your __optSealedDispatch. If you seal your portrayal (what you would return from __optUncall) then you will get the behavior you want without any global definitions. Unfortunately, IIRC, the persistence sealer is also closely held, but there is no good reason for this. (MarkM, could you confirm this?) > How is identity handled? > e.g if I have a one-shot object, how can I ensure that an object > holding it will revive with only one copy of the one-shot object? > Similarly for a caretaker. If your object uncalls only by request of the vat persistence sealer, then you're guaranteed that its reincarnations will only be along with the rest of the vat state. So your one-shot might be rolled back to the not-yet-fired state, but everything else will be rolled back too and in sync. > Persistence of functions > > The result of uncalling an object is usually of the form [makeFoo, > "run", [...]], where makeFoo is a top-level function in some module. > Is there any way to get the time machine to handle these > automatically, without having to add them all as exists manually? The proper way for this to happen is that makeFoo is DeepFrozen. If this happens, then the <import> loader will automatically serve as a loader for your maker. Unfortunately, the guard-based auditing system has not yet been implemented in E-on-Java, so the DeepFrozen auditor to verify your maker as DeepFrozen cannot be used with E-on-Java, and only built-in objects can be DeepFrozen in E-on-Java. If you want to experiment with DeepFrozen you can use my own E-on-CL <http://wiki.erights.org/wiki/E-on-CL > which contains the DeepFrozen auditor. The workaround way, which I have used in Den, is to give the maker an __optUncall: --- begin makeFoo.emaker --- def makeFoo { to __optUncall() { return [<import>, "get", ["my.fqn.goes.here"]] } to run() { def foo { to __optUncall() { return [makeFoo, "run", []] } } return foo } } --- end makeFoo.emaker --- The fully-generic way to write that optUncall is: to __optUncall() { return [<import>, "get", [meta.context().getFQNPrefix().split("$") [0]]] } > My current solution is that every module looks like this: > > def makeFooInternal(state) { ... } > > def makeFoo() { ... } > > [ =>makeFoo, =>makeFooInternal ] A few comments: * This will not work if you use persistence in the conventional fashion: uncalls should typically correspond to calls, but here you have a map, which will uncall using the map constructor, rather than <import:makeFoo>. * Why are you using two objects instead of two methods on one object? * Particularly, "internal" is a bad concept: I can guess that you are using this for persistence of the state of an object, which you never expect to be constructed explicitly, but it is important to remember that the way in which you portray the objects for serialization is part of *THE PUBLIC INTERFACE* to your code, because other people's serialized data will contain it even when you publish a new version of your library/module/appplication. -- Kevin Reid <http://switchb.org/kpreid/> _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistenceOn Fri, 2009-08-28 at 19:15 -0400, Kevin Reid wrote:
> On Aug 28, 2009, at 10:27, Thomas Leonard wrote: [...] > > Many things cannot be serialised by default, including: > > > > - facets (obj.method) > > This is a bug, IMO, and probably due to the lack of availability of > the persistence sealer as discussed below. Would be nice to have. > > - near problems (bug in minimalUncaller?) > > Do you mean broken references? Could you provide details on this bug? def makeAtomicFile := <import:org.erights.e.extern.persist.makeAtomicFile> timeMachine.new() timeMachine.createAs(makeAtomicFile(<file:.>, "tmp")) introducer.onTheAir() makeSturdyRef(Ref.broken("foo")) timeMachine.save() gives: # problem: Can't uneval problem: foo But, oddly: def makeAnUncaller := <elib:serial.makeAnUncaller> def minimalUncaller := makeAnUncaller.getMinimalUncallers()[0] println(minimalUncaller.optUncall(Ref.broken("foo"))) gives: [<makeRef>, "broken", [problem: foo]] > > Persistence of sturdy refs > > > > A sturdy ref can only be serialised if fully resolved (is this a > > bug?), > This is a bug; I have committed a fix. Thanks. There's a similar bug with files: def makeAtomicFile := <import:org.erights.e.extern.persist.makeAtomicFile> timeMachine.new() timeMachine.createAs(makeAtomicFile(<file:.>, "tmp")) introducer.onTheAir() def a bind a := <file:foo.txt> makeSturdyRef(a) timeMachine.save() gives: # problem: Can't uneval <file:.../foo.txt> > > Persistence of cycles > > > > Some cyclic data structures can be persisted, while others can't (is > > this a bug?). I haven't worked out what the rule is, but I do have > > some examples: > ... > > Serializing [[<***CYCLE***>], [<***CYCLE***>]]... > > Serialized as de: [def t__0 := [t__0], t__0] > > # problem: <IndexOutOfBoundsException: not found: t__0> > > > > This is quite annoying, because a SwissRetainer includes a pointer to > > its object, in addition to the pointer in the table for which the > > retainer is a key. Therefore, an object containing a single cycle ends > > up with the broken double-cycle structure when saved. > > This is a bug. Please send versions, test cases, patches, etc. A minimal test case is: def surgeon := <elib:serial.makeSurgeon>.withSrcKit("de: ") surgeon.unserialize("de: [def t__0 := [t__0], t__0]") which gives: # problem: <IndexOutOfBoundsException: not found: t__0> Happens with the current release (0.9.2a) and svn versions of E. > > Persistence of identity [...] > > Therefore, most objects should use __optSealedDispatch to seal the > > result. There don't seem to be many examples of this (e.g. FileGetter > > uses "obj instanceof File" instead). I'm having trouble seeing how to > > use this. Should I add a new loader/uncaller? > > No, you should use the vat-wide persistence sealer, whose unsealer is > closely held by the vat persistence system, in your > __optSealedDispatch. If you seal your portrayal (what you would return > from __optUncall) then you will get the behavior you want without any > global definitions. > > Unfortunately, IIRC, the persistence sealer is also closely held, but > there is no good reason for this. (MarkM, could you confirm this?) > > > How is identity handled? > > e.g if I have a one-shot object, how can I ensure that an object > > holding it will revive with only one copy of the one-shot object? > > Similarly for a caretaker. > > If your object uncalls only by request of the vat persistence sealer, > then you're guaranteed that its reincarnations will only be along with > the rest of the vat state. So your one-shot might be rolled back to > the not-yet-fired state, but everything else will be rolled back too > and in sync. I think I still need more help here. A naive attempt would be: def makeOneShot(var used) { return def oneShot { to __optSealedDispatch(brand) { if (keyHolder.getTHE_BRAND() == brand) { def uncall := [makeOneShot, "run", [used]] return keyHolder.getTHE_SEALER().seal(uncall) } return null } to invoke() { if (used) { throw("Used up") } used := true println("Invoking!") } } } The idea here is that a oneShot can be used to print "Invoking!" only once, e.g. def myOneShot := makeOneShot(false) myOneShot.invoke() myOneShot.invoke() gives: Invoking! # problem: Used up But, since anyone can call __optSealedDispatch, an attacker can obviously make copies of my oneShot. e.g. def makeMimic(obj) { return def mimic { to __optSealedDispatch(brand) { return obj.__optSealedDispatch(brand) } } } def makeAttacker { to run(oneShot) { return def larva { to __optUncall() { return [makeAttacker, "revive", [oneShot, makeMimic(oneShot)]] } } } to revive(oneShotA, oneShotB) { oneShotA<-invoke() oneShotB<-invoke() return def obj { } } } My attacker gets persisted with a single oneShot, but revives with two (and can therefore print "Invoking!" twice). I suppose I could create a simple proxy to the oneShot and give that to the attacker. The attacker could make copies of the proxy, but they'd still all forward to a single oneShot. It seems clumsy and error-prone, though, and I'm not sure I've thought through all the implications. A simple example to copy from would be good. Thanks, -- Dr Thomas Leonard IT Innovation Centre 2 Venture Road Southampton Hampshire SO16 7NP Tel: +44 0 23 8076 0834 Fax: +44 0 23 8076 0833 mailto:tal@... http://www.it-innovation.soton.ac.uk _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistenceOn Tue, 2009-09-01 at 16:08 +0100, Thomas Leonard wrote:
> On Fri, 2009-08-28 at 19:15 -0400, Kevin Reid wrote: > > On Aug 28, 2009, at 10:27, Thomas Leonard wrote: [ snip persistence of facets, broken promises, files, cycles ] > > > Persistence of identity > [...] > > > Therefore, most objects should use __optSealedDispatch to seal the > > > result. There don't seem to be many examples of this (e.g. FileGetter > > > uses "obj instanceof File" instead). I'm having trouble seeing how to > > > use this. Should I add a new loader/uncaller? > > > > No, you should use the vat-wide persistence sealer, whose unsealer is > > closely held by the vat persistence system, in your > > __optSealedDispatch. If you seal your portrayal (what you would return > > from __optUncall) then you will get the behavior you want without any > > global definitions. > > > > Unfortunately, IIRC, the persistence sealer is also closely held, but > > there is no good reason for this. (MarkM, could you confirm this?) OK, I modified ScopeSetup to put a "persistence" object in safeScope (I couldn't see a way to do this from E). The main program binds this to an object with the brand and sealer, using a resolver in privScope. Is this sensible (at least as a work-around)? There are 48 separate objects in my program that need it, so I'm reluctant to start passing it around everywhere. I want to make it as easy as possible to serialise objects in a safe way; otherwise people will be tempted to __optUncall instead, I think. > > > How is identity handled? > > > e.g if I have a one-shot object, how can I ensure that an object > > > holding it will revive with only one copy of the one-shot object? > > > Similarly for a caretaker. > > > > If your object uncalls only by request of the vat persistence sealer, > > then you're guaranteed that its reincarnations will only be along with > > the rest of the vat state. So your one-shot might be rolled back to > > the not-yet-fired state, but everything else will be rolled back too > > and in sync. > > I think I still need more help here. A naive attempt would be: > My attacker gets persisted with a single oneShot, but revives with two > (and can therefore print "Invoking!" twice). > > I suppose I could create a simple proxy to the oneShot and give that to > the attacker. The attacker could make copies of the proxy, but they'd > still all forward to a single oneShot. Can someone confirm whether this is the correct approach? Thanks! -- Dr Thomas Leonard IT Innovation Centre 2 Venture Road Southampton Hampshire SO16 7NP Tel: +44 0 23 8076 0834 Fax: +44 0 23 8076 0833 mailto:tal@... http://www.it-innovation.soton.ac.uk _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistenceThomas Leonard wrote:
> OK, I modified ScopeSetup to put a "persistence" object in safeScope (I > couldn't see a way to do this from E). The main program binds this to an > object with the brand and sealer, using a resolver in privScope. Is this > sensible (at least as a work-around)? > > There are 48 separate objects in my program that need it, so I'm > reluctant to start passing it around everywhere. Why can't you just define it in an outer scope of your program, so that it is accessible to all nested scopes? -- David-Sarah Hopwood ⚥ http://davidsarah.livejournal.com _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistence (Attn MarkM: Possible surprise-vulnerability in persistence protocol)On Sep 14, 2009, at 11:08, Thomas Leonard wrote:
> On Tue, 2009-09-01 at 16:08 +0100, Thomas Leonard wrote: >> On Fri, 2009-08-28 at 19:15 -0400, Kevin Reid wrote: >>> No, you should use the vat-wide persistence sealer, whose unsealer >>> is >>> closely held by the vat persistence system, in your >>> __optSealedDispatch. If you seal your portrayal (what you would >>> return >>> from __optUncall) then you will get the behavior you want without >>> any >>> global definitions. >>> >>> Unfortunately, IIRC, the persistence sealer is also closely held, >>> but >>> there is no good reason for this. (MarkM, could you confirm this?) > > OK, I modified ScopeSetup to put a "persistence" object in safeScope > (I > couldn't see a way to do this from E). The main program binds this > to an > object with the brand and sealer, using a resolver in privScope. Is > this > sensible (at least as a work-around)? IMO, ScopeSetup should directly get the sealer from the PersistentKeyHolder, rather than having E-level code do it. There may be a reason to have more configurability than that though. MarkM, is there any reason the persistence sealer should not be widely available? > There are 48 separate objects in my program that need it, so I'm > reluctant to start passing it around everywhere. I want to make it as > easy as possible to serialise objects in a safe way; otherwise people > will be tempted to __optUncall instead, I think. __optUncall is appropriate for any 'data structure'-like (Transparent) object with no private state. >> I think I still need more help here. A naive attempt would be: > [...] >> My attacker gets persisted with a single oneShot, but revives with >> two >> (and can therefore print "Invoking!" twice). >> >> I suppose I could create a simple proxy to the oneShot and give >> that to >> the attacker. The attacker could make copies of the proxy, but they'd >> still all forward to a single oneShot. > > Can someone confirm whether this is the correct approach? I missed this point before. You're right - the persistence sealer protocol does not ensure uniqueness. This could be fixed in the protocol by including the object's own traversal key. But as a workaround, you can define the proxy as you describe. I would recommend making it part of the implementation of the oneShot, and not exposing its existence to the user. (One way to do it would be to have your oneShot serialize, not as its current state, but rather the slot of the used flag: def uncall := [makeOneShot, "withFlagSlot", [&used]]. Then the 'used' slot object serves as the un-duplicatable object. But this seems like a kludge, and I think we should fix the persistence protocol. Thanks for spotting this. MarkM, do you agree this is an excessively surprising problem? -- Kevin Reid <http://switchb.org/kpreid/> _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistenceOn Mon, 2009-09-14 at 19:18 +0100, David-Sarah Hopwood wrote:
> Thomas Leonard wrote: > > OK, I modified ScopeSetup to put a "persistence" object in safeScope (I > > couldn't see a way to do this from E). The main program binds this to an > > object with the brand and sealer, using a resolver in privScope. Is this > > sensible (at least as a work-around)? > > > > There are 48 separate objects in my program that need it, so I'm > > reluctant to start passing it around everywhere. > > Why can't you just define it in an outer scope of your program, so that > it is accessible to all nested scopes? Can I do that while keeping the objects in separate files? -- Dr Thomas Leonard IT Innovation Centre 2 Venture Road Southampton Hampshire SO16 7NP Tel: +44 0 23 8076 0834 Fax: +44 0 23 8076 0833 mailto:tal@... http://www.it-innovation.soton.ac.uk _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistence (Attn MarkM: Possible surprise-vulnerability in persistence protocol)On Mon, 2009-09-14 at 15:43 -0400, Kevin Reid wrote:
> On Sep 14, 2009, at 11:08, Thomas Leonard wrote: > > On Tue, 2009-09-01 at 16:08 +0100, Thomas Leonard wrote: [...] > > There are 48 separate objects in my program that need it, so I'm > > reluctant to start passing it around everywhere. I want to make it as > > easy as possible to serialise objects in a safe way; otherwise people > > will be tempted to __optUncall instead, I think. > > __optUncall is appropriate for any 'data structure'-like (Transparent) > object with no private state. Unfortunately, few of my classes are like that, and even a class which currently provides free access to all of its state might be extended later, and it would be easy to forget to switch to the secure version. Also, people are going to cut-and-paste my code when extending it, and they probably won't think about these things much while they're doing it, so I'd like to make it as hard as possible to get it wrong. > >> I think I still need more help here. A naive attempt would be: > > [...] > >> My attacker gets persisted with a single oneShot, but revives with > >> two > >> (and can therefore print "Invoking!" twice). > >> > >> I suppose I could create a simple proxy to the oneShot and give > >> that to > >> the attacker. The attacker could make copies of the proxy, but they'd > >> still all forward to a single oneShot. > > > > Can someone confirm whether this is the correct approach? > > I missed this point before. You're right - the persistence sealer > protocol does not ensure uniqueness. This could be fixed in the > protocol by including the object's own traversal key. > > But as a workaround, you can define the proxy as you describe. I would > recommend making it part of the implementation of the oneShot, and not > exposing its existence to the user. (One way to do it would be to have > your oneShot serialize, not as its current state, but rather the slot > of the used flag: def uncall := [makeOneShot, "withFlagSlot", > [&used]]. Then the 'used' slot object serves as the un-duplicatable > object. That's clever - thanks! > But this seems like a kludge, and I think we should fix the > persistence protocol. Thanks for spotting this. > > MarkM, do you agree this is an excessively surprising problem? -- Dr Thomas Leonard IT Innovation Centre 2 Venture Road Southampton Hampshire SO16 7NP Tel: +44 0 23 8076 0834 Fax: +44 0 23 8076 0833 mailto:tal@... http://www.it-innovation.soton.ac.uk _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistenceOn Thu, 2009-09-17 at 10:21 +0100, Thomas Leonard wrote:
> On Mon, 2009-09-14 at 15:43 -0400, Kevin Reid wrote: [...] > > But as a workaround, you can define the proxy as you describe. I would > > recommend making it part of the implementation of the oneShot, and not > > exposing its existence to the user. (One way to do it would be to have > > your oneShot serialize, not as its current state, but rather the slot > > of the used flag: def uncall := [makeOneShot, "withFlagSlot", > > [&used]]. Then the 'used' slot object serves as the un-duplicatable > > object. > > That's clever - thanks! Oops. I spoke too soon. Looks like only final slots can be persisted: # . <makeRef>.fulfillment(<ref broken by problem: Can't uneval <var false>>) -- Dr Thomas Leonard IT Innovation Centre 2 Venture Road Southampton Hampshire SO16 7NP Tel: +44 0 23 8076 0834 Fax: +44 0 23 8076 0833 mailto:tal@... http://www.it-innovation.soton.ac.uk _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistenceOn Sep 17, 2009, at 8:23, Thomas Leonard wrote:
> On Thu, 2009-09-17 at 10:21 +0100, Thomas Leonard wrote: >> On Mon, 2009-09-14 at 15:43 -0400, Kevin Reid wrote: > [...] >>> exposing its existence to the user. (One way to do it would be to >>> have >>> your oneShot serialize, not as its current state, but rather the >>> slot >>> of the used flag: def uncall := [makeOneShot, "withFlagSlot", >>> [&used]]. Then the 'used' slot object serves as the un-duplicatable >>> object. >> >> That's clever - thanks! > > Oops. I spoke too soon. Looks like only final slots can be persisted: > > # . <makeRef>.fulfillment(<ref broken by problem: Can't uneval > <var false>>) Gah. Sometimes I forget what's my own invention. MarkM, is there any reason not to add __optUncall to (unguarded) var slots? -- Kevin Reid <http://switchb.org/kpreid/> _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistence (Attn MarkM: Possible surprise-vulnerability in persistence protocol)Catching up now. Sorry for the long delay. I'd like to say it won't
happen again, but I'm likely to continue to be too busy for the foreseeable future (at least seven months). But I'll try to catch up again as I have the chance. On Mon, Sep 14, 2009 at 3:43 PM, Kevin Reid <kpreid@...> wrote: > On Sep 14, 2009, at 11:08, Thomas Leonard wrote: >> OK, I modified ScopeSetup to put a "persistence" object in safeScope >> (I couldn't see a way to do this from E). The main program binds this >> to an object with the brand and sealer, using a resolver in privScope. Is >> this sensible (at least as a work-around)? > > IMO, ScopeSetup should directly get the sealer from the > PersistentKeyHolder, rather than having E-level code do it. There may > be a reason to have more configurability than that though. > > MarkM, is there any reason the persistence sealer should not be widely > available? An oversight. This is a good plan. Thomas, feel free to submit a patch. Kevin, feel free to make a commitment along the lines you explain above. >> There are 48 separate objects in my program that need it, so I'm >> reluctant to start passing it around everywhere. I want to make it as >> easy as possible to serialise objects in a safe way; otherwise people >> will be tempted to __optUncall instead, I think. > > __optUncall is appropriate for any 'data structure'-like (Transparent) > object with no private state. > >>> I think I still need more help here. A naive attempt would be: >> [...] >>> My attacker gets persisted with a single oneShot, but revives with >>> two >>> (and can therefore print "Invoking!" twice). >>> >>> I suppose I could create a simple proxy to the oneShot and give >>> that to >>> the attacker. The attacker could make copies of the proxy, but they'd >>> still all forward to a single oneShot. >> >> Can someone confirm whether this is the correct approach? > > I missed this point before. You're right - the persistence sealer > protocol does not ensure uniqueness. This could be fixed in the > protocol by including the object's own traversal key. > > But as a workaround, you can define the proxy as you describe. I would > recommend making it part of the implementation of the oneShot, and not > exposing its existence to the user. (One way to do it would be to have > your oneShot serialize, not as its current state, but rather the slot > of the used flag: def uncall := [makeOneShot, "withFlagSlot", > [&used]]. Then the 'used' slot object serves as the un-duplicatable > object. > > But this seems like a kludge, and I think we should fix the > persistence protocol. Thanks for spotting this. > > MarkM, do you agree this is an excessively surprising problem? This is indeed excessively surprising. I'm not sure whether or not the slot solution is a kludge. The persistence of var-slots needs to be fixed regardless. -- Text by me above is hereby placed in the public domain Cheers, --MarkM _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Fixing the sealed persistence protocol (was Newbie questions about persistence)On Sep 19, 2009, at 11:42, Mark Miller wrote:
> On Mon, Sep 14, 2009 at 3:43 PM, Kevin Reid <kpreid@...> wrote: >> IMO, ScopeSetup should directly get the sealer from the >> PersistentKeyHolder, rather than having E-level code do it. There may >> be a reason to have more configurability than that though. >> >> MarkM, is there any reason the persistence sealer should not be >> widely >> available? > > An oversight. This is a good plan. Thomas, feel free to submit a > patch. Kevin, feel free to make a commitment along the lines you > explain above. Commitment? Do you mean commit? I'm not sure what exactly you mean -- that I should revise and commit Thomas's patch, or ...? >> But as a workaround, you can define the proxy as you describe. I >> would >> recommend making it part of the implementation of the oneShot, and >> not >> exposing its existence to the user. (One way to do it would be to >> have >> your oneShot serialize, not as its current state, but rather the slot >> of the used flag: def uncall := [makeOneShot, "withFlagSlot", >> [&used]]. Then the 'used' slot object serves as the un-duplicatable >> object. >> >> But this seems like a kludge, and I think we should fix the >> persistence protocol. Thanks for spotting this. >> >> MarkM, do you agree this is an excessively surprising problem? > > This is indeed excessively surprising. I'm not sure whether or not the > slot solution is a kludge. The persistence of var-slots needs to be > fixed regardless. The slot solution is a kludge because: - nontrivial objects may have state which is not naturally expressed *across upgrades* as one or more var slots. - it means the object may be constructed with its internal shared with other parties: this could violate invariants. - it is not a natural style to program in and creates additional visual noise in the program. - the maker provides degrees of freedom which are unrelated to the actual application. - the need for it IS unnecessarily surprising -- programmers will write accidentally insecure programs by not doing it. Let's think about how to fix the persistence protocol. What we want to achieve is that an object (henceforth referred to as the oneShot, even though this is general) may reveal a portrayal to the persistence subsystem, and thus be persistent, but with the guarantee that it will only be instantiated at most once in any given future vat incarnation. The problem with just returning a portrayal in a sealed box from __optSealedDispatch is that any other object can proxy its __optSealedDispatch to the oneShot and thus revive as a duplicate of it. So one fix would be to stuff the identity in the box and check it: # from org.erights.e.extern.persist.initTimeMachine def persistUncaller { to optUncall(obj) :nullOk[__Portrayal] { if (Ref.isNear(obj) && pUnsealer.amplify(obj) =~ \ [[==(makeTraversalKey(obj)), portrayal]]) { return portrayal } else { return null } } } def oneShot { to __optSealedDispatch(brand) { switch (brand) { match ==persistBrand { return persistSealer.seal(makeTraversalKey(oneShot), [makeOneShot, ...]) } }} } An oddball variation of this would be to put the object in the box and use it instead if the identities don't match: this would permit proxying __optSealedDispatch but change the behavior such that the proxying object is revived as the lone oneShot rather than a duplicate of it. def persistUncaller { to optUncall(obj) :nullOk[__Portrayal] { if (Ref.isNear(obj) && pUnsealer.amplify(obj) =~ [[objForIdentity, portrayal]]) { if (obj == objForIdentity) { return portrayal } else { return [__identityFunc, "run", objForIdentity] } } else { return null } } } def oneShot { to __optSealedDispatch(brand) { switch (brand) { match ==persistBrand { return persistSealer.seal(oneShot, [makeOneShot, ...]) } }} } Also, I note that org.erights.e.extern.persist.initTimeMachine's persistUncaller is currently equivalent to makeAmplifier in org.erights.e.elib.serial.makeAnUncaller except for requiring nearness. - Should all amplifying uncallers work in this same way? I have not considered the matter, but I would think this issue is likely to crop up similarly in other applications. - The nearness restriction should be dropped and the uncall made through Ref.optSealedDispatch. If a Proxy-ref wants to be persistent, let it. Given both of these changes, the persistUncaller is just makeAnUncaller.makeAmplifier(pUnsealer). -- Kevin Reid <http://switchb.org/kpreid/> _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Fixing the sealed persistence protocol (was Newbie questions about persistence)On Sat, Sep 19, 2009 at 12:32 PM, Kevin Reid <kpreid@...> wrote:
> On Sep 19, 2009, at 11:42, Mark Miller wrote: >> An oversight. This is a good plan. Thomas, feel free to submit a >> patch. Kevin, feel free to make a commitment along the lines you >> explain above. > > Commitment? Do you mean commit? I'm not sure what exactly you mean -- > that I should revise and commit Thomas's patch, or ...? I meant "commit". Whether this is a revision made directly by you or a revision of a patch submitted by Thomas I leave to the two of you. I am still chewing on the rest of your note. You make good points about the slot solution being a kludge. -- Text by me above is hereby placed in the public domain Cheers, --MarkM _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistenceOn Thu, Sep 17, 2009 at 3:06 PM, Kevin Reid <kpreid@...> wrote:
> On Sep 17, 2009, at 8:23, Thomas Leonard wrote: >> On Thu, 2009-09-17 at 10:21 +0100, Thomas Leonard wrote: >>> On Mon, 2009-09-14 at 15:43 -0400, Kevin Reid wrote: >> [...] >>>> exposing its existence to the user. (One way to do it would be to >>>> have >>>> your oneShot serialize, not as its current state, but rather the >>>> slot >>>> of the used flag: def uncall := [makeOneShot, "withFlagSlot", >>>> [&used]]. Then the 'used' slot object serves as the un-duplicatable >>>> object. >>> >>> That's clever - thanks! >> >> Oops. I spoke too soon. Looks like only final slots can be persisted: >> >> # . <makeRef>.fulfillment(<ref broken by problem: Can't uneval >> <var false>>) > > Gah. Sometimes I forget what's my own invention. > > MarkM, is there any reason not to add __optUncall to (unguarded) var > slots? I don't believe so. This seems like a good idea to me. -- Text by me above is hereby placed in the public domain Cheers, --MarkM _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistence (Attn MarkM: Possible surprise-vulnerability in persistence protocol)On Sat, 2009-09-19 at 11:42 -0400, Mark Miller wrote:
> On Mon, Sep 14, 2009 at 3:43 PM, Kevin Reid <kpreid@...> wrote: [...] > > IMO, ScopeSetup should directly get the sealer from the > > PersistentKeyHolder, rather than having E-level code do it. There may > > be a reason to have more configurability than that though. > > > > MarkM, is there any reason the persistence sealer should not be widely > > available? > > An oversight. This is a good plan. Thomas, feel free to submit a > patch. Kevin, feel free to make a commitment along the lines you > explain above. safej syntax, so I'm just guessing here. I didn't see any way to make just the getTHE_BRAND() and getTHE_SEALER() methods safe, whilst still allowing getTHE_UNSEALER() to be accessible using <unsafe>, so I made a new class. I named the class PersistentSealer (rather than PersistenceSealer) to match PersistentKeyHolder. The seal function takes an extra "self" parameter, currently ignored, in anticipation of Kevin's changes to the persistence protocol. Thanks, -- Dr Thomas Leonard IT Innovation Centre 2 Venture Road Southampton Hampshire SO16 7NP Tel: +44 0 23 8076 0834 Fax: +44 0 23 8076 0833 mailto:tal@... http://www.it-innovation.soton.ac.uk [0001-Make-the-persistence-brand-and-sealer-widely-availab.patch] >From 6b8526ba8c459fbfee036969a5c45fa81a67f425 Mon Sep 17 00:00:00 2001 From: Thomas Leonard <tal@...> Date: Thu, 24 Sep 2009 13:39:19 +0100 Subject: [PATCH] Make the persistence brand and sealer widely available See: http://www.eros-os.org/pipermail/e-lang/2009-September/013255.html ("Newbie questions about persistence") Patch provided by the University of Southampton IT Innovation Centre. --- .../erights/e/elib/serial/PersistentSealer.java | 56 ++++++++++++++++++++ .../erights/e/elib/serial/PersistentSealer.safej | 8 +++ 2 files changed, 64 insertions(+), 0 deletions(-) create mode 100644 src/jsrc/org/erights/e/elib/serial/PersistentSealer.java create mode 100644 src/safej/org/erights/e/elib/serial/PersistentSealer.safej diff --git a/src/jsrc/org/erights/e/elib/serial/PersistentSealer.java b/src/jsrc/org/erights/e/elib/serial/PersistentSealer.java new file mode 100644 index 0000000..6eb05e6 --- /dev/null +++ b/src/jsrc/org/erights/e/elib/serial/PersistentSealer.java @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////// +// +// © University of Southampton IT Innovation Centre, 2009 +// +// Copyright in this file belongs to the University of Southampton +// University Road, Highfield, Southampton, UK, SO17 1BJ +// +// This software may not be used, sold, licensed, transferred, copied +// or reproduced in whole or in part in any manner or form or in or +// on any media by any person other than in accordance with the terms +// of the Licence Agreement supplied with the software, or otherwise +// without the prior written consent of the copyright owners. +// +// This software is distributed WITHOUT ANY WARRANTY, without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE, except where stated in the Licence Agreement supplied with +// the software. +// +// Created By : Thomas Leonard +// Created Date : 2009-09-24 +// Created for Project : SERSCIS +// +///////////////////////////////////////////////////////////////////////// + +// Released under the terms of the MIT X license +// found at http://www.opensource.org/licenses/mit-license.html ............... + +package org.erights.e.elib.serial; + +import org.erights.e.elib.sealing.SealedBox; +import org.erights.e.elib.sealing.Brand; + +/** The public facet of the persistence sealer. + * Objects which are persistent but not transparent should seal their portrayal + * using this class to prevent other objects from getting hold of their authority. + * @author Thomas Leonard + */ +public class PersistentSealer { + private PersistentSealer() { + } + + static public Brand getBrand() { + return PersistentKeyHolder.THE_BRAND; + } + + /** Seal a portrayal using the persistence sealer. + * @param self the object being persisted + * @param contents the object's portrayal + * "self" is provided to prevent a man-in-the-middle attack, where one object + * forwards to another's __optSealedDispatch in order to revive with a new + * copy of the object. Currently, this parameter is ignored. + */ + static public SealedBox seal(Object self, Object contents) { + return PersistentKeyHolder.THE_SEALER.seal(contents); + } +} diff --git a/src/safej/org/erights/e/elib/serial/PersistentSealer.safej b/src/safej/org/erights/e/elib/serial/PersistentSealer.safej new file mode 100644 index 0000000..d43fe59 --- /dev/null +++ b/src/safej/org/erights/e/elib/serial/PersistentSealer.safej @@ -0,0 +1,8 @@ +# © University of Southampton IT Innovation Centre, 2009, +# under the terms of the MIT X license found at +# http://www.opensource.org/licenses/mit-license.html ................ + +class(safe, + "org.erights.e.elib.serial.PersistentSealer", + statics(method("getBrand()"), + method("seal(Object, Object)"))) -- 1.6.0.4 _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistence (Attn MarkM: Possible surprise-vulnerability in persistence protocol)On Sep 24, 2009, at 11:11, Thomas Leonard wrote:
> On Sat, 2009-09-19 at 11:42 -0400, Mark Miller wrote: >> On Mon, Sep 14, 2009 at 3:43 PM, Kevin Reid <kpreid@...> wrote: > [...] >>> IMO, ScopeSetup should directly get the sealer from the >>> PersistentKeyHolder, rather than having E-level code do it. There >>> may >>> be a reason to have more configurability than that though. >>> >>> MarkM, is there any reason the persistence sealer should not be >>> widely >>> available? >> >> An oversight. This is a good plan. Thomas, feel free to submit a >> patch. Kevin, feel free to make a commitment along the lines you >> explain above. > > OK, here's an attempt at a patch. Your PersistentSealer.java has a copyright statement contains specific language which is not the MIT license. I would prefer that this be removed and there only be two-line header as in other E files, to avoid any future problems. > I didn't find any documentation on the > safej syntax, so I'm just guessing here. I didn't see any way to make > just the getTHE_BRAND() and getTHE_SEALER() methods safe, whilst still > allowing getTHE_UNSEALER() to be accessible using <unsafe>, so I > made a > new class. This is unnecessary complexity. Just have ScopeSetup put the sealer in the safeScope. Though I'm not sure what the name of the object should be. MarkM? > I named the class PersistentSealer (rather than PersistenceSealer) to > match PersistentKeyHolder. I haven't liked the name of PersistentKeyHolder. It's not a holder of persistent keys, and so on. I'd rather see a consistent renaming to 'Persistence'. MarkM? > The seal function takes an extra "self" parameter, currently > ignored, in > anticipation of Kevin's changes to the persistence protocol. This doesn't feel appropriate to me; I can't quite say what the problem with it is though. It feels like something that ought to be 'utility' not 'primitive', in particular that the unrestricted sealing authority should be available. but I can't quite justify that. If nothing else, we should wait to invent such things until MarkM has finished chewing on the problem: <http://www.eros-os.org/pipermail/e-lang/2009-September/013261.html> I also don't like that you're using a StaticMaker to be the sealer object, but I don't have a justification for that either. -- Kevin Reid <http://switchb.org/kpreid/> _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistence (Attn MarkM: Possible surprise-vulnerability in persistence protocol)On Thu, Sep 24, 2009 at 9:20 AM, Kevin Reid <kpreid@...> wrote:
[out of order] >> I named the class PersistentSealer (rather than PersistenceSealer) to >> match PersistentKeyHolder. > > I haven't liked the name of PersistentKeyHolder. It's not a holder of > persistent keys, and so on. I'd rather see a consistent renaming to > 'Persistence'. MarkM? Yes, 'Persistence'. > This is unnecessary complexity. Just have ScopeSetup put the sealer in > the safeScope. Though I'm not sure what the name of the object should > be. MarkM? 'PersistenceSealer'? >> The seal function takes an extra "self" parameter, currently >> ignored, in >> anticipation of Kevin's changes to the persistence protocol. > > > This doesn't feel appropriate to me; I can't quite say what the > problem with it is though. It feels like something that ought to be > 'utility' not 'primitive', in particular that the unrestricted sealing > authority should be available. but I can't quite justify that. > > If nothing else, we should wait to invent such things until MarkM has > finished chewing on the problem: > <http://www.eros-os.org/pipermail/e-lang/2009-September/013261.html> > > I also don't like that you're using a StaticMaker to be the sealer > object, but I don't have a justification for that either. Please don't wait for me. I'm not sure when I'll have the bandwidth again. -- Text by me above is hereby placed in the public domain Cheers, --MarkM _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistence (Attn MarkM: Possible surprise-vulnerability in persistence protocol)On Sep 24, 2009, at 20:28, Mark Miller wrote:
>> This is unnecessary complexity. Just have ScopeSetup put the sealer >> in >> the safeScope. Though I'm not sure what the name of the object should >> be. MarkM? > > 'PersistenceSealer'? It's not a guard/type object, so 'persistenceSealer'. -- Kevin Reid <http://switchb.org/kpreid/> _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistence (Attn MarkM: Possible surprise-vulnerability in persistence protocol)On Thu, Sep 24, 2009 at 6:04 PM, Kevin Reid <kpreid@...> wrote:
> On Sep 24, 2009, at 20:28, Mark Miller wrote: > >>> This is unnecessary complexity. Just have ScopeSetup put the sealer >>> in >>> the safeScope. Though I'm not sure what the name of the object should >>> be. MarkM? >> >> 'PersistenceSealer'? > > It's not a guard/type object, so 'persistenceSealer'. +1 > -- > Kevin Reid <http://switchb.org/kpreid/> > > > > > _______________________________________________ > e-lang mailing list > e-lang@... > http://www.eros-os.org/mailman/listinfo/e-lang > -- Text by me above is hereby placed in the public domain Cheers, --MarkM _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
|
|
Re: Newbie questions about persistence (Attn MarkM: Possible surprise-vulnerability in persistence protocol)On Thu, 2009-09-24 at 12:20 -0400, Kevin Reid wrote:
> On Sep 24, 2009, at 11:11, Thomas Leonard wrote: > > On Sat, 2009-09-19 at 11:42 -0400, Mark Miller wrote: > >> On Mon, Sep 14, 2009 at 3:43 PM, Kevin Reid <kpreid@...> wrote: > > [...] > >>> IMO, ScopeSetup should directly get the sealer from the > >>> PersistentKeyHolder, rather than having E-level code do it. There > >>> may > >>> be a reason to have more configurability than that though. > >>> > >>> MarkM, is there any reason the persistence sealer should not be > >>> widely > >>> available? > >> > >> An oversight. This is a good plan. Thomas, feel free to submit a > >> patch. Kevin, feel free to make a commitment along the lines you > >> explain above. > > > > OK, here's an attempt at a patch. > > Your PersistentSealer.java has a copyright statement contains specific > language which is not the MIT license. I would prefer that this be > removed and there only be two-line header as in other E files, to > avoid any future problems. So would I, but it's company policy, and changing it may take months or years. Is there anything actually incompatible about the terms? Mainly it just states the obvious: that copyright law applies by default, with extra rights permitted by the license, and that we provide no warranty. [...] I'd be perfectly happy if you want to make a different patch along the lines you suggest, with your own header. I added the extra "self" parameter to make it easy to switch to the new persistence protocol later (i.e. slowly move things over to using the new API, then change the protocol). I don't much mind either way, though. -- Dr Thomas Leonard IT Innovation Centre 2 Venture Road Southampton Hampshire SO16 7NP Tel: +44 0 23 8076 0834 Fax: +44 0 23 8076 0833 mailto:tal@... http://www.it-innovation.soton.ac.uk _______________________________________________ e-lang mailing list e-lang@... http://www.eros-os.org/mailman/listinfo/e-lang |
| Free embeddable forum powered by Nabble | Forum Help |