Skip to content

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

Closed
wants to merge 24 commits into from
Closed

8267485: Remove the dependency on SecurityManager in JceSecurityManager.java #4150

wants to merge 24 commits into from

Conversation

bradfordwetmore
Copy link
Contributor

@bradfordwetmore bradfordwetmore commented May 22, 2021

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

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed

Issue

  • JDK-8267485: Remove the dependency on SecurityManager in JceSecurityManager.java

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

@bridgekeeper
Copy link

bridgekeeper bot commented May 22, 2021

👋 Welcome back wetmore! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented May 22, 2021

@bradfordwetmore The following label will be automatically applied to this pull request:

  • security

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.

@openjdk openjdk bot added the security security-dev@openjdk.org label May 22, 2021
@bradfordwetmore bradfordwetmore marked this pull request as ready for review June 2, 2021 17:53
@openjdk openjdk bot added the rfr Pull request is ready for review label Jun 2, 2021
@mlbridge
Copy link

mlbridge bot commented Jun 2, 2021

Webrevs

@bradfordwetmore bradfordwetmore marked this pull request as draft June 2, 2021 18:08
@openjdk openjdk bot removed the rfr Pull request is ready for review label Jun 2, 2021
Comment on lines 105 to 107
List<StackFrame> stack = StackWalker.getInstance(
StackWalker.Option.RETAIN_CLASS_REFERENCE)
.walk((s) -> s.collect(Collectors.toList()));
Copy link
Member

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")?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thanks.

@bradfordwetmore bradfordwetmore marked this pull request as ready for review June 2, 2021 23:29
@openjdk openjdk bot added the rfr Pull request is ready for review label Jun 2, 2021
Comment on lines 106 to 111
final List<StackFrame> stack = AccessController.doPrivileged(
(PrivilegedAction<List<StackFrame>>)
() -> StackWalker.getInstance(
Option.RETAIN_CLASS_REFERENCE)
.walk((s) -> s.collect(Collectors.toList())));

Copy link
Member

@dfuch dfuch Jun 3, 2021

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);

Copy link
Contributor Author

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.

Copy link
Member

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")
Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

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);

Copy link
Contributor Author

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latter is probably better so you don't have to move the code; @wangweij used this technique quite a bit for JEP 411 refactoring, see 508cec7

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Member

@seanjmullan seanjmullan left a 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());
Copy link
Member

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);
Copy link
Member

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();
});

Copy link
Member

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()?

Copy link
Member

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.

@bridgekeeper
Copy link

bridgekeeper bot commented Jul 14, 2021

@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!

Copy link
Member

@mlchung mlchung left a 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.

@openjdk
Copy link

openjdk bot commented Jul 27, 2021

@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:

8267485: Remove the dependency on SecurityManager in JceSecurityManager.java

Reviewed-by: mchung

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 master branch:

  • 45d277f: 8270308: Arena::Amalloc may return misaligned address on 32-bit
  • fde1831: 8212961: [TESTBUG] vmTestbase/nsk/stress/jni/ native code cleanup
  • bb508e1: 8269753: Misplaced caret in PatternSyntaxException's detail message
  • c3d8e92: 8190753: (zipfs): Accessing a large entry (> 2^31 bytes) leads to a negative initial size for ByteArrayOutputStream
  • eb6da88: Merge
  • b76a838: 8269150: UnicodeReader not translating \u005c\u005d to \]
  • 7ddabbf: 8271175: runtime/jni/FindClassUtf8/FindClassUtf8.java doesn't have to be run in othervm
  • 3c27f91: 8271222: two runtime/Monitor tests don't check exit code
  • 049b2ad: 8015886: java/awt/Focus/DeiconifiedFrameLoosesFocus/DeiconifiedFrameLoosesFocus.java sometimes failed on ubuntu
  • fcc7d59: 8269342: CICrashAt=1 does not always catch first Java method
  • ... and 4 more: https://git.openjdk.java.net/jdk/compare/efa63dc1c64db357eeb497d2e1fefd170ca22d98...master

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 master branch, type /integrate in a new comment.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Jul 27, 2021
@seanjmullan
Copy link
Member

The JBS issue should have an applicable noreg label. Perhaps noreg-other with a comment about the existing tests that have been run.

@bradfordwetmore
Copy link
Contributor Author

/integrate

@openjdk
Copy link

openjdk bot commented Jul 27, 2021

Going to push as commit c8af823.
Since your change was applied there have been 16 commits pushed to the master branch:

  • ea49691: 8270794: Avoid loading Klass* twice in TypeArrayKlass::oop_size()
  • fc80a6b: 8270946: X509CertImpl.getFingerprint should not return the empty String
  • 45d277f: 8270308: Arena::Amalloc may return misaligned address on 32-bit
  • fde1831: 8212961: [TESTBUG] vmTestbase/nsk/stress/jni/ native code cleanup
  • bb508e1: 8269753: Misplaced caret in PatternSyntaxException's detail message
  • c3d8e92: 8190753: (zipfs): Accessing a large entry (> 2^31 bytes) leads to a negative initial size for ByteArrayOutputStream
  • eb6da88: Merge
  • b76a838: 8269150: UnicodeReader not translating \u005c\u005d to \]
  • 7ddabbf: 8271175: runtime/jni/FindClassUtf8/FindClassUtf8.java doesn't have to be run in othervm
  • 3c27f91: 8271222: two runtime/Monitor tests don't check exit code
  • ... and 6 more: https://git.openjdk.java.net/jdk/compare/efa63dc1c64db357eeb497d2e1fefd170ca22d98...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot closed this Jul 27, 2021
@openjdk openjdk bot added integrated Pull request has been integrated and removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Jul 27, 2021
@openjdk
Copy link

openjdk bot commented Jul 27, 2021

@bradfordwetmore Pushed as commit c8af823.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
integrated Pull request has been integrated security security-dev@openjdk.org
Development

Successfully merging this pull request may close these issues.

5 participants