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

Possible Race in JdkSslEngine #4832

Closed
carl-mastrangelo opened this issue Feb 3, 2016 · 16 comments
Closed

Possible Race in JdkSslEngine #4832

carl-mastrangelo opened this issue Feb 3, 2016 · 16 comments

Comments

@carl-mastrangelo
Copy link
Member

Following from my previously filed issues, the conflicting thread access stack traces:

  Read of size 4 at 0x7fad488432e8 by thread T42:
    #0 java.nio.Buffer.remaining()I (Buffer.java:391)  
    #1 sun.security.ssl.EngineArgs.init(Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;II)V (EngineArgs.java:131)  
    #2 sun.security.ssl.EngineArgs.<init>([Ljava/nio/ByteBuffer;IILjava/nio/ByteBuffer;)V (EngineArgs.java:73)  
    #3 sun.security.ssl.SSLEngineImpl.wrap([Ljava/nio/ByteBuffer;IILjava/nio/ByteBuffer;)Ljavax/net/ssl/SSLEngineResult; (SSLEngineImpl.java:1172)  
    #4 javax.net.ssl.SSLEngine.wrap([Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)Ljavax/net/ssl/SSLEngineResult; (SSLEngine.java:509)  
    #5 io.netty.handler.ssl.JdkSslEngine.wrap([Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)Ljavax/net/ssl/SSLEngineResult; (JdkSslEngine.java:72)  
    #6 io.netty.handler.ssl.SslHandler.wrap(Lio/netty/buffer/ByteBufAllocator;Ljavax/net/ssl/SSLEngine;Lio/netty/buffer/ByteBuf;Lio/netty/buffer/ByteBuf;)Ljavax/net/ssl/SSLEngineResult; (SslHandler.java:682)  
    #7 io.netty.handler.ssl.SslHandler.wrapNonAppData(Lio/netty/channel/ChannelHandlerContext;Z)V (SslHandler.java:591)  
    #8 io.netty.handler.ssl.SslHandler.unwrap(Lio/netty/channel/ChannelHandlerContext;Lio/netty/buffer/ByteBuf;II)Z (SslHandler.java:1064)  
    #9 io.netty.handler.ssl.SslHandler.decode(Lio/netty/channel/ChannelHandlerContext;Lio/netty/buffer/ByteBuf;Ljava/util/List;)V (SslHandler.java:968) 

and

    #0 java.nio.Buffer.limit(I)Ljava/nio/Buffer; (Buffer.java:276)  
    #1 sun.security.ssl.EngineArgs.resetLim()V (EngineArgs.java:235)  
    #2 sun.security.ssl.SSLEngineImpl.wrap([Ljava/nio/ByteBuffer;IILjava/nio/ByteBuffer;)Ljavax/net/ssl/SSLEngineResult; (SSLEngineImpl.java:1198)  
    #3 javax.net.ssl.SSLEngine.wrap([Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)Ljavax/net/ssl/SSLEngineResult; (SSLEngine.java:509)  
    #4 io.netty.handler.ssl.JdkSslEngine.wrap([Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)Ljavax/net/ssl/SSLEngineResult; (JdkSslEngine.java:72)  
    #5 io.netty.handler.ssl.SslHandler.wrap(Lio/netty/buffer/ByteBufAllocator;Ljavax/net/ssl/SSLEngine;Lio/netty/buffer/ByteBuf;Lio/netty/buffer/ByteBuf;)Ljavax/net/ssl/SSLEngineResult; (SslHandler.java:682)  
    #6 io.netty.handler.ssl.SslHandler.wrapNonAppData(Lio/netty/channel/ChannelHandlerContext;Z)V (SslHandler.java:591)  
    #7 io.netty.handler.ssl.SslHandler.unwrap(Lio/netty/channel/ChannelHandlerContext;Lio/netty/buffer/ByteBuf;II)Z (SslHandler.java:1064)  
    #8 io.netty.handler.ssl.SslHandler.decode(Lio/netty/channel/ChannelHandlerContext;Lio/netty/buffer/ByteBuf;Ljava/util/List;)V (SslHandler.java:968)  
    #9 io.netty.handler.codec.ByteToMessageDecoder.callDecode(Lio/netty/channel/ChannelHandlerContext;Lio/netty/buffer/ByteBuf;Ljava/util/List;)V (ByteToMessageDecoder.java:360)  
    #10 io.netty.handler.codec.ByteToMessageDecoder.channelRead(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Object;)V (ByteToMessageDecoder.java:244)  
    #11 io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Object;)V (ChannelHandlerInvokerUtil.java:83)  

