@sefler1987 I think you are right... We should call duplicate on the buffer first. Let me fix it
 Thank you so much~
 Fixed by https://github.com/netty/netty/pull/3930

"ByteBuf copiedBuffer(ByteBuffer buffer)" in Netty 4.0.24 is NOT thread safe
I'm not sure why this static method is not thread safe, but it bothers me a lot during the development. As the following code shows, the method firstly copy the position out and then set it back after copying. If there are two threads doing the same thing, the position may be stained.

```
    public static ByteBuf copiedBuffer(ByteBuffer buffer) {
        int length = buffer.remaining();
        if (length == 0) {
            return EMPTY_BUFFER;
        }
        byte[] copy = new byte[length];
        int position = buffer.position();
        try {
            buffer.get(copy);
        } finally {
            buffer.position(position);
        }
        return wrappedBuffer(copy).order(buffer.order());
    }
```

buffer/src/main/java/io/netty/buffer/Unpooled.java
buffer/src/main/java/io/netty/buffer/Unpooled.java
diff --git a/buffer/src/main/java/io/netty/buffer/Unpooled.java b/buffer/src/main/java/io/netty/buffer/Unpooled.java
index 0c071071cbc..742c17f49cb 100644
--- a/buffer/src/main/java/io/netty/buffer/Unpooled.java
+++ b/buffer/src/main/java/io/netty/buffer/Unpooled.java
@@ -392,13 +392,11 @@ public static ByteBuf copiedBuffer(ByteBuffer buffer) {
             return EMPTY_BUFFER;
         }
         byte[] copy = new byte[length];
-        int position = buffer.position();
-        try {
-            buffer.get(copy);
-        } finally {
-            buffer.position(position);
-        }
-        return wrappedBuffer(copy).order(buffer.order());
+        // Duplicate the buffer so we not adjust the position during our get operation.
+        // See https://github.com/netty/netty/issues/3896
+        ByteBuffer duplicate = buffer.duplicate();
+        duplicate.get(copy);
+        return wrappedBuffer(copy).order(duplicate.order());
     }
 
     /**
@@ -561,11 +559,11 @@ public static ByteBuf copiedBuffer(ByteBuffer... buffers) {
 
         byte[] mergedArray = new byte[length];
         for (int i = 0, j = 0; i < buffers.length; i ++) {
-            ByteBuffer b = buffers[i];
+            // Duplicate the buffer so we not adjust the position during our get operation.
+            // See https://github.com/netty/netty/issues/3896
+            ByteBuffer b = buffers[i].duplicate();
             int bLen = b.remaining();
-            int oldPos = b.position();
             b.get(mergedArray, j, bLen);
-            b.position(oldPos);
             j += bLen;
         }
 
