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);