Hazarding a guess looks like it might be SslHandler.singleBuffer

cc: @nmittler & @normanmaurer

@normanmaurer
Copy link
Member

@carl-mastrangelo I'm a bit confused for this one as the same SslHandler instance should only be called from the same Thread. So how could this be a race ?

@carl-mastrangelo
Copy link
Member Author

Oops, forgot the header of the second one:
Previous write of size 4 at 0x7fad488432e8 by thread T44:

It is actually being hit from another thread.

@normanmaurer
Copy link
Member

And it's the same SslHandler ? Are you sure ? Also is this the full stacktrace ?

@carl-mastrangelo
Copy link
Member Author

  Read of size 4 at 0x7fad488432e8 by thread T42:
    #0 java.nio.Buffer.remaining()I (Buffer.java:391)  
    #1 sun.security.ssl.EngineArgs.init(Ljava/nio/ByteBuffer;[Ljava/nio/ByteBuffer;II)V (EngineArgs.java:131)  
    #2 sun.security.ssl.EngineArgs.<init>([Ljava/nio/ByteBuffer;IILjava/nio/ByteBuffer;)V (EngineArgs.java:73)  
    #3 sun.security.ssl.SSLEngineImpl.wrap([Ljava/nio/ByteBuffer;IILjava/nio/ByteBuffer;)Ljavax/net/ssl/SSLEngineResult; (SSLEngineImpl.java:1172)  
    #4 javax.net.ssl.SSLEngine.wrap([Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)Ljavax/net/ssl/SSLEngineResult; (SSLEngine.java:509)  
    #5 io.netty.handler.ssl.JdkSslEngine.wrap([Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)Ljavax/net/ssl/SSLEngineResult; (JdkSslEngine.java:72)  
    #6 io.netty.handler.ssl.SslHandler.wrap(Lio/netty/buffer/ByteBufAllocator;Ljavax/net/ssl/SSLEngine;Lio/netty/buffer/ByteBuf;Lio/netty/buffer/ByteBuf;)Ljavax/net/ssl/SSLEngineResult; (SslHandler.java:682)  
    #7 io.netty.handler.ssl.SslHandler.wrapNonAppData(Lio/netty/channel/ChannelHandlerContext;Z)V (SslHandler.java:591)  
    #8 io.netty.handler.ssl.SslHandler.unwrap(Lio/netty/channel/ChannelHandlerContext;Lio/netty/buffer/ByteBuf;II)Z (SslHandler.java:1064)  
    #9 io.netty.handler.ssl.SslHandler.decode(Lio/netty/channel/ChannelHandlerContext;Lio/netty/buffer/ByteBuf;Ljava/util/List;)V (SslHandler.java:968)  
    #10 io.netty.handler.codec.ByteToMessageDecoder.callDecode(Lio/netty/channel/ChannelHandlerContext;Lio/netty/buffer/ByteBuf;Ljava/util/List;)V (ByteToMessageDecoder.java:360)  
    #11 io.netty.handler.codec.ByteToMessageDecoder.channelRead(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Object;)V (ByteToMessageDecoder.java:244)  
    #12 io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Object;)V (ChannelHandlerInvokerUtil.java:83)  
    #13 io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Object;)V (DefaultChannelHandlerInvoker.java:163)  
    #14 io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(Ljava/lang/Object;)Lio/netty/channel/ChannelHandlerContext; (AbstractChannelHandlerContext.java:155)  
    #15 io.netty.channel.DefaultChannelPipeline.fireChannelRead(Ljava/lang/Object;)Lio/netty/channel/ChannelPipeline; (DefaultChannelPipeline.java:950)  
    #16 io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read()V (AbstractNioByteChannel.java:125)  
    #17 io.netty.channel.nio.NioEventLoop.processSelectedKey(Ljava/nio/channels/SelectionKey;Lio/netty/channel/nio/AbstractNioChannel;)V (NioEventLoop.java:510)  
    #18 io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized([Ljava/nio/channels/SelectionKey;)V (NioEventLoop.java:467)  
    #19 io.netty.channel.nio.NioEventLoop.processSelectedKeys()V (NioEventLoop.java:381)  
    #20 io.netty.channel.nio.NioEventLoop.run()V (NioEventLoop.java:353)  
    #21 io.netty.util.concurrent.SingleThreadEventExecutor$5.run()V (SingleThreadEventExecutor.java:742)  
    #22 java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V (ThreadPoolExecutor.java:1142)  
    #23 java.util.concurrent.ThreadPoolExecutor$Worker.run()V (ThreadPoolExecutor.java:617)  
    #24 java.lang.Thread.run()V (Thread.java:745)  

