Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-121884

Server->Client custom payload packets can leak resources

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Minecraft 18w01a, 23w31a
    • Minecraft 1.12.2, Minecraft 17w45b, Minecraft 17w46a, Minecraft 1.14.1, Minecraft 1.14.2 Pre-Release 2, 1.15 Pre-Release 2, 1.17.1, 1.18.2, 22w16b
    • Confirmed

      Custom data packets have a PacketBuffer containing the data payload. While client->server packets release this buffer after the packet has been handled, server->client packets generally do not. (Compare processPacket for CPacketCustomPayload and SPacketCustomPayload)

      Strangely, the buffer can actually be released in NetHandlerPlayClient#handleCustomPayload, but only for "MC|TrList" packets.

      Putting the call to release in processPacket and removing the current "MC|TrList" special case seems like the best solution here.

      Here's a log extract from a detected leak: (seen on a decompiled client connecting to a local server in offline mode, passing -Dio.netty.leakDetection.level=PARANOID to client VM args)

      Nov 12, 2017 2:34:18 AM io.netty.util.ResourceLeakDetector reportTracedLeak
      SEVERE: LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
      Recent access records: 3
      #3:
      	io.netty.buffer.AdvancedLeakAwareByteBuf.toString(AdvancedLeakAwareByteBuf.java:744)
      	net.minecraft.network.PacketBuffer.toString(PacketBuffer.java:1289)
      	net.minecraft.network.PacketBuffer.readString(PacketBuffer.java:380)
      	net.minecraft.client.network.NetHandlerPlayClient.handleCustomPayload(NetHandlerPlayClient.java:1864)
      	net.minecraft.network.play.server.SPacketCustomPayload.processPacket(SPacketCustomPayload.java:54)
      	net.minecraft.network.play.server.SPacketCustomPayload.processPacket(SPacketCustomPayload.java:11)
      	net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:15)
      	java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
      	java.util.concurrent.FutureTask.run(FutureTask.java:266)
      	net.minecraft.util.Util.runTask(Util.java:50)
      	net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1068)
      	net.minecraft.client.Minecraft.run(Minecraft.java:398)
      	net.minecraft.client.main.Main.main(Main.java:118)
      	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	java.lang.reflect.Method.invoke(Method.java:498)
      	net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
      	GradleStart.main(GradleStart.java:26)
      #2:
      	io.netty.buffer.AdvancedLeakAwareByteBuf.readByte(AdvancedLeakAwareByteBuf.java:396)
      	net.minecraft.network.PacketBuffer.readByte(PacketBuffer.java:864)
      	net.minecraft.network.PacketBuffer.readVarInt(PacketBuffer.java:201)
      	net.minecraft.network.PacketBuffer.readString(PacketBuffer.java:368)
      	net.minecraft.client.network.NetHandlerPlayClient.handleCustomPayload(NetHandlerPlayClient.java:1864)
      	net.minecraft.network.play.server.SPacketCustomPayload.processPacket(SPacketCustomPayload.java:54)
      	net.minecraft.network.play.server.SPacketCustomPayload.processPacket(SPacketCustomPayload.java:11)
      	net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:15)
      	java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
      	java.util.concurrent.FutureTask.run(FutureTask.java:266)
      	net.minecraft.util.Util.runTask(Util.java:50)
      	net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1068)
      	net.minecraft.client.Minecraft.run(Minecraft.java:398)
      	net.minecraft.client.main.Main.main(Main.java:118)
      	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	java.lang.reflect.Method.invoke(Method.java:498)
      	net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
      	GradleStart.main(GradleStart.java:26)
      #1:
      	io.netty.buffer.AdvancedLeakAwareByteBuf.writeBytes(AdvancedLeakAwareByteBuf.java:600)
      	io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:829)
      	io.netty.buffer.WrappedByteBuf.readBytes(WrappedByteBuf.java:616)
      	io.netty.buffer.AdvancedLeakAwareByteBuf.readBytes(AdvancedLeakAwareByteBuf.java:469)
      	net.minecraft.network.PacketBuffer.readBytes(PacketBuffer.java:959)
      	net.minecraft.network.play.server.SPacketCustomPayload.readPacketData(SPacketCustomPayload.java:38)
      	net.minecraft.network.NettyPacketDecoder.decode(NettyPacketDecoder.java:38)
      	io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411)
      	io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
      	io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
      	io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
      	io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
      	io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
      	io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
      	io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:280)
      	io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:396)
      	io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
      	io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
      	io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:287)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
      	io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
      	io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
      	io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
      	io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
      	io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:624)
      	io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:559)
      	io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:476)
      	io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438)
      	io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
      	java.lang.Thread.run(Thread.java:748)
      Created at:
      	io.netty.util.ResourceLeakDetector.track(ResourceLeakDetector.java:237)
      	io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:327)
      	io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:181)
      	io.netty.buffer.AbstractByteBufAllocator.buffer(AbstractByteBufAllocator.java:117)
      	io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:828)
      	io.netty.buffer.WrappedByteBuf.readBytes(WrappedByteBuf.java:616)
      	io.netty.buffer.AdvancedLeakAwareByteBuf.readBytes(AdvancedLeakAwareByteBuf.java:469)
      	net.minecraft.network.PacketBuffer.readBytes(PacketBuffer.java:959)
      	net.minecraft.network.play.server.SPacketCustomPayload.readPacketData(SPacketCustomPayload.java:38)
      	net.minecraft.network.NettyPacketDecoder.decode(NettyPacketDecoder.java:38)
      	io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411)
      	io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
      	io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
      	io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
      	io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
      	io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
      	io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
      	io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:280)
      	io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:396)
      	io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
      	io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
      	io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:287)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
      	io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
      	io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
      	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
      	io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
      	io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
      	io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:624)
      	io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:559)
      	io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:476)
      	io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438)
      	io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
      	java.lang.Thread.run(Thread.java:748)
      

            Unassigned Unassigned
            quadraxis Ben Staddon
            Votes:
            15 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: