On Thu, Jul 20, 2017 at 1:05 PM, Thomas Leonard <[email protected]> wrote:

> I did start off trying to implement it that way, but then I realised
> that questions don't usually hang around long anyway, so it didn't
> seem worth the effort.
>

Yes, that's probably the right decision.


> >> Maybe I got this bit wrong. I attached the "used" flags to the
> >> question, but maybe I should be tagging the reference to the question
> >> instead. Can different references to the same question need different
> >> disembargoes? e.g. should forwarding a message mark the promised
> >> answer as needing a disembargo or not?
> >
> > Sorry, I don't understand your question here.
>
> Maybe it doesn't make sense, or only with my implementation, but it
> seems we have two objects for a question/export:
>
> - a proxy that always sends to the remote peer
> - a switchable proxy that forwards to the previous object until the
> question returns, and then sends to the new target (possibly after a
> disembargo)
>
> I was just wondering which proxy should track whether it has been used
> (and, therefore, whether it needs a disembargo).
>
> If we had the implementor's guide that was mentioned earlier, it could
> probably cover this. My current implementation muddles these two up,
> which is why it's delivering things out of order, so my question is
> probably muddled up too. I'll need to think about this a bit more.
>

OK, makes sense.


> > Nice example!
> >
> > It looks like the C++ implementation today will decide b = q1.x, and
> never
> > allow it to further resolve to client_bs. This "works" but is clearly
> > suboptimal.
> >
> > For a correct solution, we need to recognize that Disembargo messages can
> > "bounce" multiple times:
>
> Does it alternate between being a disembargo request and a disembargo
> response as this happens?
>

It alternates between `senderLoopback` and `receiverLoopback`, yes.


> Does the 3-vat case complicate things?
>

Always. :) (But I haven't thought it through lately...)

-Kenton


> > On another note, you say you found this with AFL, which is amazing. Could
> > your fuzzing strategy be applied to the C++ implementation as well?
>
> Maybe. Here's how it works:
>
> To simplify things, my OCaml capnp-rpc library is in two parts. One
> provides the RPC logic over abstract message types, and the other
> provides an implementation using the Cap'n Proto serialisation for the
> messages. Most of the unit-tests check the core logic directly, using
> a simpler message type where a payload is just a test string and an
> array of capability pointers. The fuzz tests use a mutable struct with
> things useful for checking for violations.
>
> The fuzz tests set up some vats (two or three) in a single process and
> then have them perform operations based on input from the fuzzer.
> Each step selects one vat and performs a random (fuzzer-chosen)
> operation out of:
>
> 1. Request a bootstrap capability from a random peer.
> 2. Handle one message on the incoming queue.
> 3. Call a random capability, passing randomly-selected capabilities as
> arguments.
> 4. Finish a random question.
> 5. Release a random capability.
> 6. Add a capability to a newly-created local service.
> 7. Answer a random question, passing random-selected capabilities as
> the response.
>
> When it runs out of input data from the fuzzer it releases all
> capabilities, answers all questions and allows the system to become
> idle.
>
> The fuzz tests include in the call's payload contents a sequence
> number and a (mutable) struct containing the source reference's
> counters:
>
> type cap_ref_counters = {
>   mutable next_to_send : int;
>   mutable next_expected : int;
> }
>
> When the message arrives, the target service checks that the counter
> in the content matches the current value of `next_expected` and
> increments it.
> So, it should always detect if messages arrive out of order.
>
> Another way it takes advantage of everything running in one process is
> that it maintains a second reference graph, but one which doesn't use
> CapTP. When it requests a bootstrap capability over CapTP, it also
> returns a direct pointer to the target service. So, it's a copy of the
> reference graph but with all vat-spanning links replaced with direct
> pointers. Then, it checks that every message is delivered to the
> service it would have been delivered to if there were no network in
> the way.
>
> I leave AFL running my binary for a while with the --fuzz option
> (which disables logging to keep things fast).
> When it finds a violation it leaves it in the crash directory. Then I
> run the fuzz binary on it manually without --fuzz, which turns on
> logging and runs a load of sanity checks at each step, as well as
> dumping the state of the system at each step. It also outputs an OCaml
> unit-test, which can be cut-and-pasted into the test-suite. The
> unit-tests look like this, after being cleaned up a bit:
>
> https://github.com/mirage/capnp-rpc/blob/f5a32455c41056eaa40
> b3074f1cfb33741854e69/test/test.ml#L462
>
> If the test-case is too long, afl-tmin can often shorten it.
>
> There are plenty of other things it could be made to check, e.g. that
> forked references can't access anything before their parent, that
> messages to valid targets are always eventually delivered, that after
> letting the system become idle all references point directly to the
> vat containing their target in the direct reference graph, that
> malicious vats can't cause protocol violations in connections between
> good vats, etc. However, I have enough bugs to fix with the current
> tests ;-)
>
> I don't know if that's any use to you - I'm not sure how the C++ code
> is structured.
>
>
> --
> talex5 (GitHub/Twitter)        http://roscidus.com/blog/
> GPG: 5DD5 8D70 899C 454A 966D  6A51 7513 3C8F 94F6 E0CC
>

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
Visit this group at https://groups.google.com/group/capnproto.

Reply via email to