diff --git a/source/smbd/process.c b/source/smbd/process.c
index 446b868..403c7c6 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -1645,6 +1645,7 @@ void construct_reply_common(const char *inbuf, char *outbuf)
 void chain_reply(struct smb_request *req)
 {
 	static char *orig_inbuf;
+	static int orig_size;
 
 	/*
 	 * Dirty little const_discard: We mess with req->inbuf, which is
@@ -1679,13 +1680,24 @@ void chain_reply(struct smb_request *req)
 	if (chain_size == 0) {
 		/* this is the first part of the chain */
 		orig_inbuf = inbuf;
+		orig_size = size;
 	}
 
+	/* Validate smb_off2 */
+	if ((smb_off2 < smb_wct - 4) || orig_size < (smb_off2 + 4 - smb_wct)) {
+		exit_server_cleanly("Bad chained packet");
+		return;
+	}
 	/*
 	 * We need to save the output the caller added to the chain so that we
 	 * can splice it into the final output buffer later.
 	 */
 
+	if (outsize <= smb_wct) {
+		exit_server_cleanly("Bad chained packet");
+		return;
+	}
+
 	caller_outputlen = outsize - smb_wct;
 
 	caller_output = (char *)memdup(outbuf + smb_wct, caller_outputlen);