Which is spawned from:

#2 java.lang.Thread.start()V (Thread.java:714)  
    #3 java.util.concurrent.ThreadPoolExecutor.addWorker(Ljava/lang/Runnable;Z)Z (ThreadPoolExecutor.java:950)  
    #4 java.util.concurrent.ThreadPoolExecutor.execute(Ljava/lang/Runnable;)V (ThreadPoolExecutor.java:1357)  
    #5 io.netty.util.concurrent.SingleThreadEventExecutor.doStartThread()V (SingleThreadEventExecutor.java:731)  
    #6 io.netty.util.concurrent.SingleThreadEventExecutor.startThread()V (SingleThreadEventExecutor.java:724)  
    #7 io.netty.util.concurrent.SingleThreadEventExecutor.execute(Ljava/lang/Runnable;)V (SingleThreadEventExecutor.java:671)  
    #8 io.netty.channel.AbstractChannel$AbstractUnsafe.register(Lio/netty/channel/EventLoop;Lio/netty/channel/ChannelPromise;)V (AbstractChannel.java:474)  
    #9 io.netty.channel.SingleThreadEventLoop.register(Lio/netty/channel/Channel;Lio/netty/channel/ChannelPromise;)Lio/netty/channel/ChannelFuture; (SingleThreadEventLoop.java:68)  
    #10 io.netty.channel.SingleThreadEventLoop.register(Lio/netty/channel/Channel;)Lio/netty/channel/ChannelFuture; (SingleThreadEventLoop.java:56)  
    #11 io.netty.channel.MultithreadEventLoopGroup.register(Lio/netty/channel/Channel;)Lio/netty/channel/ChannelFuture; (MultithreadEventLoopGroup.java:75)  
    #12 io.netty.bootstrap.AbstractBootstrap.initAndRegister()Lio/netty/channel/ChannelFuture; (AbstractBootstrap.java:324)  
    #13 io.netty.bootstrap.Bootstrap.doResolveAndConnect(Ljava/net/SocketAddress;Ljava/net/SocketAddress;)Lio/netty/channel/ChannelFuture; (Bootstrap.java:157)  
    #14 io.netty.bootstrap.Bootstrap.connect(Ljava/net/SocketAddress;)Lio/netty/channel/ChannelFuture; (Bootstrap.java:139)  
    #15 io.grpc.netty.NettyClientTransport.start(Lio/grpc/internal/ClientTransport$Listener;)V (NettyClientTransport.java:164)  
    #16 io.grpc.internal.TransportSet$1.run()V (TransportSet.java:197)  
    #17 io.grpc.internal.TransportSet.scheduleConnection()V (TransportSet.java:221)  
    #18 io.grpc.internal.TransportSet.obtainActiveTransport()Lcom/google/common/util/concurrent/ListenableFuture; (TransportSet.java:161)  
    #19 io.grpc.internal.ManagedChannelImpl$3.getTransport(Lio/grpc/EquivalentAddressGroup;)Lcom/google/common/util/concurrent/ListenableFuture; (ManagedChannelImpl.java:397)  
    #20 io.grpc.SimpleLoadBalancerFactory$SimpleLoadBalancer.pickTransport(Lio/grpc/RequestKey;)Lcom/google/common/util/concurrent/ListenableFuture; (SimpleLoadBalancerFactory.java:99)  
    #21 io.grpc.internal.ManagedChannelImpl$1.get(Lio/grpc/CallOptions;)Lcom/google/common/util/concurrent/ListenableFuture; (ManagedChannelImpl.java:150)  
    #22 io.grpc.internal.ClientCallImpl.start(Lio/grpc/ClientCall$Listener;Lio/grpc/Metadata;)V (ClientCallImpl.java:213)  
    #23 io.grpc.stub.ClientCalls.startCall(Lio/grpc/ClientCall;Lio/grpc/ClientCall$Listener;Z)V (ClientCalls.java:245)  
    #24 io.grpc.stub.ClientCalls.asyncUnaryRequestCall(Lio/grpc/ClientCall;Ljava/lang/Object;Lio/grpc/ClientCall$Listener;Z)V (ClientCalls.java:225)  
    #25 io.grpc.stub.ClientCalls.futureUnaryCall(Lio/grpc/ClientCall;Ljava/lang/Object;)Lcom/google/common/util/concurrent/ListenableFuture; (ClientCalls.java:186)  
    #26 io.grpc.stub.ClientCalls.blockingUnaryCall(Lio/grpc/Channel;Lio/grpc/MethodDescriptor;Lio/grpc/CallOptions;Ljava/lang/Object;)Ljava/lang/Object; (ClientCalls.java:132)  

