Skip to content
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

8318756 Create better internal buffer for AEADs #16487

Closed
wants to merge 15 commits into from

Conversation

ascarpino
Copy link
Contributor

@ascarpino ascarpino commented Nov 3, 2023

Hi,

I need a review for a new internal buffer class called AEADBufferStream. AEADBufferStream extends ByteArrayOutputStream, but eliminates some data checking and copying that are not necessary for what GaloisCounterMode.java and ChaCha20Cipher.java need.

The changes greatest benefit is with decryption operations. ChaCha20-Poly1305 had larger performance gains by adopting similar techniques that AES/GCM already uses.

The new buffer shows up to 21% bytes/sec performance increase for decryption for ChaCha20-Poly1305 and 12% for AES/GCM. 16K data sizes saw a memory usage reduction of 46% with and 83% with ChaCha20-Poly1305. These results come from the JMH tests updated in this request and memory usage using the JMH gc profile gc.alloc.rate.norm entry

thanks

Tony


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8318756: Create better internal buffer for AEADs (Enhancement - P3)

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/16487/head:pull/16487
$ git checkout pull/16487

Update a local copy of the PR:
$ git checkout pull/16487
$ git pull https://git.openjdk.org/jdk.git pull/16487/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 16487

View PR using the GUI difftool:
$ git pr show -t 16487

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/16487.diff

Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Nov 3, 2023

👋 Welcome back ascarpino! 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 Nov 3, 2023

@ascarpino 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 Nov 3, 2023
@ascarpino
Copy link
Contributor Author

Noteworthy perf data (ops/sec)

Benchmark dataMethod dataSize AEADBuffer jdk-dev  Diff
CC20P1305ByteBuffer.decrypt direct 1024 577804.81 549630.383 105.13%
CC20P1305ByteBuffer.decrypt direct 1500 424441.663 401452.037 105.73%
CC20P1305ByteBuffer.decrypt direct 4096 186333.196 152909.993 121.86%
CC20P1305ByteBuffer.decrypt direct 16384 49698.562 41966.387 118.42%
CC20P1305ByteBuffer.decrypt heap 1024 586145.31 514277.384 113.97%
CC20P1305ByteBuffer.decrypt heap 1500 429055.718 380859.773 112.65%
CC20P1305ByteBuffer.decrypt heap 4096 179807.069 179241.327 100.32%
CC20P1305ByteBuffer.decrypt heap 16384 51096.478 51097.68 100.00%
CC20P1305ByteBuffer.decryptMultiPart direct 1024 553804.884 506750.657 109.29%
CC20P1305ByteBuffer.decryptMultiPart direct 1500 399307.809 365691.011 109.19%
CC20P1305ByteBuffer.decryptMultiPart direct 4096 180940.646 165152.892 109.56%
CC20P1305ByteBuffer.decryptMultiPart direct 16384 49117.754 40808.57 120.36%
CC20P1305ByteBuffer.decryptMultiPart heap 1024 567976.828 539087.765 105.36%
CC20P1305ByteBuffer.decryptMultiPart heap 1500 415070.529 400061.343 103.75%
CC20P1305ByteBuffer.decryptMultiPart heap 4096 180878.684 178758.204 101.19%
CC20P1305ByteBuffer.decryptMultiPart heap 16384 48541.737 46645.72 104.06%
AESGCMByteBuffer.decrypt heap 1024 1826361.53 1796033.97 101.69%
AESGCMByteBuffer.decrypt heap 1500 1245406.42 1109318.44 112.27%
AESGCMByteBuffer.decrypt heap 4096 641359.437 617315.646 103.89%
AESGCMByteBuffer.decrypt heap 16384 247719.061 238448.044 103.89%
AESGCMByteBuffer.decryptMultiPart direct 1024 1574668.85 1483599.15 106.14%
AESGCMByteBuffer.decryptMultiPart direct 1500 1172906.6 1100561.62 106.57%
AESGCMByteBuffer.decryptMultiPart direct 4096 545868.754 513626.344 106.28%
AESGCMByteBuffer.decryptMultiPart direct 16384 170901.637 152173.375 112.31%
AESGCMByteBuffer.decryptMultiPart heap 1024 1889488.77 1759824.14 107.37%
AESGCMByteBuffer.decryptMultiPart heap 1500 1355897.08 1289243.83 105.17%
AESGCMByteBuffer.decryptMultiPart heap 4096 650425.638 622200.295 104.54%
AESGCMByteBuffer.decryptMultiPart heap 16384 235059.195 226745.378 103.67%

