[SCM] Samba Shared Repository - branch master updated - 2719216d60088eb3f10a2e3e968f15e8089b5491

Volker Lendecke vlendec at samba.org
Fri Nov 28 08:32:58 GMT 2008


The branch, master has been updated
       via  2719216d60088eb3f10a2e3e968f15e8089b5491 (commit)
      from  9a3be6f0f8e120797a02fa1be60b51812cfd86f5 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 2719216d60088eb3f10a2e3e968f15e8089b5491
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Nov 8 17:08:57 2008 +0100

    Consolidate the buffer checks for the reply_trans style functions
    
    This is the one where I found the problem that led to 3.2.5. So if there is one
    checkin in the last year that I would like others to review and *understand*,
    it is this one :-)
    
    Volker

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/ipc.c     |   73 +++++++++++-----------------------------------
 source3/smbd/nttrans.c |   75 +++++++++++------------------------------------
 source3/smbd/trans2.c  |   75 +++++++++++------------------------------------
 3 files changed, 54 insertions(+), 169 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index bf9b1d8..649ead4 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -503,7 +503,6 @@ void reply_trans(struct smb_request *req)
 	unsigned int pscnt;
 	struct trans_state *state;
 	NTSTATUS result;
-	unsigned int av_size;
 
 	START_PROFILE(SMBtrans);
 
@@ -513,7 +512,6 @@ void reply_trans(struct smb_request *req)
 		return;
 	}
 
-	av_size = smb_len(req->inbuf);
 	dsoff = SVAL(req->vwv+12, 0);
 	dscnt = SVAL(req->vwv+11, 0);
 	psoff = SVAL(req->vwv+10, 0);
@@ -559,6 +557,12 @@ void reply_trans(struct smb_request *req)
 		goto bad_param;
 
 	if (state->total_data)  {
+
+		if (trans_oob(state->total_data, 0, dscnt)
+		    || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
+			goto bad_param;
+		}
+
 		/* Can't use talloc here, the core routines do realloc on the
 		 * params and data. Out of paranoia, 100 bytes too many. */
 		state->data = (char *)SMB_MALLOC(state->total_data+100);
@@ -573,21 +577,16 @@ void reply_trans(struct smb_request *req)
 		/* null-terminate the slack space */
 		memset(&state->data[state->total_data], 0, 100);
 
-		if (dscnt > state->total_data ||
-				dsoff+dscnt < dsoff) {
-			goto bad_param;
-		}
-
-		if (dsoff > av_size ||
-				dscnt > av_size ||
-				dsoff+dscnt > av_size) {
-			goto bad_param;
-		}
-
 		memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
 	}
 
 	if (state->total_param) {
+
+		if (trans_oob(state->total_param, 0, pscnt)
+		    || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
+			goto bad_param;
+		}
+
 		/* Can't use talloc here, the core routines do realloc on the
 		 * params and data. Out of paranoia, 100 bytes too many */
 		state->param = (char *)SMB_MALLOC(state->total_param+100);
@@ -603,17 +602,6 @@ void reply_trans(struct smb_request *req)
 		/* null-terminate the slack space */
 		memset(&state->param[state->total_param], 0, 100);
 
-		if (pscnt > state->total_param ||
-				psoff+pscnt < psoff) {
-			goto bad_param;
-		}
-
-		if (psoff > av_size ||
-				pscnt > av_size ||
-				psoff+pscnt > av_size) {
-			goto bad_param;
-		}
-
 		memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
 	}
 
@@ -696,7 +684,6 @@ void reply_transs(struct smb_request *req)
 	connection_struct *conn = req->conn;
 	unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
 	struct trans_state *state;
-	unsigned int av_size;
 
 	START_PROFILE(SMBtranss);
 
@@ -729,8 +716,6 @@ void reply_transs(struct smb_request *req)
 	if (SVAL(req->vwv+1, 0) < state->total_data)
 		state->total_data = SVAL(req->vwv+1, 0);
 
-	av_size = smb_len(req->inbuf);
-
 	pcnt = SVAL(req->vwv+2, 0);
 	poff = SVAL(req->vwv+3, 0);
 	pdisp = SVAL(req->vwv+4, 0);