The second thread (T44) is:

 Previous write of size 4 at 0x7fad488432e8 by thread T44:
    #0 java.nio.Buffer.limit(I)Ljava/nio/Buffer; (Buffer.java:276)  
    #1 sun.security.ssl.EngineArgs.resetLim()V (EngineArgs.java:235)  
    #2 sun.security.ssl.SSLEngineImpl.wrap([Ljava/nio/ByteBuffer;IILjava/nio/ByteBuffer;)Ljavax/net/ssl/SSLEngineResult; (SSLEngineImpl.java:1198)  
    #3 javax.net.ssl.SSLEngine.wrap([Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)Ljavax/net/ssl/SSLEngineResult; (SSLEngine.java:509)  
    #4 io.netty.handler.ssl.JdkSslEngine.wrap([Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)Ljavax/net/ssl/SSLEngineResult; (JdkSslEngine.java:72)  
    #5 io.netty.handler.ssl.SslHandler.wrap(Lio/netty/buffer/ByteBufAllocator;Ljavax/net/ssl/SSLEngine;Lio/netty/buffer/ByteBuf;Lio/netty/buffer/ByteBuf;)Ljavax/net/ssl/SSLEngineResult; (SslHandler.java:682)  
    #6 io.netty.handler.ssl.SslHandler.wrapNonAppData(Lio/netty/channel/ChannelHandlerContext;Z)V (SslHandler.java:591)  
    #7 io.netty.handler.ssl.SslHandler.unwrap(Lio/netty/channel/ChannelHandlerContext;Lio/netty/buffer/ByteBuf;II)Z (SslHandler.java:1064)  
    #8 io.netty.handler.ssl.SslHandler.decode(Lio/netty/channel/ChannelHandlerContext;Lio/netty/buffer/ByteBuf;Ljava/util/List;)V (SslHandler.java:968)  
    #9 io.netty.handler.codec.ByteToMessageDecoder.callDecode(Lio/netty/channel/ChannelHandlerContext;Lio/netty/buffer/ByteBuf;Ljava/util/List;)V (ByteToMessageDecoder.java:360)  
    #10 io.netty.handler.codec.ByteToMessageDecoder.channelRead(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Object;)V (ByteToMessageDecoder.java:244)  
    #11 io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Object;)V (ChannelHandlerInvokerUtil.java:83)  
    #12 io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Object;)V (DefaultChannelHandlerInvoker.java:163)  
    #13 io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(Ljava/lang/Object;)Lio/netty/channel/ChannelHandlerContext; (AbstractChannelHandlerContext.java:155)  
    #14 io.netty.channel.DefaultChannelPipeline.fireChannelRead(Ljava/lang/Object;)Lio/netty/channel/ChannelPipeline; (DefaultChannelPipeline.java:950)  
    #15 io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read()V (AbstractNioByteChannel.java:125)  
    #16 io.netty.channel.nio.NioEventLoop.processSelectedKey(Ljava/nio/channels/SelectionKey;Lio/netty/channel/nio/AbstractNioChannel;)V (NioEventLoop.java:510)  
    #17 io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized([Ljava/nio/channels/SelectionKey;)V (NioEventLoop.java:467)  
    #18 io.netty.channel.nio.NioEventLoop.processSelectedKeys()V (NioEventLoop.java:381)  
    #19 io.netty.channel.nio.NioEventLoop.run()V (NioEventLoop.java:353)  
    #20 io.netty.util.concurrent.SingleThreadEventExecutor$5.run()V (SingleThreadEventExecutor.java:742)  
    #21 java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V (ThreadPoolExecutor.java:1142)  
    #22 java.util.concurrent.ThreadPoolExecutor$Worker.run()V (ThreadPoolExecutor.java:617)  
    #23 java.lang.Thread.run()V (Thread.java:745)  

