From 2197b3806b793594af60bd38e59c898716ee6082 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Fri, 8 Jul 2022 02:19:45 +0200 Subject: [PATCH] HBASE-27180 Fix multiple possible buffer leaks (#4597) * Fix multiple possible buffer leaks Motivation: When using ByteBuf you need to be very careful about releasing it as otherwise you might leak data. There were various places in the code-base where such a leak could happen. Modifications: - Fix possible buffer leaks - Ensure we call touch(...) so its easier to debug buffer leaks Result: Fix buffer leaks * Formatting * Revert some changes as requested * revert touch * Also release checksum and header buffers Signed-off-by: Duo Zhang --- .../hbase/io/asyncfs/FanOutOneBlockAsyncDFSOutput.java | 6 ++++++ .../io/asyncfs/FanOutOneBlockAsyncDFSOutputSaslHelper.java | 3 ++- .../io/asyncfs/TestFanOutOneBlockAsyncDFSOutputHang.java | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/hbase-asyncfs/src/main/java/org/apache/hadoop/hbase/io/asyncfs/FanOutOneBlockAsyncDFSOutput.java b/hbase-asyncfs/src/main/java/org/apache/hadoop/hbase/io/asyncfs/FanOutOneBlockAsyncDFSOutput.java index 8906f003bc8..a43bed31734 100644 --- a/hbase-asyncfs/src/main/java/org/apache/hadoop/hbase/io/asyncfs/FanOutOneBlockAsyncDFSOutput.java +++ b/hbase-asyncfs/src/main/java/org/apache/hadoop/hbase/io/asyncfs/FanOutOneBlockAsyncDFSOutput.java @@ -429,6 +429,12 @@ public class FanOutOneBlockAsyncDFSOutput implements AsyncFSOutput { future.completeExceptionally(new IOException("stream already broken")); // it's the one we have just pushed or just a no-op waitingAckQueue.removeFirst(); + + checksumBuf.release(); + headerBuf.release(); + + // This method takes ownership of the dataBuf so we need release it before returning. + dataBuf.release(); return; } // TODO: we should perhaps measure time taken per DN here; diff --git a/hbase-asyncfs/src/main/java/org/apache/hadoop/hbase/io/asyncfs/FanOutOneBlockAsyncDFSOutputSaslHelper.java b/hbase-asyncfs/src/main/java/org/apache/hadoop/hbase/io/asyncfs/FanOutOneBlockAsyncDFSOutputSaslHelper.java index 89f386c8d64..ee02d42d2d3 100644 --- a/hbase-asyncfs/src/main/java/org/apache/hadoop/hbase/io/asyncfs/FanOutOneBlockAsyncDFSOutputSaslHelper.java +++ b/hbase-asyncfs/src/main/java/org/apache/hadoop/hbase/io/asyncfs/FanOutOneBlockAsyncDFSOutputSaslHelper.java @@ -662,7 +662,8 @@ public final class FanOutOneBlockAsyncDFSOutputSaslHelper { } @Override - public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { + public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { + // Release buffer on removal. cBuf.release(); cBuf = null; } diff --git a/hbase-asyncfs/src/test/java/org/apache/hadoop/hbase/io/asyncfs/TestFanOutOneBlockAsyncDFSOutputHang.java b/hbase-asyncfs/src/test/java/org/apache/hadoop/hbase/io/asyncfs/TestFanOutOneBlockAsyncDFSOutputHang.java index 3a9c2979b6c..53fb37a8e0b 100644 --- a/hbase-asyncfs/src/test/java/org/apache/hadoop/hbase/io/asyncfs/TestFanOutOneBlockAsyncDFSOutputHang.java +++ b/hbase-asyncfs/src/test/java/org/apache/hadoop/hbase/io/asyncfs/TestFanOutOneBlockAsyncDFSOutputHang.java @@ -185,6 +185,8 @@ public class TestFanOutOneBlockAsyncDFSOutputHang extends AsyncFSTestBase { public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if (!(msg instanceof ByteBuf)) { ctx.fireChannelRead(msg); + } else { + ((ByteBuf) msg).release(); } } });