On 26/04/2022 6:28 pm, Alan Bateman wrote:
On 25/04/2022 13:53, David Lloyd wrote:
Nothing in the proposal causes splitting or delegation of
responsibilities. It is _only_ about preserving security checkpoints
in the JDK, which *add* a layer of checks to what the container might
already provide. Nothing is being subtracted, and thus I find it hard
to accept that preserving these checks somehow reduces security
overall.

"preserving security checkpoints in the JDK" suggests just leaving the calls do AccessController.doPrivileged and SecurityManager.checkPermission in place. That amounts to putting a tax on every feature, every JEP, and all ongoing maintenance of the platform. If there is refactoring or a change that forgets to insert a checkPermission somewhere then we have a security issue and everything that goes along with that. No thanks!

What about ensuring that all network access occurs through a single location that we can instrument?

It would be nice to leave AccessController calls in place, oh well, such is life.



I think Martin is right that hooking authorization libraries into low level libraries isn't the right way to do this. Aside from the complexity methods I would add that threads pools or any hand-off between threads will typically break when the context is not carried.


Yes, we went to a lot of trouble to ensure context is preserved through executors and other thread calls, for executors, it was simple enough to decorate a Callable.   However this is successful, in that our RemoteEvent's and Event listeners use the preserved AccessControlContext to establish and authenticate secure connections.



One other point about authorization libraries wanting to hook into low level code is that it's a minefield of potential issues with recursive initialization, stack overflows and some really hard to diagnose issues. JDK-8155659 [1] is one report that comes to mind.

Yes, I have also come across this problem, I use a thread local to detect the recursion, in try finally blocks.

https://github.com/pfirmstone/JGDMS/blob/c1edf5892306f24f8f97f459f499dec54984b08f/JGDMS/jgdms-platform/src/main/java/org/apache/river/api/security/CombinerSecurityManager.java#L347

One must also be aware of class loading, to ensure necessary classes are loaded at the right time.

The following is an example of a complex issue, which was solved using immutability, by avoiding shared state between threads and avoiding blocking where possible.   Java's PermissionCollection implementations are a minefield of synchronization, so we thread confined PermissionCollection.   We avoided caching permission check results as Java's policy cache is a huge performance killer.  There is also the issue of DNS calls made in URL and URLClassLoader, so we fixed those issues too.  Instead of relying on DNS we use RFC3986 and RFC5952 normalization.   The performance difference as you might imagine by removing blocking network calls and replacing it with immutable normalized forms was huge.

https://github.com/pfirmstone/JGDMS/blob/c1edf5892306f24f8f97f459f499dec54984b08f/JGDMS/jgdms-platform/src/main/java/net/jini/security/policy/DynamicPolicyProvider.java#L265

https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/jgdms-platform/src/main/java/org/apache/river/api/security/ConcurrentPolicyFile.java


-Alan

[1] https://bugs.openjdk.java.net/browse/JDK-8155659

It's just such a shame that we achieved so much and OpenJDK is pulling the rug from underneath us.

Regards,

Peter.

Reply via email to