@@ -747,41 +732,19 @@ void reply_transs(struct smb_request *req)
 		goto bad_param;
 
 	if (pcnt) {
-		if (pdisp > state->total_param ||
-				pcnt > state->total_param ||
-				pdisp+pcnt > state->total_param ||
-				pdisp+pcnt < pdisp) {
-			goto bad_param;
-		}
-
-		if (poff > av_size ||
-				pcnt > av_size ||
-				poff+pcnt > av_size ||
-				poff+pcnt < poff) {
+		if (trans_oob(state->total_param, pdisp, pcnt)
+		    || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
 			goto bad_param;
 		}
-
-		memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,
-		       pcnt);
+		memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
 	}
 
 	if (dcnt) {
-		if (ddisp > state->total_data ||
-				dcnt > state->total_data ||
-				ddisp+dcnt > state->total_data ||
-				ddisp+dcnt < ddisp) {
+		if (trans_oob(state->total_data, ddisp, dcnt)
+		    || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
 			goto bad_param;
 		}
-
-		if (doff > av_size ||
-				dcnt > av_size ||
-				doff+dcnt > av_size ||
-				doff+dcnt < doff) {
-			goto bad_param;
-		}
-
-		memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,
-		       dcnt);
+		memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
 	}
 
 	if ((state->received_param < state->total_param) ||
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index b516f02..fe2029e 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -2529,7 +2529,6 @@ void reply_nttrans(struct smb_request *req)
 	uint16 function_code;
 	NTSTATUS result;
 	struct trans_state *state;
-	uint32_t av_size;
 
 	START_PROFILE(SMBnttrans);
 
@@ -2539,7 +2538,6 @@ void reply_nttrans(struct smb_request *req)
 		return;
 	}
 
-	av_size = smb_len(req->inbuf);
 	pscnt = IVAL(req->vwv+9, 1);
 	psoff = IVAL(req->vwv+11, 1);
 	dscnt = IVAL(req->vwv+13, 1);
@@ -2616,6 +2614,12 @@ void reply_nttrans(struct smb_request *req)
 		goto bad_param;
 
 	if (state->total_data)  {
+
+		if (trans_oob(state->total_data, 0, dscnt)
+		    || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
+			goto bad_param;
+		}
+
 		/* Can't use talloc here, the core routines do realloc on the
 		 * params and data. */
 		if ((state->data = (char *)SMB_MALLOC(state->total_data)) == NULL) {
@@ -2627,21 +2631,16 @@ void reply_nttrans(struct smb_request *req)
 			return;
 		}
 
-		if (dscnt > state->total_data ||
-				dsoff+dscnt < dsoff) {
-			goto bad_param;
-		}
-
-		if (dsoff > av_size ||
-				dscnt > av_size ||
-				dsoff+dscnt > av_size) {
-			goto bad_param;
-		}
-
 		memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
 	}
 
 	if (state->total_param) {
+
+		if (trans_oob(state->total_param, 0, pscnt)
+		    || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
+			goto bad_param;
+		}
+
 		/* Can't use talloc here, the core routines do realloc on the
 		 * params and data. */
 		if ((state->param = (char *)SMB_MALLOC(state->total_param)) == NULL) {
@@ -2654,17 +2653,6 @@ void reply_nttrans(struct smb_request *req)
 			return;
 		}
 
-		if (pscnt > state->total_param ||
-				psoff+pscnt < psoff) {
-			goto bad_param;
-		}
-
-		if (psoff > av_size ||
-				pscnt > av_size ||
-				psoff+pscnt > av_size) {
-			goto bad_param;
-		}
-
 		memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
 	}
 
@@ -2741,8 +2729,6 @@ void reply_nttranss(struct smb_request *req)
 	connection_struct *conn = req->conn;
 	uint32_t pcnt,poff,dcnt,doff,pdisp,ddisp;
 	struct trans_state *state;
-	uint32_t av_size;
-	uint32_t size;
 
 	START_PROFILE(SMBnttranss);
 
@@ -2776,9 +2762,6 @@ void reply_nttranss(struct smb_request *req)
 		state->total_data = IVAL(req->vwv+3, 1);
 	}
 
-	size = smb_len(req->inbuf) + 4;
-	av_size = smb_len(req->inbuf);
-
 	pcnt = IVAL(req->vwv+5, 1);
 	poff = IVAL(req->vwv+7, 1);
 	pdisp = IVAL(req->vwv+9, 1);
