IBM / java-async-util

Java utilities for working with CompletionStages
Apache License 2.0
59 stars 12 forks source link

Should we defend against sneaky completion? #4

Open rnarubin opened 6 years ago

rnarubin commented 6 years ago

Porting issue 37 from the enterprise repo

rkhadiwa commented on Nov 29, 2017

To what extent do we need to defend against a user who backdoors past the "read only" CompletionStage with cs.toCompletableFuture().complete(t) (or the more sinister cs.toCompletableFuture.obtrudeValue) ?

For example, AsyncFunnel gives out the same CompletableFuture to many distinct users. Not sure if there are any other APIs where this matters.

In JDK9 they added CompletableFuture.copy()/CompletableFuture.minimalStage presumably because they realized this is a problem. Should we defensively copy any CompletableFuture we hand out that could be reused? Seems pretty costly to defend against something that no sane user would actually do.

See http://cs.oswego.edu/pipermail/concurrency-interest/2016-July/015299.html

rnarubin commented 6 years ago

rnarubin commented on Dec 11, 2017

I'm sure that terrible things could be done with the futures returned by locks and semaphores. I think this comes down to how optimistic we are of our userbase. Nobody cooperative would do this, but if we imagine that some security conscious library wanted to use our library in their own (and exposed to other users) then this could become an attack vector. I don't know how far our responsibility can be expected to go though.

In a particularly narrow case where a future isn't transformed before returning to user space (straight from new CompletableFuture()) we could extend the class and override toCompletableFuture to return a copy. This would solve the malicious completion in AsyncFunnel and FairAsyncLock for example, and the cost would be minimal -- only the copy on a call to toCompletableFuture which as mentioned elsewhere is a pain in the ass method anyway. The only downside is that the safety isn't preserved across transformation, which means we'd have to carefully watch how we use such futures internally (once a user has called the transform our internal state is safe)