From df4812df65d01889ba93bce1415e01461500208d Mon Sep 17 00:00:00 2001 From: "Doroszlai, Attila" <6454655+adoroszlai@users.noreply.github.com> Date: Mon, 12 Dec 2022 19:02:49 +0100 Subject: [PATCH] HADOOP-18569. NFS Gateway may release buffer too early (#5207) --- .../java/org/apache/hadoop/oncrpc/RpcProgram.java | 13 +++++++++++-- .../main/java/org/apache/hadoop/oncrpc/RpcUtil.java | 8 +++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/RpcProgram.java b/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/RpcProgram.java index 8b8d558255f..cff6693f6aa 100644 --- a/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/RpcProgram.java +++ b/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/RpcProgram.java @@ -26,6 +26,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.util.ReferenceCountUtil; import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.hadoop.oncrpc.RpcAcceptedReply.AcceptState; import org.apache.hadoop.oncrpc.security.VerifierNone; @@ -163,8 +164,16 @@ public abstract class RpcProgram extends ChannelInboundHandlerAdapter { public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { RpcInfo info = (RpcInfo) msg; + try { + channelRead(ctx, info); + } finally { + ReferenceCountUtil.release(info.data()); + } + } + + private void channelRead(ChannelHandlerContext ctx, RpcInfo info) + throws Exception { RpcCall call = (RpcCall) info.header(); - SocketAddress remoteAddress = info.remoteAddress(); if (LOG.isTraceEnabled()) { LOG.trace(program + " procedure #" + call.getProcedure()); @@ -256,4 +265,4 @@ public abstract class RpcProgram extends ChannelInboundHandlerAdapter { public int getPortmapUdpTimeoutMillis() { return portmapUdpTimeoutMillis; } -} \ No newline at end of file +} diff --git a/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/RpcUtil.java b/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/RpcUtil.java index e8bc27d687f..784e8c79618 100644 --- a/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/RpcUtil.java +++ b/hadoop-common-project/hadoop-nfs/src/main/java/org/apache/hadoop/oncrpc/RpcUtil.java @@ -129,15 +129,17 @@ public final class RpcUtil { RpcInfo info = null; try { RpcCall callHeader = RpcCall.read(in); - ByteBuf dataBuffer = Unpooled.wrappedBuffer(in.buffer() - .slice()); + ByteBuf dataBuffer = buf.slice(b.position(), b.remaining()); info = new RpcInfo(callHeader, dataBuffer, ctx, ctx.channel(), remoteAddress); } catch (Exception exc) { LOG.info("Malformed RPC request from " + remoteAddress); } finally { - buf.release(); + // only release buffer if it is not passed to downstream handler + if (info == null) { + buf.release(); + } } if (info != null) {