@@ -2795,41 +2778,19 @@ void reply_nttranss(struct smb_request *req)
 		goto bad_param;
 
 	if (pcnt) {
-		if (pdisp > state->total_param ||
-				pcnt > state->total_param ||
-				pdisp+pcnt > state->total_param ||
-				pdisp+pcnt < pdisp) {
-			goto bad_param;
-		}
-
-		if (poff > av_size ||
-				pcnt > av_size ||
-				poff+pcnt > av_size ||
-				poff+pcnt < poff) {
+		if (trans_oob(state->total_param, pdisp, pcnt)
+		    || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
 			goto bad_param;
 		}
-
-		memcpy(state->param+pdisp, smb_base(req->inbuf)+poff,
-		       pcnt);
+		memcpy(state->param+pdisp, smb_base(req->inbuf)+poff,pcnt);
 	}
 
 	if (dcnt) {
-		if (ddisp > state->total_data ||
-				dcnt > state->total_data ||
-				ddisp+dcnt > state->total_data ||
-				ddisp+dcnt < ddisp) {
+		if (trans_oob(state->total_data, ddisp, dcnt)
+		    || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
 			goto bad_param;
 		}
-
-		if (doff > av_size ||
-				dcnt > av_size ||
-				doff+dcnt > av_size ||
-				doff+dcnt < doff) {
-			goto bad_param;
-		}
-
-		memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,
-		       dcnt);
+		memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
 	}
 
 	if ((state->received_param < state->total_param) ||
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 3a28bd4..cc8c611 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -7533,7 +7533,6 @@ void reply_trans2(struct smb_request *req)
 	unsigned int psoff;
 	unsigned int pscnt;
 	unsigned int tran_call;
-	unsigned int av_size;
 	struct trans_state *state;
 	NTSTATUS result;
 
@@ -7550,7 +7549,6 @@ void reply_trans2(struct smb_request *req)
 	psoff = SVAL(req->vwv+10, 0);
 	pscnt = SVAL(req->vwv+9, 0);
 	tran_call = SVAL(req->vwv+14, 0);
-	av_size = smb_len(req->inbuf);
 
 	result = allow_new_trans(conn->pending_trans, req->mid);
 	if (!NT_STATUS_IS_OK(result)) {
@@ -7632,6 +7630,12 @@ void reply_trans2(struct smb_request *req)
 		goto bad_param;
 
 	if (state->total_data) {
+
+		if (trans_oob(state->total_data, 0, dscnt)
+		    || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
+			goto bad_param;
+		}
+
 		/* Can't use talloc here, the core routines do realloc on the
 		 * params and data. */
 		state->data = (char *)SMB_MALLOC(state->total_data);
@@ -7644,21 +7648,16 @@ void reply_trans2(struct smb_request *req)
 			return;
 		}
 
-		if (dscnt > state->total_data ||
-				dsoff+dscnt < dsoff) {
-			goto bad_param;
-		}
-
-		if (dsoff > av_size ||
-				dscnt > av_size ||
-				dsoff+dscnt > av_size) {
-			goto bad_param;
-		}
-
 		memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
 	}
 
 	if (state->total_param) {
+
+		if (trans_oob(state->total_param, 0, pscnt)
+		    || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
+			goto bad_param;
+		}
+
 		/* Can't use talloc here, the core routines do realloc on the
 		 * params and data. */
 		state->param = (char *)SMB_MALLOC(state->total_param);
@@ -7672,17 +7671,6 @@ void reply_trans2(struct smb_request *req)
 			return;
 		} 
 
-		if (pscnt > state->total_param ||
-				psoff+pscnt < psoff) {
-			goto bad_param;
-		}
-
-		if (psoff > av_size ||
-				pscnt > av_size ||
-				psoff+pscnt > av_size) {
-			goto bad_param;
-		}
-
 		memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
 	}
 
@@ -7730,8 +7718,6 @@ void reply_transs2(struct smb_request *req)
 	connection_struct *conn = req->conn;
 	unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
 	struct trans_state *state;
-	unsigned int size;
-	unsigned int av_size;
 
 	START_PROFILE(SMBtranss2);
 
@@ -7743,9 +7729,6 @@ void reply_transs2(struct smb_request *req)
 		return;
 	}
 
-	size = smb_len(req->inbuf)+4;
-	av_size = smb_len(req->inbuf);
-
 	for (state = conn->pending_trans; state != NULL;
 	     state = state->next) {
 		if (state->mid == req->mid) {
@@ -7783,41 +7766,19 @@ void reply_transs2(struct smb_request *req)
 		goto bad_param;
 
 	if (pcnt) {
-		if (pdisp > state->total_param ||
-				pcnt > state->total_param ||
-				pdisp+pcnt > state->total_param ||
-				pdisp+pcnt < pdisp) {
-			goto bad_param;
-		}
-
-		if (poff > av_size ||
-				pcnt > av_size ||
-				poff+pcnt > av_size ||
-				poff+pcnt < poff) {
+		if (trans_oob(state->total_param, pdisp, pcnt)
+		    || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
 			goto bad_param;
 		}
-
-		memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,
-		       pcnt);
+		memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
 	}
 
 	if (dcnt) {
-		if (ddisp > state->total_data ||
-				dcnt > state->total_data ||
-				ddisp+dcnt > state->total_data ||
-				ddisp+dcnt < ddisp) {
+		if (trans_oob(state->total_data, ddisp, dcnt)
+		    || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
 			goto bad_param;
 		}
-
-		if (doff > av_size ||
-				dcnt > av_size ||
-				doff+dcnt > av_size ||
-				doff+dcnt < doff) {
-			goto bad_param;
-		}
-
-		memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,
-		       dcnt);      
+		memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
 	}
 
 	if ((state->received_param < state->total_param) ||


-- 
Samba Shared Repository


More information about the samba-cvs mailing list