-
Notifications
You must be signed in to change notification settings - Fork 6k
8267485: Remove the dependency on SecurityManager in JceSecurityManager.java #4150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
👋 Welcome back wetmore! A progress list of the required criteria for merging this PR into |
@bradfordwetmore The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
List<StackFrame> stack = StackWalker.getInstance( | ||
StackWalker.Option.RETAIN_CLASS_REFERENCE) | ||
.walk((s) -> s.collect(Collectors.toList())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE) will require a permission check.
As long as the SecurityManager is still functional, doesn't this mean that creating the StackWalker should be performed in a doPrivileged? If so maybe it should be done in a (possibly static) initializer. Or is it intentional to check that the caller (and the whole calling stack) posses the RuntimePermission("getStackWalkerWithClassReference")
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, thanks.
final List<StackFrame> stack = AccessController.doPrivileged( | ||
(PrivilegedAction<List<StackFrame>>) | ||
() -> StackWalker.getInstance( | ||
Option.RETAIN_CLASS_REFERENCE) | ||
.walk((s) -> s.collect(Collectors.toList()))); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: StackWalker is a stateless capability object. It's not the walk() method that requires a permission, but the creation of the StackWalker itself (hence my suggestion to create it in the constructor, or in a static initializer). If you walk the stack from within a doPrivileged call then the doPrivileged frame will appear in the returned List<StackFrame>
; this may (or may not) be OK - depending on the logic that processes the stack.
You could consider simplifying:
PrivilegedAction<StackWalker> pa = () -> StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
final List<StackFrame> stack = AccessController.doPrivileged(pa).walk(Stream::toList);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I was going to step through this code more thoroughly today, hopefully I would have caught that.
This code is only needed in certain deployment and Cipher creation situations, so would rather not create a static CodeWalker that is not normally used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough.
@@ -45,9 +47,8 @@ | |||
* | |||
* @since 1.4 | |||
*/ | |||
|
|||
@SuppressWarnings("removal") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should remove this annotation now that the dependency on SecurityManager has been removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, we are still calling AccessController, thus the annotation needs to remain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But if you follow my suggestion you can simply apply it to this line:
@SuppressWarnings("removal")
final List<StackFrame> stack = AccessController.doPrivileged(pa).walk(Stream::toList);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the static initializer that needs updating: I could move the code out of the initializer up to the declaration, or I could create a dummy declaration and then assign to INSTANCE.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@seanjmullan , that's what I ended up doing. I'll have a new revision out as soon as the mach5 finishes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, I name the variable tmp
. There are cases where the action is a PrivlegedAction<Void>
and you still have to create a variable for the return value, and then I call it dummy
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove line 44 from the comments as it is no longer applicable:
-
Note that this security manager is never installed, only instantiated.
Also, you may want to rename this class to something other than JceSecurityManager to avoid future confusion, maybe "JcePolicyManager".
() -> StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE); | ||
@SuppressWarnings("removal") | ||
Optional<StackFrame> stackFrame = AccessController.doPrivileged(pa) | ||
.walk((s) -> s.skip(2).findFirst()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use the same StackWalker
instance in multiple places.
StackWalker::getCallerClass
is the API to get the caller class. You want to get the caller of the subclass of Cipher
in this case. So Cipher
constructor will call walker.getCallerClass()
and then pass it to isCallerTrusted
which will take an additional caller class parameter for validation.
() -> StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE); | ||
@SuppressWarnings("removal") | ||
List<StackFrame> stack = | ||
AccessController.doPrivileged(pa).walk(Stream::toList); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can replace line 108-125 with something like this:
StackWalker walker = AccessController.doPrivileged(pa);
Optional<URL> callerCodeBase = walker.walk(s -> {
s.map(f -> JceSecurity.getCodeBase(f.getDeclaringClass()))
.findFirst();
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mlchung Maybe there should be a .filter(cb -> cb != null)
inserted before .findFirst()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Daniel is right and it needs the filter to find the first non-null code base.
@bradfordwetmore This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good with some minor comments.
src/java.base/share/classes/javax/crypto/JceSecurityManager.java
Outdated
Show resolved
Hide resolved
@bradfordwetmore This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 14 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
The JBS issue should have an applicable |
/integrate |
Going to push as commit c8af823.
Your commit was automatically rebased without conflicts. |
@bradfordwetmore Pushed as commit c8af823. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
The JceSecurityManager is currently a subclass of java.security.SecurityManager. Now that JEP 411 has been integrated, this class should be updated to no longer subclass SecurityManager.
The only reason for using SecurityManager to easily get the Class Context (call stack), but we can achieve the same effect by using the JDK 9 API java.lang.StackWalkeer. None of the other SecurityManager API are used.
I have run mach5 tier1/tier2 plus --test jck:api/java_security,jck:api/javax_crypto,jck:api/javax_net,jck:api/javax_security,jck:api/org_ietf,jck:api/javax_xml/crypto with all green.
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/4150/head:pull/4150
$ git checkout pull/4150
Update a local copy of the PR:
$ git checkout pull/4150
$ git pull https://git.openjdk.java.net/jdk pull/4150/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 4150
View PR using the GUI difftool:
$ git pr show -t 4150
Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/4150.diff