diff options
-rw-r--r-- | source3/include/client.h | 2 | ||||
-rw-r--r-- | source3/libsmb/clifile.c | 12 | ||||
-rw-r--r-- | source3/libsmb/clilist.c | 2 | ||||
-rw-r--r-- | source3/libsmb/clirap.c | 38 | ||||
-rw-r--r-- | source3/libsmb/clitrans.c | 233 |
5 files changed, 191 insertions, 96 deletions
diff --git a/source3/include/client.h b/source3/include/client.h index 2e6b9337e4..a3efda4918 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -114,7 +114,7 @@ struct cli_state { int max_mux; char *outbuf; char *inbuf; - int bufsize; + unsigned int bufsize; int initialised; int win95; uint32 capabilities; diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 31d7ea5911..f61787abde 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -29,8 +29,8 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, const char *fname_dst, BOOL hard_link) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; char param[sizeof(pstring)+6]; pstring data; @@ -123,8 +123,8 @@ BOOL cli_unix_hardlink(struct cli_state *cli, const char *fname_src, const char static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32 mode, uint32 uid, uint32 gid) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; char param[sizeof(pstring)+6]; char data[100]; @@ -335,8 +335,8 @@ BOOL cli_rmdir(struct cli_state *cli, const char *dname) int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) { - int data_len = 1; - int param_len = 6; + unsigned int data_len = 1; + unsigned int param_len = 6; uint16 setup = TRANSACT2_SETFILEINFO; pstring param; unsigned char data; diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 89ab5d6414..3884e4da82 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -154,7 +154,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; - int param_len, data_len; + unsigned int param_len, data_len; uint16 setup; pstring param; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index a1845b2e16..b38e7d5c23 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -41,8 +41,8 @@ BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name, data, data_count, max_data_count); return (cli_receive_trans(cli, SMBtrans, - rparam, (int *)rparam_count, - rdata, (int *)rdata_count)); + rparam, (unsigned int *)rparam_count, + rdata, (unsigned int *)rdata_count)); } /**************************************************************************** @@ -51,8 +51,8 @@ call a remote api BOOL cli_api(struct cli_state *cli, char *param, int prcnt, int mprcnt, char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt) + char **rparam, unsigned int *rprcnt, + char **rdata, unsigned int *rdrcnt) { cli_send_trans(cli,SMBtrans, PIPE_LANMAN, /* Name */ @@ -286,8 +286,8 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char char *p = param; unsigned char old_pw_hash[16]; unsigned char new_pw_hash[16]; - int data_len; - int param_len = 0; + unsigned int data_len; + unsigned int param_len = 0; char *rparam = NULL; char *rdata = NULL; int rprcnt, rdrcnt; @@ -368,9 +368,9 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, size_t *size, uint16 *mode) { - int data_len = 0; - int param_len = 0; - int rparam_len, rdata_len; + unsigned int data_len = 0; + unsigned int param_len = 0; + unsigned int rparam_len, rdata_len; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -449,8 +449,8 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, time_t *w_time, size_t *size, uint16 *mode, SMB_INO_T *ino) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -518,8 +518,8 @@ send a qfileinfo QUERY_FILE_NAME_INFO call BOOL cli_qfilename(struct cli_state *cli, int fnum, pstring name) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -563,8 +563,8 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, SMB_INO_T *ino) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -631,8 +631,8 @@ send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -677,8 +677,8 @@ send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call ****************************************************************************/ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 3d862a1796..7e3357a8cc 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -24,18 +24,19 @@ /**************************************************************************** - send a SMB trans or trans2 request - ****************************************************************************/ + Send a SMB trans or trans2 request. +****************************************************************************/ + BOOL cli_send_trans(struct cli_state *cli, int trans, const char *pipe_name, int fid, int flags, - uint16 *setup, int lsetup, int msetup, - char *param, int lparam, int mparam, - char *data, int ldata, int mdata) + uint16 *setup, unsigned int lsetup, unsigned int msetup, + char *param, unsigned int lparam, unsigned int mparam, + char *data, unsigned int ldata, unsigned int mdata) { int i; - int this_ldata,this_lparam; - int tot_data=0,tot_param=0; + unsigned int this_ldata,this_lparam; + unsigned int tot_data=0,tot_param=0; char *outdata,*outparam; char *p; int pipe_name_len=0; @@ -83,14 +84,13 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!cli_receive_smb(cli) || - cli_is_error(cli)) { + if (!cli_receive_smb(cli) || cli_is_error(cli)) return(False); - } tot_data = this_ldata; tot_param = this_lparam; @@ -123,7 +123,8 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; tot_data += this_ldata; tot_param += this_lparam; @@ -133,17 +134,17 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, return(True); } - /**************************************************************************** - receive a SMB trans or trans2 response allocating the necessary memory - ****************************************************************************/ + Receive a SMB trans or trans2 response allocating the necessary memory. +****************************************************************************/ + BOOL cli_receive_trans(struct cli_state *cli,int trans, - char **param, int *param_len, - char **data, int *data_len) + char **param, unsigned int *param_len, + char **data, unsigned int *data_len) { - int total_data=0; - int total_param=0; - int this_data,this_param; + unsigned int total_data=0; + unsigned int total_param=0; + unsigned int this_data,this_param; NTSTATUS status; char *tdata; char *tparam; @@ -170,9 +171,8 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, */ status = cli_nt_error(cli); - if (NT_STATUS_IS_ERR(status)) { + if (NT_STATUS_IS_ERR(status)) return False; - } /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_tdrcnt); @@ -199,7 +199,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, *param = tparam; } - while (1) { + for (;;) { this_data = SVAL(cli->inbuf,smb_drcnt); this_param = SVAL(cli->inbuf,smb_prcnt); @@ -209,21 +209,59 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, return False; } - if (this_data) - memcpy(*data + SVAL(cli->inbuf,smb_drdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_droff), - this_data); - if (this_param) - memcpy(*param + SVAL(cli->inbuf,smb_prdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_proff), - this_param); + if (this_data + *data_len < this_data || + this_data + *data_len < *data_len || + this_param + *param_len < this_param || + this_param + *param_len < *param_len) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + + if (this_data) { + unsigned int data_offset_out = SVAL(cli->inbuf,smb_drdisp); + unsigned int data_offset_in = SVAL(cli->inbuf,smb_droff); + + if (data_offset_out > total_data || + data_offset_out + this_data > total_data || + data_offset_out + this_data < data_offset_out || + data_offset_out + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + if (data_offset_in > cli->bufsize || + data_offset_in + this_data > cli->bufsize || + data_offset_in + this_data < data_offset_in || + data_offset_in + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + + memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); + } + if (this_param) { + unsigned int param_offset_out = SVAL(cli->inbuf,smb_prdisp); + unsigned int param_offset_in = SVAL(cli->inbuf,smb_proff); + + if (param_offset_out > total_param || + param_offset_out + this_param > total_param || + param_offset_out + this_param < param_offset_out || + param_offset_out + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_trans\n")); + return False; + } + if (param_offset_in > cli->bufsize || + param_offset_in + this_param > cli->bufsize || + param_offset_in + this_param < param_offset_in || + param_offset_in + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_trans\n")); + return False; + } + + memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); + } *data_len += this_data; *param_len += this_param; - /* parse out the total lengths again - they can shrink! */ - total_data = SVAL(cli->inbuf,smb_tdrcnt); - total_param = SVAL(cli->inbuf,smb_tprcnt); - if (total_data <= *data_len && total_param <= *param_len) break; @@ -242,27 +280,35 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { return(False); } + + /* parse out the total lengths again - they can shrink! */ + if (SVAL(cli->inbuf,smb_tdrcnt) < total_data) + total_data = SVAL(cli->inbuf,smb_tdrcnt); + if (SVAL(cli->inbuf,smb_tprcnt) < total_param) + total_param = SVAL(cli->inbuf,smb_tprcnt); + + if (total_data <= *data_len && total_param <= *param_len) + break; + } return(True); } - - - /**************************************************************************** - send a SMB nttrans request - ****************************************************************************/ + Send a SMB nttrans request. +****************************************************************************/ + BOOL cli_send_nt_trans(struct cli_state *cli, int function, int flags, - uint16 *setup, int lsetup, int msetup, - char *param, int lparam, int mparam, - char *data, int ldata, int mdata) + uint16 *setup, unsigned int lsetup, unsigned int msetup, + char *param, unsigned int lparam, unsigned int mparam, + char *data, unsigned int ldata, unsigned int mdata) { - int i; - int this_ldata,this_lparam; - int tot_data=0,tot_param=0; + unsigned int i; + unsigned int this_ldata,this_lparam; + unsigned int tot_data=0,tot_param=0; char *outdata,*outparam; this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ @@ -301,14 +347,13 @@ BOOL cli_send_nt_trans(struct cli_state *cli, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!cli_receive_smb(cli) || - cli_is_error(cli)) { + if (!cli_receive_smb(cli) || cli_is_error(cli)) return(False); - } tot_data = this_ldata; tot_param = this_lparam; @@ -340,7 +385,8 @@ BOOL cli_send_nt_trans(struct cli_state *cli, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; tot_data += this_ldata; tot_param += this_lparam; @@ -355,13 +401,14 @@ BOOL cli_send_nt_trans(struct cli_state *cli, /**************************************************************************** receive a SMB nttrans response allocating the necessary memory ****************************************************************************/ + BOOL cli_receive_nt_trans(struct cli_state *cli, - char **param, int *param_len, - char **data, int *data_len) + char **param, unsigned int *param_len, + char **data, unsigned int *data_len) { - int total_data=0; - int total_param=0; - int this_data,this_param; + unsigned int total_data=0; + unsigned int total_param=0; + unsigned int this_data,this_param; uint8 eclass; uint32 ecode; char *tdata; @@ -423,25 +470,65 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (this_data + *data_len > total_data || this_param + *param_len > total_param) { - DEBUG(1,("Data overflow in cli_receive_trans\n")); + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + return False; + } + + if (this_data + *data_len < this_data || + this_data + *data_len < *data_len || + this_param + *param_len < this_param || + this_param + *param_len < *param_len) { + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); return False; } - if (this_data) - memcpy(*data + SVAL(cli->inbuf,smb_ntr_DataDisplacement), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_ntr_DataOffset), - this_data); - if (this_param) - memcpy(*param + SVAL(cli->inbuf,smb_ntr_ParameterDisplacement), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_ntr_ParameterOffset), - this_param); + if (this_data) { + unsigned int data_offset_out = SVAL(cli->inbuf,smb_ntr_DataDisplacement); + unsigned int data_offset_in = SVAL(cli->inbuf,smb_ntr_DataOffset); + + if (data_offset_out > total_data || + data_offset_out + this_data > total_data || + data_offset_out + this_data < data_offset_out || + data_offset_out + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + return False; + } + if (data_offset_in > cli->bufsize || + data_offset_in + this_data > cli->bufsize || + data_offset_in + this_data < data_offset_in || + data_offset_in + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + return False; + } + + memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); + } + + if (this_param) { + unsigned int param_offset_out = SVAL(cli->inbuf,smb_ntr_ParameterDisplacement); + unsigned int param_offset_in = SVAL(cli->inbuf,smb_ntr_ParameterOffset); + + if (param_offset_out > total_param || + param_offset_out + this_param > total_param || + param_offset_out + this_param < param_offset_out || + param_offset_out + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); + return False; + } + if (param_offset_in > cli->bufsize || + param_offset_in + this_param > cli->bufsize || + param_offset_in + this_param < param_offset_in || + param_offset_in + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); + return False; + } + + memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); + } + *data_len += this_data; *param_len += this_param; - /* parse out the total lengths again - they can shrink! */ - total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); - total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); - if (total_data <= *data_len && total_param <= *param_len) break; @@ -462,6 +549,14 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, !(eclass == ERRDOS && ecode == ERRmoredata)) return(False); } + /* parse out the total lengths again - they can shrink! */ + if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data) + total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); + if (SVAL(cli->inbuf,smb_ntr_TotalParameterCount) < total_param) + total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); + + if (total_data <= *data_len && total_param <= *param_len) + break; } return(True); |