which is spawned by

   #2 java.lang.Thread.start()V (Thread.java:714)  
    #3 java.util.concurrent.ThreadPoolExecutor.addWorker(Ljava/lang/Runnable;Z)Z (ThreadPoolExecutor.java:950)  
    #4 java.util.concurrent.ThreadPoolExecutor.execute(Ljava/lang/Runnable;)V (ThreadPoolExecutor.java:1357)  
    #5 io.netty.util.concurrent.SingleThreadEventExecutor.doStartThread()V (SingleThreadEventExecutor.java:731)  
    #6 io.netty.util.concurrent.SingleThreadEventExecutor.startThread()V (SingleThreadEventExecutor.java:724)  
    #7 io.netty.util.concurrent.SingleThreadEventExecutor.execute(Ljava/lang/Runnable;)V (SingleThreadEventExecutor.java:671)  
    #8 io.netty.channel.AbstractChannel$AbstractUnsafe.register(Lio/netty/channel/EventLoop;Lio/netty/channel/ChannelPromise;)V (AbstractChannel.java:474)  
    #9 io.netty.channel.SingleThreadEventLoop.register(Lio/netty/channel/Channel;Lio/netty/channel/ChannelPromise;)Lio/netty/channel/ChannelFuture; (SingleThreadEventLoop.java:68)  
    #10 io.netty.channel.SingleThreadEventLoop.register(Lio/netty/channel/Channel;)Lio/netty/channel/ChannelFuture; (SingleThreadEventLoop.java:56)  
    #11 io.netty.channel.MultithreadEventLoopGroup.register(Lio/netty/channel/Channel;)Lio/netty/channel/ChannelFuture; (MultithreadEventLoopGroup.java:75)  
    #12 io.netty.bootstrap.ServerBootstrap$ServerBootstrapAcceptor.channelRead(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Object;)V (ServerBootstrap.java:252)  
    #13 io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Object;)V (ChannelHandlerInvokerUtil.java:83)  
    #14 io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Object;)V (DefaultChannelHandlerInvoker.java:163)  
    #15 io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(Ljava/lang/Object;)Lio/netty/channel/ChannelHandlerContext; (AbstractChannelHandlerContext.java:155)  
    #16 io.netty.channel.DefaultChannelPipeline.fireChannelRead(Ljava/lang/Object;)Lio/netty/channel/ChannelPipeline; (DefaultChannelPipeline.java:950)  
    #17 io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read()V (AbstractNioMessageChannel.java:94)  
    #18 io.netty.channel.nio.NioEventLoop.processSelectedKey(Ljava/nio/channels/SelectionKey;Lio/netty/channel/nio/AbstractNioChannel;)V (NioEventLoop.java:510)  
    #19 io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized([Ljava/nio/channels/SelectionKey;)V (NioEventLoop.java:467)  
    #20 io.netty.channel.nio.NioEventLoop.processSelectedKeys()V (NioEventLoop.java:381)  
    #21 io.netty.channel.nio.NioEventLoop.run()V (NioEventLoop.java:353)  
    #22 io.netty.util.concurrent.SingleThreadEventExecutor$5.run()V (SingleThreadEventExecutor.java:742)  
    #23 java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V (ThreadPoolExecutor.java:1142)  
    #24 java.util.concurrent.ThreadPoolExecutor$Worker.run()V (ThreadPoolExecutor.java:617)  
    #25 java.lang.Thread.run()V (Thread.java:745)  