Memory reduction (bytes / op)

Benchmark (dataMethod) (dataSize) AEADBuffer jdk-dev  Reduction
CC20P1305ByteBuffer.decrypt:gc.alloc.rate.norm direct 1024 3600.006 5704.006 36.89%
CC20P1305ByteBuffer.decrypt:gc.alloc.rate.norm direct 1500 4080.008 6664.008 38.78%
CC20P1305ByteBuffer.decrypt:gc.alloc.rate.norm direct 4096 6672.018 28280.022 76.41%
CC20P1305ByteBuffer.decrypt:gc.alloc.rate.norm direct 16384 18960.069 102040.082 81.42%
CC20P1305ByteBuffer.decrypt:gc.alloc.rate.norm heap 1024 2544.006 3608.007 29.49%
CC20P1305ByteBuffer.decrypt:gc.alloc.rate.norm heap 1500 2544.008 3608.009 29.49%
CC20P1305ByteBuffer.decrypt:gc.alloc.rate.norm heap 4096 2544.019 3608.019 29.49%
CC20P1305ByteBuffer.decrypt:gc.alloc.rate.norm heap 16384 2544.068 3608.068 29.49%
CC20P1305ByteBuffer.decryptMultiPart:gc.alloc.rate.norm direct 1024 3688.006 9352.007 60.56%
CC20P1305ByteBuffer.decryptMultiPart:gc.alloc.rate.norm direct 1500 4168.009 11032.009 62.22%
CC20P1305ByteBuffer.decryptMultiPart:gc.alloc.rate.norm direct 4096 6760.019 24232.021 72.10%
CC20P1305ByteBuffer.decryptMultiPart:gc.alloc.rate.norm direct 16384 19048.07 114344.084 83.34%
CC20P1305ByteBuffer.decryptMultiPart:gc.alloc.rate.norm heap 1024 4200.006 6728.006 37.57%
CC20P1305ByteBuffer.decryptMultiPart:gc.alloc.rate.norm heap 1500 4920.008 7208.008 31.74%
CC20P1305ByteBuffer.decryptMultiPart:gc.alloc.rate.norm heap 4096 8808.019 13928.019 36.76%
CC20P1305ByteBuffer.decryptMultiPart:gc.alloc.rate.norm heap 16384 27240.071 44648.074 38.99%
CC20P1305Bench.decrypt:gc.alloc.rate.norm   1024 2544.006 3608.007 29.49%
CC20P1305Bench.decrypt:gc.alloc.rate.norm   1500 2544.008 3608.009 29.49%
CC20P1305Bench.decrypt:gc.alloc.rate.norm   4096 2544.02 3608.019 29.49%
CC20P1305Bench.decrypt:gc.alloc.rate.norm   16384 2544.067 3608.068 29.49%
CC20P1305Bench.decryptMultiPart:gc.alloc.rate.norm   1024 4200.006 6728.006 37.57%
CC20P1305Bench.decryptMultiPart:gc.alloc.rate.norm   1500 4920.008 7208.008 31.74%
CC20P1305Bench.decryptMultiPart:gc.alloc.rate.norm   4096 8808.019 13928.019 36.76%
CC20P1305Bench.decryptMultiPart:gc.alloc.rate.norm   16384 27240.07 44648.073 38.99%
AESGCMByteBuffer.decryptMultiPart:gc.alloc.rate.norm direct 1024 3240.002 4248.002 23.73%
AESGCMByteBuffer.decryptMultiPart:gc.alloc.rate.norm direct 1500 4344.003 5832.003 25.51%
AESGCMByteBuffer.decryptMultiPart:gc.alloc.rate.norm direct 4096 6312.006 10392.007 39.26%
AESGCMByteBuffer.decryptMultiPart:gc.alloc.rate.norm direct 16384 41704.021 58072.023 28.19%
AESGCMByteBuffer.decryptMultiPart:gc.alloc.rate.norm heap 1024 1704.002 2184.002 21.98%
AESGCMByteBuffer.decryptMultiPart:gc.alloc.rate.norm heap 1500 2040.003 2760.003 26.09%
AESGCMByteBuffer.decryptMultiPart:gc.alloc.rate.norm heap 4096 3240.005 5256.006 38.36%
AESGCMByteBuffer.decryptMultiPart:gc.alloc.rate.norm heap 16384 9328.015 17488.016 46.66%
AESGCMBench.decryptMultiPart:gc.alloc.rate.norm   1024 1736.002 2216.002 21.66%
AESGCMBench.decryptMultiPart:gc.alloc.rate.norm   1500 2016.002 2848.002 29.21%
AESGCMBench.decryptMultiPart:gc.alloc.rate.norm   4096 3272.005 5288.005 38.12%
AESGCMBench.decryptMultiPart:gc.alloc.rate.norm   16384 9304.014 17464.015 46.72%

