You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@river.apache.org by Peter <ji...@zeus.net.au> on 2011/12/10 06:12:28 UTC

Re: Implications for Security Checks - SocketPermission, URL and DNS lookups

Actually, my last comment about executor based parallel protection domain security checks, it is possible (in spite of AccessControlContext being declared final), by using a domain combiner to merge all protectiondomain's on the stack into callable tasks and returning one ProtectionDomain that contains all these tasks, when implies is called, it submits all tasks to an executor, the first task to return false causes the Protectiondomain's implies method to return false, while the rest are cancelled using the thread interrupt status.  The policy could check the interrupt status at execution check points and return early if interrupted.

Since a policy is mostly read, occasional write, this could speed execution considerably, especially when permission checks require network or file access and there are a number of ProtectionDomain's on the stack.

Cheers,

Peter.

----- Original message -----
> DNS lookups and reverse lookups caused by URL and SocketPermission,
> equals, hashCode and implies methods create some serious performance
> problems for distributed programs.
>
> The concurrent policy implementation I've been working on reduces lock
> contention between threads performing security checks.
>
> When the SecurityManager is used to check a guard, it calls the
> AccessController, which retrieves the AccessControlContext from the call
> stack, this contains all the ProtectionDomain's on the call stack (I
> won't go into privileged calls here), if a ProtectionDomain is dynamic
> it will consult the Policy, prior to checking the static permissions it
> contains.
>
> The problem with the old policy implementation is lock contention caused
> by multiple threads all using multiple ProtectionDomains, when the time
> taken to perform a check is considerable, especially where identical
> security checks might be performed by multiple threads executing the
> same code.
>
> Although concurrent policy reduces contention between ProtectionDomain's
> calls to Policy.implies, there remain some fundamental problems with the
> implementations of SocketPermission and URL, that cause unnecessary DNS
> lookups during equals(), hashCode() and implies() methods.
>
> The following bugs concern SocketPermission (please read before
> continuing) :
>
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6592285
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4975882 - contains a
> lot of valuable comments.
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4671007 - fixed,
> perhaps incorrectly.
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6501746
>
> Anyway to cut a long story short, DNS lookups and DNS reverse lookups
> are performed for the equals and hashCode implementations in
> SocketPermission and URL, with disastrous performance implications for
> policy implementations using collections and caching security permission
> check results.
>
> For example, once a SocketPermission guard has been checked for a
> specific AccessContolContext the result is cached by my SecurityManager,
> avoiding repeat security checks, however if that cache contains
> SocketPermission, DNS lookups will be required, the cache will perform
> slower than some other directly performed security checks!  The cache is
> intended to return quickly to avoid reconsulting every ProtectionDomain
> on the stack.
>
> To make matters worse, when checking a SocketPermission guard, the DNS
> may be consulted for every non wild card SocketPermission contained
> within a SocketPermissionCollection, up until it is implied.  DNS checks
> are being made unnecessarily, since the wild card that matches may not
> require a DNS lookup at all, but because the non matching
> SocketPermission's are being checked first, the DNS lookups and reverse
> lookups are still performed.  This could be fixed completely, by moving
> the responsibility of DNS lookups from SocketPermission to
> SocketPermissionCollection.
>
> The identity of two SocketPermission's are equal if they resolve to the
> same IP address, but their hashCode's are different! See bug 6592623.
>
> The identity of a SocketPermission with an IP address and a DNS name,
> resolving to identical IP address should not (in my opinion) be equal,
> but is!  One SocketPermission should only imply the other while DNS
> resolves to the same IP address, otherwise the equality of the two
> SocketPermission's will change if the IP address is assigned to a
> different domain!  Object equality / identity shouldn't depend on the
> result of a possibly unreliable network source.
>
> SocketPermission and SocketPermissionCollection are broken, the only
> solution I can think of is to re-implement these classes (from Harmony)
> in the policy and SecurityManager, substituting the existing jvm
> classes.  This would not be visible to client developers.
>
> SocketPermission's may also exist in a ProtectionDomain's static
> Permissions, these would have to be converted by the policy when merging
> the permissions from the ProtectionDomain with those from the policy. 
> Since ProtectionDomain, attempts to check it's own internal permissions,
> after the policy permission check fails, DNS checks are currently
> performed by duplicate SocketPermission's residing in the
> ProectionDomain, this will no longer occur, since the permission being
> checked will be converted to say for argument sake
> org.apache.river.security.SocketPermission.  However because some
> ProtectionDomains are static, they never consult the policy, so the
> Permission's contained in each ProtectionDomain will require conversion
> also, to do so will require extending and implementing a
> ProtectionDomain that encapsulates existing ProtectionDomain's in the
> AccessControlContext, by utilising a DomainCombiner.
>
> For CodeSource grant's, the policy file based grant's are defined by
> URL's, however URL's identity depend upon DNS record results, similar to
> SocketPermission equals and hashCode implementations which we have no
> control over.
>
> I'm thinking about implementing URI based grant's instead, to avoid DNS
> lookups, then allowing a policy compatibility mode to be enabled (with
> logging) for falling back to CodeSource grant's when a URL cannot be
> converted to a URI, this is a much simpler fix than the SocketPermission
> problem.
>
> For Dynamic Policy Grants, because ProtectionDomain doesn't override
> equals (that's a good thing), the contained CodeSource must also be
> checked, again potentially slowing down permission checks with DNS
> lookups, simply because CodeSource uses URL's.  Changing the Dynamic
> Grant's to use URI based comparison would be relatively simple, since
> the URI is obtained dynamically when the dynamic grant is created.
>
> URI based grant's don't use DNS resolution and would have a narrower
> scope of implied CodeSources, an IP based grant won't imply a DNS domain
> URL based CodeSource and vice versa.  Rather than rely on DNS
> resolution, grant's could be made specifically for IPv4, IPv6 and DNS
> names in policy files.  URL.toURI() can be utilised to check if URI
> grant's imply a CodeSource without resorting to DNS.
>
> Any thoughts, comments or ideas?
>
> N.B. It's sad that security is implemented the way it is, it would be
> far better if it was Executor based, since every protection domain could
> be checked in parallel, rather than in sequence.
>
> Regards,
>
> Peter.
>
>