8296024: Usage of DirectBuffer::address should be guarded

Reviewed-by: mcimadamore, alanb, psandoz, bpb
This commit is contained in:
Per Minborg 2022-12-06 10:42:59 +00:00 committed by Alan Bateman
parent a9e6c62ba7
commit 84b927a05b
24 changed files with 635 additions and 430 deletions

View File

@ -25,6 +25,8 @@
package com.sun.crypto.provider;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.misc.Unsafe;
import sun.nio.ch.DirectBuffer;
import sun.security.jca.JCAUtil;
@ -92,6 +94,8 @@ abstract class GaloisCounterMode extends CipherSpi {
static final byte[] EMPTY_BUF = new byte[0];
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
private boolean initialized = false;
SymmetricCipher blockCipher;
@ -909,6 +913,8 @@ abstract class GaloisCounterMode extends CipherSpi {
*/
ByteBuffer overlapDetection(ByteBuffer src, ByteBuffer dst) {
if (src.isDirect() && dst.isDirect()) {
// The use of DirectBuffer::address below need not be guarded as
// no access is made to actual memory.
DirectBuffer dsrc = (DirectBuffer) src;
DirectBuffer ddst = (DirectBuffer) dst;
@ -946,7 +952,6 @@ abstract class GaloisCounterMode extends CipherSpi {
((DirectBuffer) dst).address() - dstaddr + dst.position()) {
return dst;
}
} else if (!src.isDirect() && !dst.isDirect()) {
// if src is read only, then we need a copy
if (!src.isReadOnly()) {
@ -1585,8 +1590,13 @@ abstract class GaloisCounterMode extends CipherSpi {
int ofs = dst.arrayOffset() + dst.position();
Arrays.fill(dst.array(), ofs , ofs + len, (byte)0);
} else {
Unsafe.getUnsafe().setMemory(((DirectBuffer)dst).address(),
len + dst.position(), (byte)0);
NIO_ACCESS.acquireSession(dst);
try {
Unsafe.getUnsafe().setMemory(((DirectBuffer)dst).address(),
len + dst.position(), (byte) 0);
} finally {
NIO_ACCESS.releaseSession(dst);
}
}
throw new AEADBadTagException("Tag mismatch");
}

View File

@ -37,6 +37,7 @@ import jdk.internal.vm.annotation.ForceInline;
import java.io.FileDescriptor;
import java.lang.foreign.MemorySegment;
import java.lang.ref.Reference;
import java.util.Objects;
import java.util.Spliterator;
@ -779,6 +780,7 @@ public abstract sealed class Buffer
// setup access to this package in SharedSecrets
SharedSecrets.setJavaNioAccess(
new JavaNioAccess() {
@Override
public BufferPool getDirectBufferPool() {
return Bits.BUFFER_POOL;
@ -824,16 +826,34 @@ public abstract sealed class Buffer
}
@Override
public Runnable acquireSession(Buffer buffer, boolean async) {
var session = buffer.session();
if (session == null) {
return null;
public void acquireSession(Buffer buffer) {
var scope = buffer.session();
if (scope != null) {
scope.acquire0();
}
if (async && session.ownerThread() != null) {
throw new IllegalStateException("Confined session not supported");
}
@Override
public void releaseSession(Buffer buffer) {
try {
var scope = buffer.session();
if (scope != null) {
scope.release0();
}
} finally {
Reference.reachabilityFence(buffer);
}
session.acquire0();
return session::release0;
}
@Override
public boolean isThreadConfined(Buffer buffer) {
var scope = buffer.session();
return scope != null && scope.ownerThread() != null;
}
@Override
public boolean hasSession(Buffer buffer) {
return buffer.session() != null;
}
@Override

View File

@ -25,11 +25,13 @@
package java.util.zip;
import java.lang.ref.Reference;
import java.nio.ByteBuffer;
import sun.nio.ch.DirectBuffer;
import jdk.internal.util.Preconditions;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import sun.nio.ch.DirectBuffer;
import static java.util.zip.ZipUtils.NIO_ACCESS;
/**
* A class that can be used to compute the Adler-32 checksum of a data
@ -96,10 +98,11 @@ public class Adler32 implements Checksum {
if (rem <= 0)
return;
if (buffer.isDirect()) {
NIO_ACCESS.acquireSession(buffer);
try {
adler = updateByteBuffer(adler, ((DirectBuffer)buffer).address(), pos, rem);
} finally {
Reference.reachabilityFence(buffer);
NIO_ACCESS.releaseSession(buffer);
}
} else if (buffer.hasArray()) {
adler = updateBytes(adler, buffer.array(), pos + buffer.arrayOffset(), rem);

View File

@ -25,7 +25,6 @@
package java.util.zip;
import java.lang.ref.Reference;
import java.nio.ByteBuffer;
import java.util.Objects;
@ -33,6 +32,8 @@ import sun.nio.ch.DirectBuffer;
import jdk.internal.util.Preconditions;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import static java.util.zip.ZipUtils.NIO_ACCESS;
/**
* A class that can be used to compute the CRC-32 of a data stream.
*
@ -96,10 +97,11 @@ public class CRC32 implements Checksum {
if (rem <= 0)
return;
if (buffer.isDirect()) {
NIO_ACCESS.acquireSession(buffer);
try {
crc = updateByteBuffer(crc, ((DirectBuffer)buffer).address(), pos, rem);
} finally {
Reference.reachabilityFence(buffer);
NIO_ACCESS.releaseSession(buffer);
}
} else if (buffer.hasArray()) {
crc = updateBytes(crc, buffer.array(), pos + buffer.arrayOffset(), rem);

View File

@ -24,7 +24,6 @@
*/
package java.util.zip;
import java.lang.ref.Reference;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@ -33,6 +32,8 @@ import jdk.internal.util.Preconditions;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import sun.nio.ch.DirectBuffer;
import static java.util.zip.ZipUtils.NIO_ACCESS;
/**
* A class that can be used to compute the CRC-32C of a data stream.
*
@ -171,11 +172,12 @@ public final class CRC32C implements Checksum {
}
if (buffer.isDirect()) {
NIO_ACCESS.acquireSession(buffer);
try {
crc = updateDirectByteBuffer(crc, ((DirectBuffer) buffer).address(),
crc = updateDirectByteBuffer(crc, ((DirectBuffer)buffer).address(),
pos, limit);
} finally {
Reference.reachabilityFence(buffer);
NIO_ACCESS.releaseSession(buffer);
}
} else if (buffer.hasArray()) {
crc = updateBytes(crc, buffer.array(), pos + buffer.arrayOffset(),

View File

@ -26,7 +26,6 @@
package java.util.zip;
import java.lang.ref.Cleaner.Cleanable;
import java.lang.ref.Reference;
import java.nio.ByteBuffer;
import java.nio.ReadOnlyBufferException;
import java.util.Objects;
@ -35,6 +34,8 @@ import jdk.internal.ref.CleanerFactory;
import jdk.internal.util.Preconditions;
import sun.nio.ch.DirectBuffer;
import static java.util.zip.ZipUtils.NIO_ACCESS;
/**
* This class provides support for general purpose compression using the
* popular ZLIB compression library. The ZLIB compression library was
@ -337,11 +338,12 @@ public class Deflater {
int remaining = Math.max(dictionary.limit() - position, 0);
ensureOpen();
if (dictionary.isDirect()) {
long address = ((DirectBuffer) dictionary).address();
NIO_ACCESS.acquireSession(dictionary);
try {
long address = ((DirectBuffer) dictionary).address();
setDictionaryBuffer(zsRef.address(), address + position, remaining);
} finally {
Reference.reachabilityFence(dictionary);
NIO_ACCESS.releaseSession(dictionary);
}
} else {
byte[] array = ZipUtils.getBufferArray(dictionary);
@ -587,6 +589,7 @@ public class Deflater {
inputPos = input.position();
int inputRem = Math.max(input.limit() - inputPos, 0);
if (input.isDirect()) {
NIO_ACCESS.acquireSession(input);
try {
long inputAddress = ((DirectBuffer) input).address();
result = deflateBufferBytes(zsRef.address(),
@ -594,7 +597,7 @@ public class Deflater {
output, off, len,
flush, params);
} finally {
Reference.reachabilityFence(input);
NIO_ACCESS.releaseSession(input);
}
} else {
byte[] inputArray = ZipUtils.getBufferArray(input);
@ -709,14 +712,15 @@ public class Deflater {
if (input == null) {
inputPos = this.inputPos;
if (output.isDirect()) {
long outputAddress = ((DirectBuffer) output).address();
NIO_ACCESS.acquireSession(output);
try {
long outputAddress = ((DirectBuffer) output).address();
result = deflateBytesBuffer(zsRef.address(),
inputArray, inputPos, inputLim - inputPos,
outputAddress + outputPos, outputRem,
flush, params);
} finally {
Reference.reachabilityFence(output);
NIO_ACCESS.releaseSession(output);
}
} else {
byte[] outputArray = ZipUtils.getBufferArray(output);
@ -730,17 +734,19 @@ public class Deflater {
inputPos = input.position();
int inputRem = Math.max(input.limit() - inputPos, 0);
if (input.isDirect()) {
long inputAddress = ((DirectBuffer) input).address();
NIO_ACCESS.acquireSession(input);
try {
long inputAddress = ((DirectBuffer) input).address();
if (output.isDirect()) {
long outputAddress = outputPos + ((DirectBuffer) output).address();
NIO_ACCESS.acquireSession(output);
try {
long outputAddress = outputPos + ((DirectBuffer) output).address();
result = deflateBufferBuffer(zsRef.address(),
inputAddress + inputPos, inputRem,
outputAddress, outputRem,
flush, params);
} finally {
Reference.reachabilityFence(output);
NIO_ACCESS.releaseSession(output);
}
} else {
byte[] outputArray = ZipUtils.getBufferArray(output);
@ -751,20 +757,21 @@ public class Deflater {
flush, params);
}
} finally {
Reference.reachabilityFence(input);
NIO_ACCESS.releaseSession(input);
}
} else {
byte[] inputArray = ZipUtils.getBufferArray(input);
int inputOffset = ZipUtils.getBufferOffset(input);
if (output.isDirect()) {
long outputAddress = ((DirectBuffer) output).address();
NIO_ACCESS.acquireSession(output);
try {
long outputAddress = ((DirectBuffer) output).address();
result = deflateBytesBuffer(zsRef.address(),
inputArray, inputOffset + inputPos, inputRem,
outputAddress + outputPos, outputRem,
flush, params);
} finally {
Reference.reachabilityFence(output);
NIO_ACCESS.releaseSession(output);
}
} else {
byte[] outputArray = ZipUtils.getBufferArray(output);

View File

@ -26,7 +26,6 @@
package java.util.zip;
import java.lang.ref.Cleaner.Cleanable;
import java.lang.ref.Reference;
import java.nio.ByteBuffer;
import java.nio.ReadOnlyBufferException;
import java.util.Objects;
@ -35,6 +34,8 @@ import jdk.internal.ref.CleanerFactory;
import jdk.internal.util.Preconditions;
import sun.nio.ch.DirectBuffer;
import static java.util.zip.ZipUtils.NIO_ACCESS;
/**
* This class provides support for general purpose decompression using the
* popular ZLIB compression library. The ZLIB compression library was
@ -259,11 +260,12 @@ public class Inflater {
int remaining = Math.max(dictionary.limit() - position, 0);
ensureOpen();
if (dictionary.isDirect()) {
long address = ((DirectBuffer) dictionary).address();
NIO_ACCESS.acquireSession(dictionary);
try {
long address = ((DirectBuffer) dictionary).address();
setDictionaryBuffer(zsRef.address(), address + position, remaining);
} finally {
Reference.reachabilityFence(dictionary);
NIO_ACCESS.releaseSession(dictionary);
}
} else {
byte[] array = ZipUtils.getBufferArray(dictionary);
@ -383,13 +385,14 @@ public class Inflater {
try {
int inputRem = Math.max(input.limit() - inputPos, 0);
if (input.isDirect()) {
NIO_ACCESS.acquireSession(input);
try {
long inputAddress = ((DirectBuffer) input).address();
result = inflateBufferBytes(zsRef.address(),
inputAddress + inputPos, inputRem,
output, off, len);
} finally {
Reference.reachabilityFence(input);
NIO_ACCESS.releaseSession(input);
}
} else {
byte[] inputArray = ZipUtils.getBufferArray(input);
@ -517,13 +520,14 @@ public class Inflater {
inputPos = this.inputPos;
try {
if (output.isDirect()) {
long outputAddress = ((DirectBuffer) output).address();
NIO_ACCESS.acquireSession(output);
try {
long outputAddress = ((DirectBuffer) output).address();
result = inflateBytesBuffer(zsRef.address(),
inputArray, inputPos, inputLim - inputPos,
outputAddress + outputPos, outputRem);
} finally {
Reference.reachabilityFence(output);
NIO_ACCESS.releaseSession(output);
}
} else {
byte[] outputArray = ZipUtils.getBufferArray(output);
@ -541,16 +545,18 @@ public class Inflater {
int inputRem = Math.max(input.limit() - inputPos, 0);
try {
if (input.isDirect()) {
long inputAddress = ((DirectBuffer) input).address();
NIO_ACCESS.acquireSession(input);
try {
long inputAddress = ((DirectBuffer) input).address();
if (output.isDirect()) {
long outputAddress = ((DirectBuffer) output).address();
NIO_ACCESS.acquireSession(output);
try {
long outputAddress = ((DirectBuffer) output).address();
result = inflateBufferBuffer(zsRef.address(),
inputAddress + inputPos, inputRem,
outputAddress + outputPos, outputRem);
} finally {
Reference.reachabilityFence(output);
NIO_ACCESS.releaseSession(output);
}
} else {
byte[] outputArray = ZipUtils.getBufferArray(output);
@ -560,19 +566,20 @@ public class Inflater {
outputArray, outputOffset + outputPos, outputRem);
}
} finally {
Reference.reachabilityFence(input);
NIO_ACCESS.releaseSession(input);
}
} else {
byte[] inputArray = ZipUtils.getBufferArray(input);
int inputOffset = ZipUtils.getBufferOffset(input);
if (output.isDirect()) {
long outputAddress = ((DirectBuffer) output).address();
NIO_ACCESS.acquireSession(output);
try {
long outputAddress = ((DirectBuffer) output).address();
result = inflateBytesBuffer(zsRef.address(),
inputArray, inputOffset + inputPos, inputRem,
outputAddress + outputPos, outputRem);
} finally {
Reference.reachabilityFence(output);
NIO_ACCESS.releaseSession(output);
}
} else {
byte[] outputArray = ZipUtils.getBufferArray(output);

View File

@ -36,10 +36,14 @@ import java.util.concurrent.TimeUnit;
import static java.util.zip.ZipConstants.ENDHDR;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.misc.Unsafe;
class ZipUtils {
static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
// used to adjust values between Windows and java epoch
private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;

View File

@ -86,12 +86,26 @@ public interface JavaNioAccess {
MemorySegment bufferSegment(Buffer buffer);
/**
* Used by I/O operations to make a buffer's session non-closeable
* (for the duration of the I/O operation) by acquiring the session.
* Null is returned if the buffer has no scope, or acquiring is not
* required to guarantee safety.
* Used by operations to make a buffer's session non-closeable
* (for the duration of the operation) by acquiring the session.
* {@snippet lang = java:
* acquireSession(buffer);
* try {
* performOperation(buffer);
* } finally {
* releaseSession(buffer);
* }
*}
*
* @see #releaseSession(Buffer)
*/
Runnable acquireSession(Buffer buffer, boolean async);
void acquireSession(Buffer buffer);
void releaseSession(Buffer buffer);
boolean isThreadConfined(Buffer buffer);
boolean hasSession(Buffer buffer);
/**
* Used by {@code jdk.internal.foreign.MappedMemorySegmentImpl} and byte buffer var handle views.

View File

@ -166,7 +166,9 @@ module java.base {
jdk.jartool,
jdk.jlink,
jdk.jfr,
jdk.net;
jdk.net,
jdk.sctp,
jdk.crypto.cryptoki;
exports jdk.internal.foreign to
jdk.incubator.vector;
exports jdk.internal.event to

View File

@ -71,6 +71,8 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.ref.CleanerFactory;
import sun.net.ResourceManager;
import sun.net.ext.ExtendedSocketOptions;
@ -87,6 +89,8 @@ class DatagramChannelImpl
// Used to make native read and write calls
private static final NativeDispatcher nd = new DatagramDispatcher();
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
// true if interruptible (can be false to emulate legacy DatagramSocket)
private final boolean interruptible;
@ -780,13 +784,18 @@ class DatagramChannelImpl
boolean connected)
throws IOException
{
int n = receive0(fd,
((DirectBuffer)bb).address() + pos, rem,
sourceSockAddr.address(),
connected);
if (n > 0)
bb.position(pos + n);
return n;
NIO_ACCESS.acquireSession(bb);
try {
int n = receive0(fd,
((DirectBuffer)bb).address() + pos, rem,
sourceSockAddr.address(),
connected);
if (n > 0)
bb.position(pos + n);
return n;
} finally {
NIO_ACCESS.releaseSession(bb);
}
}
/**
@ -930,6 +939,7 @@ class DatagramChannelImpl
int rem = (pos <= lim ? lim - pos : 0);
int written;
NIO_ACCESS.acquireSession(bb);
try {
int addressLen = targetSocketAddress(target);
written = send0(fd, ((DirectBuffer)bb).address() + pos, rem,
@ -938,6 +948,8 @@ class DatagramChannelImpl
if (isConnected())
throw pue;
written = rem;
} finally {
NIO_ACCESS.releaseSession(bb);
}
if (written > 0)
bb.position(pos + written);

View File

@ -30,6 +30,13 @@ import jdk.internal.ref.Cleaner;
public interface DirectBuffer {
// Use of the returned address must be guarded if this DirectBuffer
// is backed by a memory session that is explicitly closeable.
//
// Failure to do this means the outcome is undefined including
// silent unrelated memory mutation and JVM crashes.
//
// See JavaNioAccess for methods to safely acquire/release resources.
public long address();
public Object attachment();

View File

@ -31,12 +31,13 @@ import java.nio.ByteBuffer;
import java.util.Objects;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.foreign.MemorySessionImpl;
/**
* File-descriptor based I/O utilities that are shared by NIO classes.
*/
public class IOUtil {
public final class IOUtil {
/**
* Max number of iovec structures that readv/writev supports
@ -128,7 +129,7 @@ public class IOUtil {
int written = 0;
if (rem == 0)
return 0;
var handle = acquireScope(bb, async);
acquireScope(bb, async);
try {
if (position != -1) {
written = nd.pwrite(fd, bufferAddress(bb) + pos, rem, position);
@ -136,7 +137,7 @@ public class IOUtil {
written = nd.write(fd, bufferAddress(bb) + pos, rem);
}
} finally {
releaseScope(handle);
releaseScope(bb);
}
if (written > 0)
bb.position(pos + written);
@ -181,9 +182,9 @@ public class IOUtil {
int i = offset;
while (i < count && iov_len < IOV_MAX && writevLen < WRITEV_MAX) {
ByteBuffer buf = bufs[i];
var h = acquireScope(buf, async);
if (h != null) {
handleReleasers = LinkedRunnable.of(Releaser.of(h), handleReleasers);
acquireScope(buf, async);
if (NIO_ACCESS.hasSession(buf)) {
handleReleasers = LinkedRunnable.of(Releaser.of(buf), handleReleasers);
}
int pos = buf.position();
int lim = buf.limit();
@ -331,7 +332,7 @@ public class IOUtil {
if (rem == 0)
return 0;
int n = 0;
var handle = acquireScope(bb, async);
acquireScope(bb, async);
try {
if (position != -1) {
n = nd.pread(fd, bufferAddress(bb) + pos, rem, position);
@ -339,7 +340,7 @@ public class IOUtil {
n = nd.read(fd, bufferAddress(bb) + pos, rem);
}
} finally {
releaseScope(handle);
releaseScope(bb);
}
if (n > 0)
bb.position(pos + n);
@ -393,9 +394,9 @@ public class IOUtil {
ByteBuffer buf = bufs[i];
if (buf.isReadOnly())
throw new IllegalArgumentException("Read-only buffer");
var h = acquireScope(buf, async);
if (h != null) {
handleReleasers = LinkedRunnable.of(Releaser.of(h), handleReleasers);
acquireScope(buf, async);
if (NIO_ACCESS.hasSession(buf)) {
handleReleasers = LinkedRunnable.of(Releaser.of(buf), handleReleasers);
}
int pos = buf.position();
int lim = buf.limit();
@ -474,15 +475,16 @@ public class IOUtil {
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
static Runnable acquireScope(ByteBuffer bb, boolean async) {
return NIO_ACCESS.acquireSession(bb, async);
static void acquireScope(ByteBuffer bb, boolean async) {
if (async && NIO_ACCESS.isThreadConfined(bb)) {
throw new IllegalStateException("Confined session not supported");
}
NIO_ACCESS.acquireSession(bb);
}
private static void releaseScope(Runnable handle) {
if (handle == null)
return;
private static void releaseScope(ByteBuffer bb) {
try {
handle.run();
NIO_ACCESS.releaseSession(bb);
} catch (Exception e) {
throw new IllegalStateException(e);
}
@ -495,15 +497,14 @@ public class IOUtil {
static Runnable acquireScopes(ByteBuffer buf, ByteBuffer[] buffers) {
if (buffers == null) {
assert buf != null;
return IOUtil.Releaser.ofNullable(IOUtil.acquireScope(buf, true));
IOUtil.acquireScope(buf, true);
return IOUtil.Releaser.of(buf);
} else {
assert buf == null;
Runnable handleReleasers = null;
for (var b : buffers) {
var h = IOUtil.acquireScope(b, true);
if (h != null) {
handleReleasers = IOUtil.LinkedRunnable.of(IOUtil.Releaser.of(h), handleReleasers);
}
IOUtil.acquireScope(b, true);
handleReleasers = IOUtil.LinkedRunnable.of(IOUtil.Releaser.of(b), handleReleasers);
}
return handleReleasers;
}
@ -514,12 +515,11 @@ public class IOUtil {
releasers.run();
}
static record LinkedRunnable(Runnable node, Runnable next)
implements Runnable
{
record LinkedRunnable(Runnable node, Runnable next) implements Runnable {
LinkedRunnable {
Objects.requireNonNull(node);
}
@Override
public void run() {
try {
@ -529,20 +529,28 @@ public class IOUtil {
next.run();
}
}
static LinkedRunnable of(Runnable first, Runnable second) {
return new LinkedRunnable(first, second);
}
}
static record Releaser(Runnable handle) implements Runnable {
Releaser { Objects.requireNonNull(handle) ; }
@Override public void run() { releaseScope(handle); }
static Runnable of(Runnable handle) { return new Releaser(handle); }
static Runnable ofNullable(Runnable handle) {
if (handle == null)
return () -> { };
return new Releaser(handle);
record Releaser(ByteBuffer bb) implements Runnable {
Releaser {
Objects.requireNonNull(bb);
}
@Override
public void run() {
releaseScope(bb);
}
static Runnable of(ByteBuffer bb) {
return NIO_ACCESS.hasSession(bb)
? new Releaser(bb)
: () -> {};
}
}
static long bufferAddress(ByteBuffer buf) {

View File

@ -134,6 +134,7 @@ grant codeBase "jrt:/jdk.crypto.cryptoki" {
permission java.lang.RuntimePermission
"accessClassInPackage.com.sun.crypto.provider";
permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.access";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.*";
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";

View File

@ -25,11 +25,13 @@
package sun.nio.fs;
import java.lang.ref.Reference;
import java.nio.file.*;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.util.*;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.misc.Unsafe;
import static sun.nio.fs.UnixConstants.*;
@ -43,6 +45,8 @@ abstract class UnixUserDefinedFileAttributeView
{
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
// namespace for extended user attributes
private static final String USER_NAMESPACE = "user.";
@ -174,14 +178,15 @@ abstract class UnixUserDefinedFileAttributeView
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
if (dst instanceof sun.nio.ch.DirectBuffer buf) {
if (dst instanceof sun.nio.ch.DirectBuffer ddst) {
NIO_ACCESS.acquireSession(dst);
try {
long address = buf.address() + pos;
long address = ddst.address() + pos;
int n = read(name, address, rem);
dst.position(pos + n);
return n;
} finally {
Reference.reachabilityFence(buf);
NIO_ACCESS.releaseSession(dst);
}
} else {
try (NativeBuffer nb = NativeBuffers.getNativeBuffer(rem)) {
@ -237,13 +242,14 @@ abstract class UnixUserDefinedFileAttributeView
int rem = (pos <= lim ? lim - pos : 0);
if (src instanceof sun.nio.ch.DirectBuffer buf) {
NIO_ACCESS.acquireSession(src);
try {
long address = buf.address() + pos;
write(name, address, rem);
src.position(pos + rem);
return rem;
} finally {
Reference.reachabilityFence(buf);
NIO_ACCESS.releaseSession(src);
}
} else {
try (NativeBuffer nb = NativeBuffers.getNativeBuffer(rem)) {

View File

@ -35,6 +35,8 @@ import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import sun.nio.ch.DirectBuffer;
import sun.security.jca.JCAUtil;
import sun.security.pkcs11.wrapper.*;
@ -55,6 +57,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
*/
final class P11AEADCipher extends CipherSpi {
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
// supported AEAD algorithms/transformations
private enum Transformation {
AES_GCM("AES", "GCM", "NOPADDING", 16, 16),
@ -705,84 +709,94 @@ final class P11AEADCipher extends CipherSpi {
}
boolean doCancel = true;
NIO_ACCESS.acquireSession(inBuffer);
try {
ensureInitialized();
NIO_ACCESS.acquireSession(outBuffer);
try {
try {
ensureInitialized();
long inAddr = 0;
byte[] in = null;
int inOfs = 0;
if (dataBuffer.size() > 0) {
if (inLen > 0) {
byte[] temp = new byte[inLen];
inBuffer.get(temp);
dataBuffer.write(temp, 0, temp.length);
}
in = dataBuffer.toByteArray();
inOfs = 0;
inLen = in.length;
} else {
if (inBuffer instanceof DirectBuffer) {
inAddr = ((DirectBuffer) inBuffer).address();
inOfs = inBuffer.position();
} else {
if (inBuffer.hasArray()) {
in = inBuffer.array();
inOfs = inBuffer.position() + inBuffer.arrayOffset();
long inAddr = 0;
byte[] in = null;
int inOfs = 0;
if (dataBuffer.size() > 0) {
if (inLen > 0) {
byte[] temp = new byte[inLen];
inBuffer.get(temp);
dataBuffer.write(temp, 0, temp.length);
}
in = dataBuffer.toByteArray();
inOfs = 0;
inLen = in.length;
} else {
in = new byte[inLen];
inBuffer.get(in);
if (inBuffer instanceof DirectBuffer dInBuffer) {
inAddr = dInBuffer.address();
inOfs = inBuffer.position();
} else {
if (inBuffer.hasArray()) {
in = inBuffer.array();
inOfs = inBuffer.position() + inBuffer.arrayOffset();
} else {
in = new byte[inLen];
inBuffer.get(in);
}
}
}
long outAddr = 0;
byte[] outArray = null;
int outOfs = 0;
if (outBuffer instanceof DirectBuffer dOutBuffer) {
outAddr = dOutBuffer.address();
outOfs = outBuffer.position();
} else {
if (outBuffer.hasArray()) {
outArray = outBuffer.array();
outOfs = outBuffer.position() + outBuffer.arrayOffset();
} else {
outArray = new byte[outLen];
}
}
}
}
long outAddr = 0;
byte[] outArray = null;
int outOfs = 0;
if (outBuffer instanceof DirectBuffer) {
outAddr = ((DirectBuffer) outBuffer).address();
outOfs = outBuffer.position();
} else {
if (outBuffer.hasArray()) {
outArray = outBuffer.array();
outOfs = outBuffer.position() + outBuffer.arrayOffset();
} else {
outArray = new byte[outLen];
}
}
int k = 0;
if (encrypt) {
k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
outAddr, outArray, outOfs, outLen);
doCancel = false;
} else {
// Special handling to match SunJCE provider behavior
if (inLen == 0) {
return 0;
int k = 0;
if (encrypt) {
k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
outAddr, outArray, outOfs, outLen);
doCancel = false;
} else {
// Special handling to match SunJCE provider behavior
if (inLen == 0) {
return 0;
}
k = token.p11.C_Decrypt(session.id(), inAddr, in, inOfs, inLen,
outAddr, outArray, outOfs, outLen);
doCancel = false;
}
inBuffer.position(inBuffer.limit());
outBuffer.position(outBuffer.position() + k);
return k;
} catch (PKCS11Exception e) {
// As per the PKCS#11 standard, C_Encrypt and C_Decrypt may only
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
// successful calls to determine the output length. However,
// these cases are not expected here because the output length
// is checked in the OpenJDK side before making the PKCS#11 call.
// Thus, doCancel can safely be 'false'.
doCancel = false;
handleException(e);
throw new ProviderException("doFinal() failed", e);
} finally {
if (encrypt) {
lastEncKey = this.p11Key;
lastEncIv = this.iv;
requireReinit = true;
}
reset(doCancel);
}
k = token.p11.C_Decrypt(session.id(), inAddr, in, inOfs, inLen,
outAddr, outArray, outOfs, outLen);
doCancel = false;
} finally {
NIO_ACCESS.releaseSession(outBuffer);
}
inBuffer.position(inBuffer.limit());
outBuffer.position(outBuffer.position() + k);
return k;
} catch (PKCS11Exception e) {
// As per the PKCS#11 standard, C_Encrypt and C_Decrypt may only
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
// successful calls to determine the output length. However,
// these cases are not expected here because the output length
// is checked in the OpenJDK side before making the PKCS#11 call.
// Thus, doCancel can safely be 'false'.
doCancel = false;
handleException(e);
throw new ProviderException("doFinal() failed", e);
} finally {
if (encrypt) {
lastEncKey = this.p11Key;
lastEncIv = this.iv;
requireReinit = true;
}
reset(doCancel);
NIO_ACCESS.releaseSession(inBuffer);
}
}

View File

@ -34,6 +34,8 @@ import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import sun.nio.ch.DirectBuffer;
import sun.security.jca.JCAUtil;
import sun.security.pkcs11.wrapper.*;
@ -56,6 +58,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
*/
final class P11Cipher extends CipherSpi {
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
// mode constant for ECB mode
private static final int MODE_ECB = 3;
// mode constant for CBC mode
@ -678,115 +682,123 @@ final class P11Cipher extends CipherSpi {
throw new ShortBufferException();
}
int origPos = inBuffer.position();
NIO_ACCESS.acquireSession(inBuffer);
try {
ensureInitialized();
NIO_ACCESS.acquireSession(outBuffer);
try {
ensureInitialized();
long inAddr = 0;
int inOfs = 0;
byte[] inArray = null;
long inAddr = 0;
int inOfs = 0;
byte[] inArray = null;
if (inBuffer instanceof DirectBuffer) {
inAddr = ((DirectBuffer) inBuffer).address();
inOfs = origPos;
} else if (inBuffer.hasArray()) {
inArray = inBuffer.array();
inOfs = (origPos + inBuffer.arrayOffset());
}
long outAddr = 0;
int outOfs = 0;
byte[] outArray = null;
if (outBuffer instanceof DirectBuffer) {
outAddr = ((DirectBuffer) outBuffer).address();
outOfs = outBuffer.position();
} else {
if (outBuffer.hasArray()) {
outArray = outBuffer.array();
outOfs = (outBuffer.position() + outBuffer.arrayOffset());
} else {
outArray = new byte[outLen];
if (inBuffer instanceof DirectBuffer dInBuffer) {
inAddr = dInBuffer.address();
inOfs = origPos;
} else if (inBuffer.hasArray()) {
inArray = inBuffer.array();
inOfs = (origPos + inBuffer.arrayOffset());
}
}
int k = 0;
int newPadBufferLen = 0;
if (paddingObj != null && (!encrypt || reqBlockUpdates)) {
if (padBufferLen != 0) {
if (padBufferLen != padBuffer.length) {
int bufCapacity = padBuffer.length - padBufferLen;
if (inLen > bufCapacity) {
bufferInputBytes(inBuffer, bufCapacity);
inOfs += bufCapacity;
inLen -= bufCapacity;
} else {
bufferInputBytes(inBuffer, inLen);
return 0;
long outAddr = 0;
int outOfs = 0;
byte[] outArray = null;
if (outBuffer instanceof DirectBuffer dOutBuffer) {
outAddr = dOutBuffer.address();
outOfs = outBuffer.position();
} else {
if (outBuffer.hasArray()) {
outArray = outBuffer.array();
outOfs = (outBuffer.position() + outBuffer.arrayOffset());
} else {
outArray = new byte[outLen];
}
}
int k = 0;
int newPadBufferLen = 0;
if (paddingObj != null && (!encrypt || reqBlockUpdates)) {
if (padBufferLen != 0) {
if (padBufferLen != padBuffer.length) {
int bufCapacity = padBuffer.length - padBufferLen;
if (inLen > bufCapacity) {
bufferInputBytes(inBuffer, bufCapacity);
inOfs += bufCapacity;
inLen -= bufCapacity;
} else {
bufferInputBytes(inBuffer, inLen);
return 0;
}
}
if (encrypt) {
k = token.p11.C_EncryptUpdate(session.id(), 0,
padBuffer, 0, padBufferLen, outAddr, outArray,
outOfs, outLen);
} else {
k = token.p11.C_DecryptUpdate(session.id(), 0,
padBuffer, 0, padBufferLen, outAddr, outArray,
outOfs, outLen);
}
padBufferLen = 0;
}
newPadBufferLen = inLen & (blockSize - 1);
if (!encrypt && newPadBufferLen == 0) {
// While decrypting with implUpdate, the last encrypted block
// is always held in a buffer. If it's the final one (unknown
// at this point), it may contain padding bytes and need further
// processing. In implDoFinal (where we know it's the final one)
// the buffer is decrypted, unpadded and returned.
newPadBufferLen = padBuffer.length;
}
inLen -= newPadBufferLen;
}
if (inLen > 0) {
if (inAddr == 0 && inArray == null) {
inArray = new byte[inLen];
inBuffer.get(inArray);
} else {
inBuffer.position(inBuffer.position() + inLen);
}
if (encrypt) {
k = token.p11.C_EncryptUpdate(session.id(), 0,
padBuffer, 0, padBufferLen, outAddr, outArray,
outOfs, outLen);
k += token.p11.C_EncryptUpdate(session.id(), inAddr,
inArray, inOfs, inLen, outAddr, outArray,
(outOfs + k), (outLen - k));
} else {
k = token.p11.C_DecryptUpdate(session.id(), 0,
padBuffer, 0, padBufferLen, outAddr, outArray,
outOfs, outLen);
k += token.p11.C_DecryptUpdate(session.id(), inAddr,
inArray, inOfs, inLen, outAddr, outArray,
(outOfs + k), (outLen - k));
}
padBufferLen = 0;
}
newPadBufferLen = inLen & (blockSize - 1);
if (!encrypt && newPadBufferLen == 0) {
// While decrypting with implUpdate, the last encrypted block
// is always held in a buffer. If it's the final one (unknown
// at this point), it may contain padding bytes and need further
// processing. In implDoFinal (where we know it's the final one)
// the buffer is decrypted, unpadded and returned.
newPadBufferLen = padBuffer.length;
// update 'padBuffer' if using our own padding impl.
if (paddingObj != null && newPadBufferLen > 0) {
bufferInputBytes(inBuffer, newPadBufferLen);
}
inLen -= newPadBufferLen;
}
if (inLen > 0) {
if (inAddr == 0 && inArray == null) {
inArray = new byte[inLen];
inBuffer.get(inArray);
bytesBuffered += (inLen - k);
if (!(outBuffer instanceof DirectBuffer) &&
!outBuffer.hasArray()) {
outBuffer.put(outArray, outOfs, k);
} else {
inBuffer.position(inBuffer.position() + inLen);
outBuffer.position(outBuffer.position() + k);
}
if (encrypt) {
k += token.p11.C_EncryptUpdate(session.id(), inAddr,
inArray, inOfs, inLen, outAddr, outArray,
(outOfs + k), (outLen - k));
} else {
k += token.p11.C_DecryptUpdate(session.id(), inAddr,
inArray, inOfs, inLen, outAddr, outArray,
(outOfs + k), (outLen - k));
return k;
} catch (PKCS11Exception e) {
// Reset input buffer to its original position for
inBuffer.position(origPos);
if (e.match(CKR_BUFFER_TOO_SMALL)) {
throw (ShortBufferException)
(new ShortBufferException().initCause(e));
}
// Some implementations such as the NSS Software Token do not
// cancel the operation upon a C_EncryptUpdate/C_DecryptUpdate
// failure (as required by the PKCS#11 standard). See JDK-8258833
// for further information.
reset(true);
throw new ProviderException("update() failed", e);
} finally {
NIO_ACCESS.releaseSession(outBuffer);
}
// update 'padBuffer' if using our own padding impl.
if (paddingObj != null && newPadBufferLen > 0) {
bufferInputBytes(inBuffer, newPadBufferLen);
}
bytesBuffered += (inLen - k);
if (!(outBuffer instanceof DirectBuffer) &&
!outBuffer.hasArray()) {
outBuffer.put(outArray, outOfs, k);
} else {
outBuffer.position(outBuffer.position() + k);
}
return k;
} catch (PKCS11Exception e) {
// Reset input buffer to its original position for
inBuffer.position(origPos);
if (e.match(CKR_BUFFER_TOO_SMALL)) {
throw (ShortBufferException)
(new ShortBufferException().initCause(e));
}
// Some implementations such as the NSS Software Token do not
// cancel the operation upon a C_EncryptUpdate/C_DecryptUpdate
// failure (as required by the PKCS#11 standard). See JDK-8258833
// for further information.
reset(true);
throw new ProviderException("update() failed", e);
} finally {
NIO_ACCESS.releaseSession(inBuffer);
}
}
@ -877,99 +889,104 @@ final class P11Cipher extends CipherSpi {
}
boolean doCancel = true;
NIO_ACCESS.acquireSession(outBuffer);
try {
ensureInitialized();
try {
ensureInitialized();
long outAddr = 0;
byte[] outArray = null;
int outOfs = 0;
if (outBuffer instanceof DirectBuffer) {
outAddr = ((DirectBuffer) outBuffer).address();
outOfs = outBuffer.position();
} else {
if (outBuffer.hasArray()) {
outArray = outBuffer.array();
outOfs = outBuffer.position() + outBuffer.arrayOffset();
long outAddr = 0;
byte[] outArray = null;
int outOfs = 0;
if (outBuffer instanceof DirectBuffer dOutBuffer) {
outAddr = dOutBuffer.address();
outOfs = outBuffer.position();
} else {
outArray = new byte[outLen];
}
}
int k = 0;
if (encrypt) {
if (paddingObj != null) {
int startOff = 0;
if (reqBlockUpdates) {
// call C_EncryptUpdate first if the padBuffer is full
// to make room for padding bytes
if (padBufferLen == padBuffer.length) {
k = token.p11.C_EncryptUpdate(session.id(),
0, padBuffer, 0, padBufferLen,
outAddr, outArray, outOfs, outLen);
} else {
startOff = padBufferLen;
}
if (outBuffer.hasArray()) {
outArray = outBuffer.array();
outOfs = outBuffer.position() + outBuffer.arrayOffset();
} else {
outArray = new byte[outLen];
}
int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
startOff, requiredOutLen - bytesBuffered);
k += token.p11.C_EncryptUpdate(session.id(),
0, padBuffer, 0, startOff + actualPadLen,
outAddr, outArray, outOfs + k, outLen - k);
}
// Some implementations such as the NSS Software Token do not
// cancel the operation upon a C_EncryptUpdate failure (as
// required by the PKCS#11 standard). Cancel is not needed
// only after this point. See JDK-8258833 for further
// information.
doCancel = false;
k += token.p11.C_EncryptFinal(session.id(),
outAddr, outArray, (outOfs + k), (outLen - k));
} else {
// Special handling to match SunJCE provider behavior
if (bytesBuffered == 0 && padBufferLen == 0) {
return 0;
}
if (paddingObj != null) {
if (padBufferLen != 0) {
k = token.p11.C_DecryptUpdate(session.id(),
0, padBuffer, 0, padBufferLen,
0, padBuffer, 0, padBuffer.length);
padBufferLen = 0;
int k = 0;
if (encrypt) {
if (paddingObj != null) {
int startOff = 0;
if (reqBlockUpdates) {
// call C_EncryptUpdate first if the padBuffer is full
// to make room for padding bytes
if (padBufferLen == padBuffer.length) {
k = token.p11.C_EncryptUpdate(session.id(),
0, padBuffer, 0, padBufferLen,
outAddr, outArray, outOfs, outLen);
} else {
startOff = padBufferLen;
}
}
int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
startOff, requiredOutLen - bytesBuffered);
k += token.p11.C_EncryptUpdate(session.id(),
0, padBuffer, 0, startOff + actualPadLen,
outAddr, outArray, outOfs + k, outLen - k);
}
// Some implementations such as the NSS Software Token do not
// cancel the operation upon a C_DecryptUpdate failure (as
// cancel the operation upon a C_EncryptUpdate failure (as
// required by the PKCS#11 standard). Cancel is not needed
// only after this point. See JDK-8258833 for further
// information.
doCancel = false;
k += token.p11.C_DecryptFinal(session.id(),
0, padBuffer, k, padBuffer.length - k);
int actualPadLen = paddingObj.unpad(padBuffer, k);
k -= actualPadLen;
outArray = padBuffer;
outOfs = 0;
k += token.p11.C_EncryptFinal(session.id(),
outAddr, outArray, (outOfs + k), (outLen - k));
} else {
doCancel = false;
k = token.p11.C_DecryptFinal(session.id(),
outAddr, outArray, outOfs, outLen);
// Special handling to match SunJCE provider behavior
if (bytesBuffered == 0 && padBufferLen == 0) {
return 0;
}
if (paddingObj != null) {
if (padBufferLen != 0) {
k = token.p11.C_DecryptUpdate(session.id(),
0, padBuffer, 0, padBufferLen,
0, padBuffer, 0, padBuffer.length);
padBufferLen = 0;
}
// Some implementations such as the NSS Software Token do not
// cancel the operation upon a C_DecryptUpdate failure (as
// required by the PKCS#11 standard). Cancel is not needed
// only after this point. See JDK-8258833 for further
// information.
doCancel = false;
k += token.p11.C_DecryptFinal(session.id(),
0, padBuffer, k, padBuffer.length - k);
int actualPadLen = paddingObj.unpad(padBuffer, k);
k -= actualPadLen;
outArray = padBuffer;
outOfs = 0;
} else {
doCancel = false;
k = token.p11.C_DecryptFinal(session.id(),
outAddr, outArray, outOfs, outLen);
}
}
if ((!encrypt && paddingObj != null) ||
(!(outBuffer instanceof DirectBuffer) &&
!outBuffer.hasArray())) {
outBuffer.put(outArray, outOfs, k);
} else {
outBuffer.position(outBuffer.position() + k);
}
return k;
} catch (PKCS11Exception e) {
handleException(e);
throw new ProviderException("doFinal() failed", e);
} finally {
reset(doCancel);
}
if ((!encrypt && paddingObj != null) ||
(!(outBuffer instanceof DirectBuffer) &&
!outBuffer.hasArray())) {
outBuffer.put(outArray, outOfs, k);
} else {
outBuffer.position(outBuffer.position() + k);
}
return k;
} catch (PKCS11Exception e) {
handleException(e);
throw new ProviderException("doFinal() failed", e);
} finally {
reset(doCancel);
NIO_ACCESS.releaseSession(outBuffer);
}
}

View File

@ -25,13 +25,14 @@
package sun.security.pkcs11;
import java.util.*;
import java.nio.ByteBuffer;
import java.security.*;
import javax.crypto.SecretKey;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import sun.nio.ch.DirectBuffer;
import sun.security.util.MessageDigestSpi2;
@ -55,6 +56,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
final class P11Digest extends MessageDigestSpi implements Cloneable,
MessageDigestSpi2 {
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
/* fields initialized, no session acquired */
private static final int S_BLANK = 1;
@ -268,13 +271,12 @@ final class P11Digest extends MessageDigestSpi implements Cloneable,
return;
}
if (!(byteBuffer instanceof DirectBuffer)) {
if (!(byteBuffer instanceof DirectBuffer dByteBuffer)) {
super.engineUpdate(byteBuffer);
return;
}
fetchSession();
long addr = ((DirectBuffer)byteBuffer).address();
int ofs = byteBuffer.position();
try {
if (state == S_BUFFERED) {
@ -285,7 +287,12 @@ final class P11Digest extends MessageDigestSpi implements Cloneable,
token.p11.C_DigestUpdate(session.id(), 0, buffer, 0, bufOfs);
bufOfs = 0;
}
token.p11.C_DigestUpdate(session.id(), addr + ofs, null, 0, len);
NIO_ACCESS.acquireSession(byteBuffer);
try {
token.p11.C_DigestUpdate(session.id(), dByteBuffer.address() + ofs, null, 0, len);
} finally {
NIO_ACCESS.releaseSession(byteBuffer);
}
byteBuffer.position(ofs + len);
} catch (PKCS11Exception e) {
engineReset();

View File

@ -37,13 +37,14 @@ import javax.crypto.spec.*;
import java.util.HexFormat;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import sun.nio.ch.DirectBuffer;
import sun.security.jca.JCAUtil;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
import static sun.security.pkcs11.TemplateManager.*;
import static sun.security.pkcs11.P11Cipher.*;
/**
* P11 KeyWrap Cipher implementation class for native impl which only support
@ -58,6 +59,8 @@ import static sun.security.pkcs11.P11Cipher.*;
*/
final class P11KeyWrapCipher extends CipherSpi {
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
private static final int BLK_SIZE = 8;
// supported mode and padding with AES cipher
@ -552,78 +555,88 @@ final class P11KeyWrapCipher extends CipherSpi {
boolean doCancel = true;
int k = 0;
NIO_ACCESS.acquireSession(inBuffer);
try {
ensureInitialized();
NIO_ACCESS.acquireSession(outBuffer);
try {
try {
ensureInitialized();
long inAddr = 0;
byte[] in = null;
int inOfs = 0;
long inAddr = 0;
byte[] in = null;
int inOfs = 0;
if (dataBuffer.size() > 0) {
if (inBuffer != null && inLen > 0) {
byte[] temp = new byte[inLen];
inBuffer.get(temp);
dataBuffer.write(temp, 0, temp.length);
}
if (dataBuffer.size() > 0) {
if (inBuffer != null && inLen > 0) {
byte[] temp = new byte[inLen];
inBuffer.get(temp);
dataBuffer.write(temp, 0, temp.length);
}
in = dataBuffer.toByteArray();
inOfs = 0;
inLen = in.length;
} else {
if (inBuffer instanceof DirectBuffer) {
inAddr = ((DirectBuffer) inBuffer).address();
inOfs = inBuffer.position();
} else {
if (inBuffer.hasArray()) {
in = inBuffer.array();
inOfs = inBuffer.position() + inBuffer.arrayOffset();
in = dataBuffer.toByteArray();
inOfs = 0;
inLen = in.length;
} else {
in = new byte[inLen];
inBuffer.get(in);
if (inBuffer instanceof DirectBuffer dInBuffer) {
inAddr = dInBuffer.address();
inOfs = inBuffer.position();
} else {
if (inBuffer.hasArray()) {
in = inBuffer.array();
inOfs = inBuffer.position() + inBuffer.arrayOffset();
} else {
in = new byte[inLen];
inBuffer.get(in);
}
}
}
long outAddr = 0;
byte[] outArray = null;
int outOfs = 0;
if (outBuffer instanceof DirectBuffer dOutBuffer) {
outAddr = dOutBuffer.address();
outOfs = outBuffer.position();
} else {
if (outBuffer.hasArray()) {
outArray = outBuffer.array();
outOfs = outBuffer.position() + outBuffer.arrayOffset();
} else {
outArray = new byte[outLen];
}
}
}
}
long outAddr = 0;
byte[] outArray = null;
int outOfs = 0;
if (outBuffer instanceof DirectBuffer) {
outAddr = ((DirectBuffer) outBuffer).address();
outOfs = outBuffer.position();
} else {
if (outBuffer.hasArray()) {
outArray = outBuffer.array();
outOfs = outBuffer.position() + outBuffer.arrayOffset();
} else {
outArray = new byte[outLen];
}
}
if (opmode == Cipher.ENCRYPT_MODE) {
k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
outAddr, outArray, outOfs, outLen);
doCancel = false;
} else {
// Special handling to match SunJCE provider behavior
if (inLen == 0) {
return 0;
if (opmode == Cipher.ENCRYPT_MODE) {
k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
outAddr, outArray, outOfs, outLen);
doCancel = false;
} else {
// Special handling to match SunJCE provider behavior
if (inLen == 0) {
return 0;
}
k = token.p11.C_Decrypt(session.id(), inAddr, in, inOfs, inLen,
outAddr, outArray, outOfs, outLen);
doCancel = false;
}
inBuffer.position(inBuffer.limit());
outBuffer.position(outBuffer.position() + k);
} catch (PKCS11Exception e) {
// As per the PKCS#11 standard, C_Encrypt and C_Decrypt may only
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
// successful calls to determine the output length. However,
// these cases are not expected here because the output length
// is checked in the OpenJDK side before making the PKCS#11 call.
// Thus, doCancel can safely be 'false'.
doCancel = false;
handleEncException("doFinal() failed", e);
} finally {
reset(doCancel);
}
k = token.p11.C_Decrypt(session.id(), inAddr, in, inOfs, inLen,
outAddr, outArray, outOfs, outLen);
doCancel = false;
} finally {
NIO_ACCESS.releaseSession(outBuffer);
}
inBuffer.position(inBuffer.limit());
outBuffer.position(outBuffer.position() + k);
} catch (PKCS11Exception e) {
// As per the PKCS#11 standard, C_Encrypt and C_Decrypt may only
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
// successful calls to determine the output length. However,
// these cases are not expected here because the output length
// is checked in the OpenJDK side before making the PKCS#11 call.
// Thus, doCancel can safely be 'false'.
doCancel = false;
handleEncException("doFinal() failed", e);
} finally {
reset(doCancel);
NIO_ACCESS.releaseSession(inBuffer);
}
return k;
}

View File

@ -32,6 +32,8 @@ import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.MacSpi;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import sun.nio.ch.DirectBuffer;
import sun.security.pkcs11.wrapper.*;
@ -55,6 +57,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
*/
final class P11Mac extends MacSpi {
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
// token instance
private final Token token;
@ -246,13 +250,17 @@ final class P11Mac extends MacSpi {
if (len <= 0) {
return;
}
if (!(byteBuffer instanceof DirectBuffer directBuffer)) {
if (!(byteBuffer instanceof DirectBuffer dByteBuffer)) {
super.engineUpdate(byteBuffer);
return;
}
long addr = directBuffer.address();
int ofs = byteBuffer.position();
token.p11.C_SignUpdate(session.id(), addr + ofs, null, 0, len);
NIO_ACCESS.acquireSession(byteBuffer);
try {
token.p11.C_SignUpdate(session.id(), dByteBuffer.address() + ofs, null, 0, len);
} finally {
NIO_ACCESS.releaseSession(byteBuffer);
}
byteBuffer.position(ofs + len);
} catch (PKCS11Exception e) {
throw new ProviderException("update() failed", e);

View File

@ -25,13 +25,13 @@
package sun.security.pkcs11;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import sun.nio.ch.DirectBuffer;
import java.util.Hashtable;
import java.util.Arrays;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.MGF1ParameterSpec;
@ -68,6 +68,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
*/
final class P11PSSSignature extends SignatureSpi {
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
private static final boolean DEBUG = false;
// mappings of digest algorithms and their output length in bytes
@ -613,14 +615,15 @@ final class P11PSSSignature extends SignatureSpi {
isActive = true;
switch (type) {
case T_UPDATE -> {
if (byteBuffer instanceof DirectBuffer == false) {
if (!(byteBuffer instanceof DirectBuffer dByteBuffer)) {
// cannot do better than default impl
super.engineUpdate(byteBuffer);
return;
}
long addr = ((DirectBuffer) byteBuffer).address();
int ofs = byteBuffer.position();
NIO_ACCESS.acquireSession(byteBuffer);
try {
long addr = dByteBuffer.address();
if (mode == M_SIGN) {
if (DEBUG) System.out.println(this + ": Calling C_SignUpdate");
token.p11.C_SignUpdate
@ -635,6 +638,8 @@ final class P11PSSSignature extends SignatureSpi {
} catch (PKCS11Exception e) {
reset(false);
throw new ProviderException("Update failed", e);
} finally {
NIO_ACCESS.releaseSession(byteBuffer);
}
}
case T_DIGEST -> {

View File

@ -32,10 +32,12 @@ import java.nio.ByteBuffer;
import java.security.*;
import java.security.interfaces.*;
import java.security.spec.AlgorithmParameterSpec;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import sun.nio.ch.DirectBuffer;
import sun.security.util.*;
import sun.security.x509.AlgorithmId;
import sun.security.rsa.RSAUtil;
import sun.security.rsa.RSAPadding;
@ -98,6 +100,8 @@ import sun.security.util.KeyUtil;
*/
final class P11Signature extends SignatureSpi {
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
// token instance
private final Token token;
@ -575,14 +579,15 @@ final class P11Signature extends SignatureSpi {
}
switch (type) {
case T_UPDATE -> {
if (!(byteBuffer instanceof DirectBuffer)) {
if (!(byteBuffer instanceof DirectBuffer dByteBuffer)) {
// cannot do better than default impl
super.engineUpdate(byteBuffer);
return;
}
long addr = ((DirectBuffer) byteBuffer).address();
int ofs = byteBuffer.position();
NIO_ACCESS.acquireSession(byteBuffer);
try {
long addr = dByteBuffer.address();
if (mode == M_SIGN) {
token.p11.C_SignUpdate
(session.id(), addr + ofs, null, 0, len);
@ -595,6 +600,8 @@ final class P11Signature extends SignatureSpi {
} catch (PKCS11Exception e) {
reset(false);
throw new ProviderException("Update failed", e);
} finally {
NIO_ACCESS.releaseSession(byteBuffer);
}
}
case T_DIGEST -> {

View File

@ -53,6 +53,8 @@ import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.NotificationHandler;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpSocketOption;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import sun.net.util.IPAddressUtil;
import sun.nio.ch.DirectBuffer;
import sun.nio.ch.IOStatus;
@ -74,6 +76,9 @@ import static sun.nio.ch.sctp.ResultContainer.SHUTDOWN;
public class SctpChannelImpl extends SctpChannel
implements SelChImpl
{
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
private final FileDescriptor fd;
private final int fdVal;
@ -839,11 +844,16 @@ public class SctpChannelImpl extends SctpChannel
boolean peek)
throws IOException
{
int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem, peek);
NIO_ACCESS.acquireSession(bb);
try {
int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem, peek);
if (n > 0)
bb.position(pos + n);
return n;
if (n > 0)
bb.position(pos + n);
return n;
} finally {
NIO_ACCESS.releaseSession(bb);
}
}
private InternalNotificationHandler internalNotificationHandler =
@ -1028,11 +1038,16 @@ public class SctpChannelImpl extends SctpChannel
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
port, -1 /*121*/, streamNumber, unordered, ppid);
if (written > 0)
bb.position(pos + written);
return written;
NIO_ACCESS.acquireSession(bb);
try {
int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
port, -1 /*121*/, streamNumber, unordered, ppid);
if (written > 0)
bb.position(pos + written);
return written;
} finally {
NIO_ACCESS.releaseSession(bb);
}
}
@Override

View File

@ -53,6 +53,8 @@ import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.SctpMultiChannel;
import com.sun.nio.sctp.SctpSocketOption;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import sun.net.util.IPAddressUtil;
import sun.nio.ch.DirectBuffer;
import sun.nio.ch.NativeThread;
@ -71,6 +73,8 @@ import static sun.nio.ch.sctp.ResultContainer.*;
public class SctpMultiChannelImpl extends SctpMultiChannel
implements SelChImpl
{
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
private final FileDescriptor fd;
private final int fdVal;
@ -583,10 +587,15 @@ public class SctpMultiChannelImpl extends SctpMultiChannel
int rem,
int pos)
throws IOException {
int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem);
if (n > 0)
bb.position(pos + n);
return n;
NIO_ACCESS.acquireSession(bb);
try {
int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem);
if (n > 0)
bb.position(pos + n);
return n;
} finally {
NIO_ACCESS.releaseSession(bb);
}
}
private InternalNotificationHandler internalNotificationHandler =
@ -908,11 +917,16 @@ public class SctpMultiChannelImpl extends SctpMultiChannel
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
port, assocId, streamNumber, unordered, ppid);
if (written > 0)
bb.position(pos + written);
return written;
NIO_ACCESS.acquireSession(bb);
try {
int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
port, assocId, streamNumber, unordered, ppid);
if (written > 0)
bb.position(pos + written);
return written;
} finally {
NIO_ACCESS.releaseSession(bb);
}
}
@Override