@ascarpino ascarpino marked this pull request as ready for review November 23, 2023 01:07
@openjdk openjdk bot added the rfr Pull request is ready for review label Nov 23, 2023
@mlbridge
Copy link

mlbridge bot commented Nov 23, 2023

Webrevs

Copy link
Member

@djelinski djelinski left a comment

Choose a reason for hiding this comment

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

Thanks for doing this! A few comments in line.

/**
* Create an instance with no buffer
*/
public AEADBufferedStream() {
Copy link
Member

Choose a reason for hiding this comment

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

Never used. And once you remove it, buf is never null

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure


public AEADBufferedStream(int len) {
buf = new byte[len];
count = 0;
Copy link
Member

Choose a reason for hiding this comment

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

no need to zero-initialize, it's zero by default

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes

* @return internal or new byte array of non-blocksize data.
*/
@Override
public synchronized byte[] toByteArray() {
Copy link
Member

Choose a reason for hiding this comment

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

remove this synchronized; the new write methods are not synchronized, so this does not add value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting, I thought I was stuck with synchronized from the parent

*/
@Override
public synchronized byte[] toByteArray() {
if (buf.length > count) {
Copy link
Member

Choose a reason for hiding this comment

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

Can this ever happen? And if it can, would it be better to return the whole buffer and have the caller extract the necessary range?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, because it can reuse the allocated buffer during encryption scenarios when multi-part ops send non-block size data. For decryption, it should never happen.

count = buf.length;
} else {
if (buf.length < (count + len)) {
buf = Arrays.copyOf(buf, count + len);
Copy link
Member

Choose a reason for hiding this comment

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

this will copy a lot if the user performs many small writes, for example when decrypting with CipherInputStream; see AESGCMCipherOutputStream benchmark.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As I understand the ByteArrayOutputStream code, the ArraysSupport.newLength() will double the allocation each time. So if the buffer is 1k size and it wants to add one more byte, the method will allocate 2k.
I agree that in my change, if you send one byte at a time, it will be doing a lot of allocating. But I don't believe that is the general case. If you have examples of apps doing small allocations, let me know and I can come up with a different scheme. But at this point I thought it was a bitter risk more allocations in the less-likely situation, than unused allocation in what I see as a more common case.

Copy link
Member

Choose a reason for hiding this comment

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

Well, as stated above, any application using CipherInputStream will do O(N) reallocations here, bringing back JDK-8298249; you might want to check with the reporter if this actually affects any real applications.

For reference, the results with this patch:

Benchmark                         (dataSize)  (keyLength)  (provider)   Mode  Cnt       Score      Error  Units
AESGCMCipherOutputStream.decrypt       16384          128              thrpt   40   30325.669 ? 1616.428  ops/s
AESGCMCipherOutputStream.decrypt     1048576          128              thrpt   40       7.034 ?    0.479  ops/s

Baseline:

Benchmark                         (dataSize)  (keyLength)  (provider)   Mode  Cnt       Score      Error  Units
AESGCMCipherOutputStream.decrypt       16384          128              thrpt   40   52171.497 ? 6229.841  ops/s
AESGCMCipherOutputStream.decrypt     1048576          128              thrpt   40     470.844 ?  179.817  ops/s

i.e. with the patch, decryption is 40% slower for 16KB stream, 98% (or 50x) slower for 1MB stream.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok.. I updated the code to handle it more like it did. With one update(), the memory usage is still how I intended. So keeping the CipherOutputStream case, where it's multiple update() calls, it's a problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After my change, that perf test showed a 30% for 16k and 15% for 1M perf increase

iv_index = (iv_index + 1) % IV_MODULO;
return r;
return new GCMParameterSpec(96, iv, iv_index, 12);
Copy link
Member

Choose a reason for hiding this comment

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

Also use 128-bit tag here.


AlgorithmParameterSpec getNewSpec() {
iv_index = (iv_index + 1) % IV_MODULO;
return new GCMParameterSpec(96, iv, iv_index, 12);
Copy link
Member

Choose a reason for hiding this comment

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

Also use 128-bit tag here.


AlgorithmParameterSpec getNewSpec() {
iv_index = (iv_index + 1) % IV_MODULO;
return new GCMParameterSpec(96, iv, iv_index, 12);
Copy link
Member

Choose a reason for hiding this comment

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

Also use 128-bit tag here.

@Benchmark
public void decrypt() throws Exception {
decryptCipher.init(Cipher.DECRYPT_MODE, ks,
encryptCipher.getParameters().
Copy link
Member

Choose a reason for hiding this comment

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

Consider using a different method to obtain parameter spec here; the flamegraph suggests that getParameters is responsible for up to 20% of the time spent in these benchmarks

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 for point that out. I have decided to leave this as is. There are optimizations that can be made to getParameters that I would like the benchmark to measure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There was no optimization available for getParameters so I saved the parameters from the encryption op and it greatly improved the test performance

*/

public AEADBufferedStream(int len) {
buf = new byte[len];
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
buf = new byte[len];
super(len);

otherwise buf will be initialized twice, once here, once in the base class constructor

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah.. better memory performance too.

}

/*
* Optimized version of bufferCrypt from CipherSpi.java. Direct
Copy link
Member

Choose a reason for hiding this comment

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

well I was under the impression that the bulk of the optimization comes from using modified engineGetOutputSize that does not allocate when isUpdate== true and decrypting. That's not documented anywhere.

} else {
try {
outArray = engineDoFinal(inArray, inOfs, inLen);
} catch (BadPaddingException e) {
Copy link
Member

Choose a reason for hiding this comment

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

Should we really be hiding the BadPaddingException here and in other places in this method? AEADBadTagException extends BadPaddingException, and I'm pretty sure we don't want to hide it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

CipherSpi:engineUpdate() only throws ShortBufferException. That forces many exceptions into a ProviderException with extends RuntimeException. The BadPaddingException doesn't matter because CC20 doesn't have padding. AEADTagException should be specified and thrown, not wrapped.

src.position(pos + len);
return;
}
if (buf == null) {
Copy link
Member

Choose a reason for hiding this comment

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

leftover from previous implementation; buf is never null.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I redid a lot of this code in this update

count = buf.length;
} else {
if (buf.length < (count + len)) {
buf = Arrays.copyOf(buf, count + len);
Copy link
Member

Choose a reason for hiding this comment

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

Well, as stated above, any application using CipherInputStream will do O(N) reallocations here, bringing back JDK-8298249; you might want to check with the reporter if this actually affects any real applications.

For reference, the results with this patch:

Benchmark                         (dataSize)  (keyLength)  (provider)   Mode  Cnt       Score      Error  Units
AESGCMCipherOutputStream.decrypt       16384          128              thrpt   40   30325.669 ? 1616.428  ops/s
AESGCMCipherOutputStream.decrypt     1048576          128              thrpt   40       7.034 ?    0.479  ops/s

Baseline:

Benchmark                         (dataSize)  (keyLength)  (provider)   Mode  Cnt       Score      Error  Units
AESGCMCipherOutputStream.decrypt       16384          128              thrpt   40   52171.497 ? 6229.841  ops/s
AESGCMCipherOutputStream.decrypt     1048576          128              thrpt   40     470.844 ?  179.817  ops/s

i.e. with the patch, decryption is 40% slower for 16KB stream, 98% (or 50x) slower for 1MB stream.

return bufferCrypt(input, output, true);
} catch (AEADBadTagException e) {
// exception is never thrown by update ops
return 0;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return 0;
throw new AssertionError(e);

Changed aeadbuffer usage away from byte[].length to aeadbuffer.size()
int blen = buf.length;
// Create a new larger buffer and append the new data
if (blen < count + len) {
buf = Arrays.copyOf(buf, ArraysSupport.newLength(blen, blen + len,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
buf = Arrays.copyOf(buf, ArraysSupport.newLength(blen, blen + len,
buf = Arrays.copyOf(buf, ArraysSupport.newLength(blen, count + len - blen,

the second parameter is minGrowth; count+len-blen would be more appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually it should be len. That is the minGrowth as that is the size being added to the buffer, and Math.max(len, blen)

* method must use {@code size()} for the relevant data length as the
* returning byte[] maybe larger.
*
* @return internal or new byte array of non-blocksize data.
Copy link
Member

Choose a reason for hiding this comment

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

Please update the doc - the method always returns the internal array.

I would create a new method to retrieve the internal buffer instead of overriding toByteArray; it would be less surprising to the future code editors.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

Copy link
Member

@djelinski djelinski left a comment

Choose a reason for hiding this comment

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

LGTM. Thank you!

@openjdk
Copy link

openjdk bot commented Dec 6, 2023

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

8318756: Create better internal buffer for AEADs

Reviewed-by: djelinski

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 772 new commits pushed to the master branch:

  • a9cb120: 8320948: NPE due to unreported compiler error
  • 4ef24e2: 8319938: TestFileChooserSingleDirectorySelection.java fails with "getSelectedFiles returned empty array"
  • cc25d8b: 8319662: ForkJoinPool trims worker threads too slowly
  • 90e433d: 8320144: Compilation crashes when a custom annotation with invalid default value is used
  • 50f3124: 8320892: AArch64: Restore FPU control state after JNI
  • 0217b5a: 8321248: ClassFile API ClassModel::verify is inconsistent with the rest of the API
  • 7fbfb3b: 8321369: Unproblemlist gc/cslocker/TestCSLocker.java
  • 2678e4c: 8319111: Mismatched MemorySegment heap access is not consistently intrinsified
  • a0920aa: 8321159: SymbolLookup.libraryLookup(Path, Arena) Assumes default Filesystem
  • 9d77677: 8321124: java/util/stream/GatherersTest.java times out
  • ... and 762 more: https://git.openjdk.org/jdk/compare/2edf9c3f1e968779c6e92b3e25d780db68ace5cc...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 Dec 6, 2023
@ascarpino
Copy link
Contributor Author

/integrate

@openjdk
Copy link

openjdk bot commented Dec 6, 2023

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

  • a9cb120: 8320948: NPE due to unreported compiler error
  • 4ef24e2: 8319938: TestFileChooserSingleDirectorySelection.java fails with "getSelectedFiles returned empty array"
  • cc25d8b: 8319662: ForkJoinPool trims worker threads too slowly
  • 90e433d: 8320144: Compilation crashes when a custom annotation with invalid default value is used
  • 50f3124: 8320892: AArch64: Restore FPU control state after JNI
  • 0217b5a: 8321248: ClassFile API ClassModel::verify is inconsistent with the rest of the API
  • 7fbfb3b: 8321369: Unproblemlist gc/cslocker/TestCSLocker.java
  • 2678e4c: 8319111: Mismatched MemorySegment heap access is not consistently intrinsified
  • a0920aa: 8321159: SymbolLookup.libraryLookup(Path, Arena) Assumes default Filesystem
  • 9d77677: 8321124: java/util/stream/GatherersTest.java times out
  • ... and 762 more: https://git.openjdk.org/jdk/compare/2edf9c3f1e968779c6e92b3e25d780db68ace5cc...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Dec 6, 2023
@openjdk openjdk bot closed this Dec 6, 2023
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Dec 6, 2023
@openjdk
Copy link

openjdk bot commented Dec 6, 2023

@ascarpino Pushed as commit dc9c77b.

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

@eirbjo
Copy link
Contributor

eirbjo commented Dec 8, 2023

@ascarpino I'm seeing GHA test failures on linux-x86 for AEADBufferTest.java after the integration of this change [1]. This PR's checks also fail [2]

build/run-test-prebuilt/test-support/jtreg_test_jdk_tier1_part3/com/sun/crypto/provider/Cipher/AEAD/AEADBufferTest/hs_err_pid4225.log:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00000000, pid=4225, tid=10054
#
# JRE version: OpenJDK Runtime Environment (23.0) (build 23-internal-eirbjo-f6a00f0cfe870a555c559063d7eab53366fa6d70)
# Java VM: OpenJDK Server VM (23-internal-eirbjo-f6a00f0cfe870a555c559063d7eab53366fa6d70, mixed mode, tiered, g1 gc, linux-x86)
# Problematic frame:
# J 6617 c2 com.sun.crypto.provider.ChaCha20Cipher.chaCha20Transform([BII[BI)V java.base@23-internal (193 bytes) @ 0xef6677bd [0xef667440+0x0000037d]
#
# CreateCoredumpOnCrash turned off, no core file dumped
#
# If you would like to submit a bug report, please visit:
#   https://bugreport.java.com/bugreport/crash.jsp
#

---------------  S U M M A R Y ------------

Command Line: -Xmx768m -XX:MaxRAMPercentage=12.5 -Dtest.boot.jdk=/home/runner/work/jdk/jdk/bootjdk/jdk -Djava.io.tmpdir=/home/runner/work/jdk/jdk/build/run-test-prebuilt/test-support/jtreg_test_jdk_tier1_part3/tmp -ea -esa -XX:-CreateCoredumpOnCrash -Djava.library.path=/home/runner/work/jdk/jdk/bundles/tests/jdk/jtreg/native --patch-module=java.base=/home/runner/work/jdk/jdk/build/run-test-prebuilt/test-support/jtreg_test_jdk_tier1_part3/patches/java.base -Djava.security.policy=file:/home/runner/work/jdk/jdk/build/run-test-prebuilt/test-support/jtreg_test_jdk_tier1_part3/jtreg.policy com.sun.javatest.regtest.agent.AgentServer -id 7 -logfile /home/runner/work/jdk/jdk/build/run-test-prebuilt/test-support/jtreg_test_jdk_tier1_part3/jtData/agentServer.7.trace -allowSetSecurityManager -port 35137 -timeoutFactor 4.0

Host: AMD EPYC 7763 64-Core Processor, 4 cores, 15G, Ubuntu 22.04.3 LTS
Time: Fri Dec  8 21:03:25 2023 UTC elapsed time: 82.102203 seconds (0d 0h 1m 22s)

---------------  T H R E A D  ---------------

Current thread (0xb3ff0ea0):  JavaThread "AgentVMThread"            [_thread_in_Java, id=10054, stack(0xb50b0000,0xb5100000) (320K)]

Stack: [0xb50b0000,0xb5100000],  sp=0xb50fe910,  free space=314k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
J 6617 c2 com.sun.crypto.provider.ChaCha20Cipher.chaCha20Transform([BII[BI)V java.base@23-internal (193 bytes) @ 0xef6677bd [0xef667440+0x0000037d]
J 6559 c1 com.sun.crypto.provider.ChaCha20Cipher$EngineAEADEnc.doUpdate([BII[BI)I java.base@23-internal (148 bytes) @ 0xe82a5d64 [0xe82a5a40+0x00000324]
J 6598 c1 com.sun.crypto.provider.ChaCha20Cipher$EngineAEADEnc.doFinal([BII[BI)I java.base@23-internal (64 bytes) @ 0xe82b55c0 [0xe82b54e0+0x000000e0]
J 6601 c1 com.sun.crypto.provider.ChaCha20Cipher.engineDoFinal([BII[BI)I java.base@23-internal (52 bytes) @ 0xe82b6a98 [0xe82b6980+0x00000118]
J 6252 c1 javax.crypto.Cipher.doFinal([BII[BI)I java.base@23-internal (59 bytes) @ 0xe8208878 [0xe8208600+0x00000278]
J 6218 c1 AEADBufferTest.crypto(ZLAEADBufferTest$Data;[B[B)V (1208 bytes) @ 0xe81eee40 [0xe81ebac0+0x00003380]
J 6277 c1 AEADBufferTest.encrypt(LAEADBufferTest$Data;)V (119 bytes) @ 0xe821a01c [0xe8218be0+0x0000143c]
j  AEADBufferTest.test()V+181
j  AEADBufferTest.main([Ljava/lang/String;)V+1458
j  java.lang.invoke.LambdaForm$DMH+0xb4402a58.invokeStatic(Ljava/lang/Object;Ljava/lang/Object;)V+10 java.base@23-internal
j  java.lang.invoke.LambdaForm$MH+0xb0672280.invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+33 java.base@23-internal
J 4739 c2 jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; java.base@23-internal (92 bytes) @ 0xef4d8dbc [0xef4d8ae0+0x000002dc]
J 2103 c1 java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; java.base@23-internal (108 bytes) @ 0xe796bb34 [0xe796b740+0x000003f4]
j  com.sun.javatest.regtest.agent.MainActionHelper$AgentVMRunnable.run()V+10
j  java.lang.Thread.runWith(Ljava/lang/Object;Ljava/lang/Runnable;)V+5 java.base@23-internal
j  java.lang.Thread.run()V+19 java.base@23-internal
v  ~StubRoutines::call_stub 0xeebe1c7c
V  [libjvm.so+0x6e58d2]  JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x232  (javaCalls.cpp:415)
V  [libjvm.so+0x6e64e5]  JavaCalls::call_virtual(JavaValue*, Handle, Klass*, Symbol*, Symbol*, JavaThread*)+0x195  (javaCalls.cpp:329)
V  [libjvm.so+0x7c5e7b]  thread_entry(JavaThread*, JavaThread*)+0x8b  (jvm.cpp:2937)
V  [libjvm.so+0x6ff668]  JavaThread::thread_main_inner() [clone .part.0]+0xb8  (javaThread.cpp:720)
V  [libjvm.so+0xc487e3]  Thread::call_run()+0xa3  (thread.cpp:220)
V  [libjvm.so+0xa34859]  thread_native_entry(Thread*)+0xf9  (os_linux.cpp:789)
C  [libc.so.6+0x86071]

[1] https://github.com/eirbjo/jdk/actions/runs/7145974602#user-content-com_sun_crypto_provider_cipher_aead_aeadbuffertest
[2] https://github.com/ascarpino/jdk/actions/runs/7117563802#user-content-com_sun_crypto_provider_cipher_aead_aeadbuffertest

@ascarpino
Copy link
Contributor Author

This change did not introduce the problem. The test just exposed the problem that has existed since https://bugs.openjdk.org/browse/JDK-8247645 was integrated in JDK 20.

A bug was filed: https://bugs.openjdk.org/browse/JDK-8321542

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.

3 participants