diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/ipc.c | 20 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 16 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 16 |
3 files changed, 38 insertions, 14 deletions
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 39072f9b91..9bdd02b059 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -388,7 +388,8 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int } if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt)) goto bad_param; - if (smb_base(inbuf)+dsoff+dscnt > inbuf + size) + if ((smb_base(inbuf)+dsoff+dscnt > inbuf + size) || + (smb_base(inbuf)+dsoff+dscnt < smb_base(inbuf))) goto bad_param; memcpy(data,smb_base(inbuf)+dsoff,dscnt); @@ -402,8 +403,9 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int return(ERROR_DOS(ERRDOS,ERRnomem)); } if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt)) - goto bad_param; - if (smb_base(inbuf)+psoff+pscnt > inbuf + size) + goto bad_param; + if ((smb_base(inbuf)+psoff+pscnt > inbuf + size) || + (smb_base(inbuf)+psoff+pscnt < smb_base(inbuf))); goto bad_param; memcpy(params,smb_base(inbuf)+psoff,pscnt); @@ -487,8 +489,11 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int if (pdisp+pcnt >= tpscnt) goto bad_param; if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt)) - goto bad_param; - if (smb_base(inbuf) + poff + pcnt >= inbuf + bufsize) + goto bad_param; + if (pdisp > tpscnt) + goto bad_param; + if ((smb_base(inbuf) + poff + pcnt >= inbuf + bufsize) || + (smb_base(inbuf) + poff + pcnt < smb_base(inbuf))) goto bad_param; if (params + pdisp < params) goto bad_param; @@ -501,7 +506,10 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int goto bad_param; if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt)) goto bad_param; - if (smb_base(inbuf) + doff + dcnt >= inbuf + bufsize) + if (ddisp > tdscnt) + goto bad_param; + if ((smb_base(inbuf) + doff + dcnt >= inbuf + bufsize) || + (smb_base(inbuf) + doff + dcnt < smb_base(inbuf))) goto bad_param; if (data + ddisp < data) goto bad_param; diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index b4e7a70088..19af61f190 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -2463,7 +2463,8 @@ due to being in oplock break state.\n", (unsigned int)function_code )); if ((parameter_offset + parameter_count < parameter_offset) || (parameter_offset + parameter_count < parameter_count)) goto bad_param; - if (smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length) + if ((smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length)|| + (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf))) goto bad_param; memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count); @@ -2473,7 +2474,8 @@ due to being in oplock break state.\n", (unsigned int)function_code )); DEBUG(10,("reply_nttrans: data_count = %d\n",data_count)); if ((data_offset + data_count < data_offset) || (data_offset + data_count < data_count)) goto bad_param; - if (smb_base(inbuf) + data_offset + data_count > inbuf + length) + if ((smb_base(inbuf) + data_offset + data_count > inbuf + length) || + (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf))) goto bad_param; memcpy( data, smb_base(inbuf) + data_offset, data_count); @@ -2534,7 +2536,10 @@ due to being in oplock break state.\n", (unsigned int)function_code )); if ((parameter_displacement + parameter_count < parameter_displacement) || (parameter_displacement + parameter_count < parameter_count)) goto bad_param; - if (smb_base(inbuf) + parameter_offset + parameter_count >= inbuf + bufsize) + if (parameter_displacement > total_parameter_count) + goto bad_param; + if ((smb_base(inbuf) + parameter_offset + parameter_count >= inbuf + bufsize) || + (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf))) goto bad_param; if (parameter_displacement + params < params) goto bad_param; @@ -2548,7 +2553,10 @@ due to being in oplock break state.\n", (unsigned int)function_code )); if ((data_displacement + data_count < data_displacement) || (data_displacement + data_count < data_count)) goto bad_param; - if (smb_base(inbuf) + data_offset + data_count >= inbuf + bufsize) + if (data_displacement > total_data_count) + goto bad_param; + if ((smb_base(inbuf) + data_offset + data_count >= inbuf + bufsize) || + (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf))) goto bad_param; if (data_displacement + data < data) goto bad_param; diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 3d53387c9f..0f02403184 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3497,7 +3497,8 @@ int reply_trans2(connection_struct *conn, unsigned int psoff = SVAL(inbuf, smb_psoff); if ((psoff + num_params < psoff) || (psoff + num_params < num_params)) goto bad_param; - if (smb_base(inbuf) + psoff + num_params > inbuf + length) + if ((smb_base(inbuf) + psoff + num_params > inbuf + length) || + (smb_base(inbuf) + psoff + num_params < smb_base(inbuf))) goto bad_param; memcpy( params, smb_base(inbuf) + psoff, num_params); } @@ -3505,7 +3506,8 @@ int reply_trans2(connection_struct *conn, unsigned int dsoff = SVAL(inbuf, smb_dsoff); if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data)) goto bad_param; - if (smb_base(inbuf) + dsoff + num_data > inbuf + length) + if ((smb_base(inbuf) + dsoff + num_data > inbuf + length) || + (smb_base(inbuf) + dsoff + num_data < smb_base(inbuf))) goto bad_param; memcpy( data, smb_base(inbuf) + dsoff, num_data); } @@ -3566,7 +3568,10 @@ int reply_trans2(connection_struct *conn, if ((param_disp + num_params < param_disp) || (param_disp + num_params < num_params)) goto bad_param; - if (smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) + if (param_disp > total_params) + goto bad_param; + if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) || + (smb_base(inbuf) + param_off + num_params < smb_base(inbuf))) goto bad_param; if (params + param_disp < params) goto bad_param; @@ -3579,7 +3584,10 @@ int reply_trans2(connection_struct *conn, if ((data_disp + num_data < data_disp) || (data_disp + num_data < num_data)) goto bad_param; - if (smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) + if (data_disp > total_data) + goto bad_param; + if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) || + (smb_base(inbuf) + data_off + num_data < smb_base(inbuf))) goto bad_param; if (data + data_disp < data) goto bad_param; |