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

Fix BufferOverflowException during non-Unsafe PooledDirectByteBuf resize #9912

Merged
merged 5 commits into from
Jan 11, 2020

Conversation

njhill
Copy link
Member

@njhill njhill commented Dec 30, 2019

Motivation

Recent optimization #9765 introduced a bug where the native indices of the internal reused duplicate nio buffer are not properly reset prior to using it to copy data during a reallocation operation. This can result in BufferOverflowExceptions thrown during ByteBuf capacity changes.

The code path in question applies only to pooled direct buffers when Unsafe is disabled or not available.

Modification

Ensure ByteBuffer#clear() is always called on the reused internal nio buffer prior to returning it from PooledByteBuf#internalNioBuffer() (protected method); add unit test that exposes the bug.

Result

Fixes #9911

Motivation

Recent optimization netty#9765 introduced a bug where the native indices of
the internal reused duplicate nio buffer are not properly reset prior to
using it to copy data during a reallocation operation. This can result
in BufferOverflowExceptions thrown during ByteBuf capacity changes.

The code path in question applies only to pooled direct buffers when
Unsafe is disabled or not available.

Modification

Ensure ByteBuffer#clear() is always called on the reused internal nio
buffer prior to returning it from PooledByteBuf#internalNioBuffer()
(protected method); add unit test that exposes the bug.

Result

Fixes netty#9911
@netty-bot
Copy link

Can one of the admins verify this patch?

@normanmaurer normanmaurer added this to the 4.1.45.Final milestone Jan 10, 2020
@normanmaurer
Copy link
Member

@netty-bot test this please

@normanmaurer
Copy link
Member

@netty-bot test this please

@Test
public void testDirectArenaMemoryCopy() {
PooledByteBuf<ByteBuffer> src = unwrapIfNeeded(PooledByteBufAllocator.DEFAULT.directBuffer(512));
PooledByteBuf<ByteBuffer> dst = unwrapIfNeeded(PooledByteBufAllocator.DEFAULT.directBuffer(512));
Copy link
Member

Choose a reason for hiding this comment

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

@njhill this may produce leaks as you loose the "wrapper".

You need to do something like this:

ByteBuf src =PooledByteBufAllocator.DEFAULT.directBuffer(512);
ByteBuf dst = PooledByteBufAllocator.DEFAULT.directBuffer(512);

// This causes the internal reused ByteBuffer duplicate limit to be set to 128
dst.writeBytes(ByteBuffer.allocate(128));
         
// Ensure internal ByteBuffer duplicate limit is properly reset (used in memoryCopy non-Unsafe case)
PooledByteBuf<ByteBuffer> pooledSrc = unwrapIfNeeded(src);
PooledByteBuf<ByteBuffer> pooledDst = unwrapIfNeeded(dst);

pooledDst.chunk.arena.memoryCopy(pooledSrc.memory, 0, pooledDst, 512);

src.release();
dst.release();

Copy link
Member Author

Choose a reason for hiding this comment

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

@normanmaurer sorry I realized this after pushing but was already falling asleep :) now fixed

@normanmaurer
Copy link
Member

@netty-bot test this please

2 similar comments
@normanmaurer
Copy link
Member

@netty-bot test this please

@normanmaurer
Copy link
Member

@netty-bot test this please

@njhill
Copy link
Member Author

njhill commented Jan 10, 2020

@normanmaurer hopefully this will help #9943 :)

@normanmaurer normanmaurer merged commit 607bc05 into netty:4.1 Jan 11, 2020
@normanmaurer
Copy link
Member

@njhill thanks a lot

normanmaurer pushed a commit that referenced this pull request Jan 11, 2020
…ize (#9912)


Motivation

Recent optimization #9765 introduced a bug where the native indices of
the internal reused duplicate nio buffer are not properly reset prior to
using it to copy data during a reallocation operation. This can result
in BufferOverflowExceptions thrown during ByteBuf capacity changes.

The code path in question applies only to pooled direct buffers when
Unsafe is disabled or not available.

Modification

Ensure ByteBuffer#clear() is always called on the reused internal nio
buffer prior to returning it from PooledByteBuf#internalNioBuffer()
(protected method); add unit test that exposes the bug.

Result

Fixes #9911
@njhill njhill deleted the directpooled-realloc-fix branch January 11, 2020 05:17
ihanyong pushed a commit to ihanyong/netty that referenced this pull request Jul 31, 2020
…ize (netty#9912)


Motivation

Recent optimization netty#9765 introduced a bug where the native indices of
the internal reused duplicate nio buffer are not properly reset prior to
using it to copy data during a reallocation operation. This can result
in BufferOverflowExceptions thrown during ByteBuf capacity changes.

The code path in question applies only to pooled direct buffers when
Unsafe is disabled or not available.

Modification

Ensure ByteBuffer#clear() is always called on the reused internal nio
buffer prior to returning it from PooledByteBuf#internalNioBuffer()
(protected method); add unit test that exposes the bug.

Result

Fixes netty#9911
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

Successfully merging this pull request may close these issues.

BufferOverflowException with specific buffer sizes
3 participants