@normanmaurer
Copy link
Member

@carl-mastrangelo sorry for all the question but how can I see that it is the same instance of SslHandler ? From the stacktraces it is always called because of NioByteUnsafe.read() which can only be called from one Thread per Channel.

@carl-mastrangelo
Copy link
Member Author

It may be that the description of this bug is wrong, and the bug is somewhere else. The memory address is the same in both cases, and looks to be triggered by a write followed by a read on separate threads.

@normanmaurer
Copy link
Member

@carl-mastrangelo hmm... both traces have io.netty.channel.nio.NioEventLoop.processSelectedKeys with means it is a read. Why you think it is a write ?

@carl-mastrangelo
Copy link
Member Author

In the top most stack trace, it has the header:

  Read of size 4 at 0x7fad488432e8 by thread T42:
    #0 java.nio.Buffer.remaining()I (Buffer.java:391)  

Which is why I suspect it is a RaW hazard.

@carl-mastrangelo
Copy link
Member Author

I looked into this again when rerunning the race detector. I see the issue clearly now: The Buffer being modified is Unpooled.EMPTY_BUFFER. The empty buffer has a nioBuffer attached which is concurrently modified in two places by the SSLEngine. I think this is benign, but it adds noise to the race detector output, and could possibly be used to frighten small shildren.

Is there any reason EMPTY_BUFFER has to be backed by an actual nioBuffer? Could it work without one?

Side note: is it even safe to call SSLEngine concurrently? Isn't SSL data inherently linear and dependent on previous data?

@normanmaurer
Copy link
Member

It needs to be backed by one as SSLEngine works on ByteBuffer.

Am 02.07.2016 um 03:39 schrieb Carl Mastrangelo notifications@github.com:

I looked into this again when rerunning the race detector. I see the issue clearly now: The Buffer being modified is Unpooled.EMPTY_BUFFER. The empty buffer has a nioBuffer attached which is concurrently modified in two places by the SSLEngine. I think this is benign, but it adds noise to the race detector output, and could possibly be used to frighten small shildren.

Is there any reason EMPTY_BUFFER has to be backed by an actual nioBuffer? Could it work without one?

Side note: is it even safe to call SSLEngine concurrently? Isn't SSL data inherently linear and dependent on previous data?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@carl-mastrangelo
Copy link
Member Author

Would it make more sense for the SSL Handler to just make's its own empty buffer, since the SSLEngine is going to be modifying it?

@normanmaurer
Copy link
Member

How is it modifing it? Its empty with a limit and capacity of 0. there is techical no way to modify it

Am 02.07.2016 um 18:12 schrieb Carl Mastrangelo notifications@github.com:

Would it make more sense for the SSL Handler to just make's its own empty buffer, since the SSLEngine is going to be modifying it?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@carl-mastrangelo
Copy link
Member Author

The call to java.nio.Buffer.limit(I)Ljava/nio/Buffer; (Buffer.java:276) is mutating the buffer, while #0 java.nio.Buffer.remaining()I (Buffer.java:391) is reading from it. The race is that these are not synchronized.

@carl-mastrangelo
Copy link
Member Author

Alternatively, Buffer and ByteBuffer are not final. It would be easy to make a "empty" noop Buffer to just ignore all calls and have that be the empty buffer.

@normanmaurer
Copy link
Member

These are not final but constructor is package private so nope this is not possible

Am 02.07.2016 um 18:32 schrieb Carl Mastrangelo notifications@github.com:

Alternatively, Buffer and ByteBuffer are not final. It would be easy to make a "empty" noop Buffer to just ignore all calls and have that be the empty buffer.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@normanmaurer
Copy link
Member

I think it is fine as it is... @carl-mastrangelo please reopen if you not agree

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants