OpenPKG CVS Repository
http://cvs.openpkg.org/
____________________________________________________________________________
Server: cvs.openpkg.org Name: Thomas Lotterer
Root: /e/openpkg/cvs Email: [EMAIL PROTECTED]
Module: openpkg-src Date: 17-Mar-2003 20:32:18
Branch: OPENPKG_1_2_SOLID Handle: 2003031719321700
Added files: (Branch: OPENPKG_1_2_SOLID)
openpkg-src/samba samba.patch
Modified files: (Branch: OPENPKG_1_2_SOLID)
openpkg-src/samba samba.spec
Log:
SA-2003.021-samba; CAN-2003-0085, CAN-2003-0086
Summary:
Revision Changes Path
1.1.8.1 +1419 -0 openpkg-src/samba/samba.patch
1.35.2.1.2.2+3 -1 openpkg-src/samba/samba.spec
____________________________________________________________________________
patch -p0 <<'@@ .'
Index: openpkg-src/samba/samba.patch
============================================================================
$ cvs diff -u -r0 -r1.1.8.1 samba.patch
--- /dev/null 2003-03-17 20:32:17.000000000 +0100
+++ samba.patch 2003-03-17 20:32:18.000000000 +0100
@@ -0,0 +1,1419 @@
+
+IMPORTANT: Security bugfix for Samba
+------------------------------------
+
+Summary
+-------
+
+The SuSE security audit team, in particular Sebastian Krahmer
+<[EMAIL PROTECTED]>, has found a flaw in the Samba main smbd code which
+could allow an external attacker to remotely and anonymously gain
+Super User (root) privileges on a server running a Samba server.
+
+This flaw exists in previous versions of Samba from 2.0.x to 2.2.7a
+inclusive. This is a serious problem and all sites should either
+upgrade to Samba 2.2.8 immediately or prohibit access to TCP ports 139
+and 445. Advice created by Andrew Tridgell, the leader of the Samba Team,
+on how to protect an unpatched Samba server is given at the end of this
+section.
+
+The SMB/CIFS protocol implemented by Samba is vulnerable to many
+attacks, even without specific security holes. The TCP ports 139 and
+the new port 445 (used by Win2k and the Samba 3.0 alpha code in
+particular) should never be exposed to untrusted networks.
+
+Description
+-----------
+
+A buffer overrun condition exists in the SMB/CIFS packet fragment
+re-assembly code in smbd which would allow an attacker to cause smbd
+to overwrite arbitrary areas of memory in its own process address
+space. This could allow a skilled attacker to inject binary specific
+exploit code into smbd.
+
+This version of Samba adds explicit overrun and overflow checks on
+fragment re-assembly of SMB/CIFS packets to ensure that only valid
+re-assembly is performed by smbd.
+
+In addition, the same checks have been added to the re-assembly
+functions in the client code, making it safe for use in other
+services.
+
+Credit
+------
+
+This security flaw was discovered and reported to the Samba Team by
+Sebastian Krahmer <[EMAIL PROTECTED]> of the SuSE Security Audit Team.
+The fix was prepared by Jeremy Allison and reviewed by engineers from
+the Samba Team, SuSE, HP, SGI, Apple, and the Linux vendor engineers
+on the Linux Vendor security mailing list.
+
+The Samba Team would like to thank SuSE and Sebastian Krahmer for
+their excellent auditing work and for drawing attention to this flaw.
+
+Patch Availability
+-----------------
+
+As this is a security issue, patches for this flaw specific to earlier
+versions of Samba will be posted on the [EMAIL PROTECTED]
+mailing list as requested.
+
+The patch below was extracted for OpenPKG from the Samba 2.2.7a to 2.2.8
+differences regarding the following files:
+ source/include/client.h
+ source/include/proto.h changes reduced to functions affected by this patch
+ source/client/client.c
+ source/client/clitar.c
+ source/libsmb/clifile.c
+ source/libsmb/clilist.c
+ source/libsmb/clirap.c
+ source/libsmb/clitrans.c
+ source/smbd/ipc.c
+ source/smbd/trans2.c removed "6) Fix delete on close semantics to match
W2K")
+ source/smbd/nttrans.c whitespace differences were removed
+ source/smbd/vfs-wrap.c
+
+--- samba-2.2.7a/source/include/client.h Mon Mar 17 11:00:11 2003
++++ samba-2.2.8/source/include/client.h Fri Mar 14 22:34:47 2003
+@@ -103,7 +103,7 @@
+ int max_mux;
+ char *outbuf;
+ char *inbuf;
+- int bufsize;
++ unsigned int bufsize;
+ int initialised;
+ int win95;
+ uint32 capabilities;
+--- samba-2.2.7a/source/include/proto.h Mon Mar 17 11:00:16 2003
++++ samba-2.2.8-patchedonly/source/include/proto.h Fri Mar 14 22:34:47 2003
+@@ -301,7 +301,7 @@
+ SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type
lock_type);
+ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset,
SMB_BIG_UINT len);
+ BOOL cli_getattrE(struct cli_state *cli, int fd,
+- uint16 *attr, size_t *size,
++ uint16 *attr, SMB_BIG_UINT *size,
+ time_t *c_time, time_t *a_time, time_t *m_time);
+ BOOL cli_getatr(struct cli_state *cli, const char *fname,
+ uint16 *attr, size_t *size, time_t *t);
+@@ -425,7 +425,7 @@
+
+ /* The following definitions come from libsmb/clirap.c */
+
+-BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name,
++BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name,
+ uint16 *setup, uint32 setup_count, uint32 max_setup_count,
+ char *params, uint32 param_count, uint32 max_param_count,
+ char *data, uint32 data_count, uint32 max_data_count,
+@@ -434,8 +434,8 @@
+ 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);
+ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation);
+ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32,
const char *, void *), void *state);
+ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
+@@ -653,21 +653,21 @@
+ 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);
+ 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);
+ 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);
+ 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);
+
+ /* The following definitions come from libsmb/credentials.c */
+
+--- samba-2.2.7a/source/libsmb/clifile.c Mon Mar 17 10:53:21 2003
++++ samba-2.2.8/source/libsmb/clifile.c Fri Mar 14 22:34:48 2003
+@@ -30,8 +30,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;
+@@ -124,8 +124,8 @@
+
+ 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];
+@@ -336,8 +336,8 @@
+
+ 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;
+@@ -802,11 +802,11 @@
+ }
+
+ /****************************************************************************
+- Do a SMBgetattrE call.
++ Do a SMBgetattrE call. The size is 32 bits.
+ ****************************************************************************/
+
+ BOOL cli_getattrE(struct cli_state *cli, int fd,
+- uint16 *attr, size_t *size,
++ uint16 *attr, SMB_BIG_UINT *size,
+ time_t *c_time, time_t *a_time, time_t *m_time)
+ {
+ memset(cli->outbuf,'\0',smb_size);
+--- samba-2.2.7a/source/libsmb/clilist.c Mon Mar 17 11:00:18 2003
++++ samba-2.2.8/source/libsmb/clilist.c Fri Mar 14 22:34:48 2003
+@@ -152,7 +152,7 @@
+ 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;
+
+--- samba-2.2.7a/source/libsmb/clirap.c Mon Mar 17 10:53:23 2003
++++ samba-2.2.8/source/libsmb/clirap.c Fri Mar 14 22:34:48 2003
+@@ -27,7 +27,7 @@
+ /****************************************************************************
+ Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
+ ****************************************************************************/
+-BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name,
++BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name,
+ uint16 *setup, uint32 setup_count, uint32 max_setup_count,
+ char *params, uint32 param_count, uint32 max_param_count,
+ char *data, uint32 data_count, uint32 max_data_count,
+@@ -42,8 +42,8 @@
+ 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));
+ }
+
+ /****************************************************************************
+@@ -52,8 +52,8 @@
+ 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 */
+@@ -176,7 +176,7 @@
+ char *sname = p;
+ int type = SVAL(p,14);
+ int comment_offset = IVAL(p,16) & 0xFFFF;
+- char *cmnt =
comment_offset?(rdata+comment_offset-converter):"";
++ const char *cmnt =
comment_offset?(rdata+comment_offset-converter):"";
+ pstring s1, s2;
+
+ pstrcpy(s1, dos_to_unix_static(sname));
+@@ -254,7 +254,7 @@
+ for (i = 0;i < count;i++, p += 26) {
+ char *sname = p;
+ int comment_offset = (IVAL(p,22) & 0xFFFF)-converter;
+- char *cmnt = comment_offset?(rdata+comment_offset):"";
++ const char *cmnt =
comment_offset?(rdata+comment_offset):"";
+ pstring s1, s2;
+
+ if (comment_offset < 0 || comment_offset > rdrcnt)
continue;
+@@ -289,8 +289,8 @@
+ fstring upper_case_new_pw;
+ 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;
+@@ -372,8 +372,8 @@
+ 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;
++ unsigned int data_len = 0;
++ unsigned int param_len = 0;
+ uint16 setup = TRANSACT2_QPATHINFO;
+ pstring param;
+ char *rparam=NULL, *rdata=NULL;
+@@ -451,8 +451,8 @@
+ 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;
+@@ -522,8 +522,8 @@
+ 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;
+@@ -590,8 +590,8 @@
+ ****************************************************************************/
+ 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;
+@@ -635,8 +635,8 @@
+
+ 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;
+--- samba-2.2.7a/source/client/client.c Mon Mar 17 14:49:44 2003
++++ samba-2.2.8/source/client/client.c Mon Mar 17 14:50:19 2003
+@@ -644,8 +644,9 @@
+ struct timeval tp_start;
+ int read_size = io_bufsize;
+ uint16 attr;
+- size_t size;
+- off_t nread = 0;
++ size_t old_size = 0;
++ SMB_BIG_UINT size = 0;
++ SMB_BIG_UINT nread = 0;
+
+ GetTimeOfDay(&tp_start);
+
+@@ -671,9 +672,8 @@
+ return;
+ }
+
+-
+ if (!cli_qfileinfo(cli, fnum,
+- &attr, &size, NULL, NULL, NULL, NULL, NULL) &&
++ &attr, &old_size, NULL, NULL, NULL, NULL, NULL) &&
+ !cli_getattrE(cli, fnum,
+ &attr, &size, NULL, NULL, NULL)) {
+ DEBUG(0,("getattrib: %s\n",cli_errstr(cli)));
+--- samba-2.2.7a/source/client/clitar.c Mon Mar 17 14:53:27 2003
++++ samba-2.2.8/source/client/clitar.c Mon Mar 17 14:53:58 2003
+@@ -45,7 +45,7 @@
+
+ struct file_info_struct
+ {
+- size_t size;
++ SMB_BIG_UINT size;
+ uint16 mode;
+ int uid;
+ int gid;
+@@ -621,7 +621,7 @@
+ static void do_atar(char *rname,char *lname,file_info *finfo1)
+ {
+ int fnum;
+- uint32 nread=0;
++ SMB_BIG_UINT nread=0;
+ char ftype;
+ file_info2 finfo;
+ BOOL close_done = False;
+@@ -643,6 +643,7 @@
+ finfo.mtime = finfo1 -> mtime;
+ finfo.atime = finfo1 -> atime;
+ finfo.ctime = finfo1 -> ctime;
++ finfo.name = finfo1 -> name;
+ }
+ else {
+ finfo.size = def_finfo.size;
+@@ -652,13 +653,14 @@
+ finfo.mtime = def_finfo.mtime;
+ finfo.atime = def_finfo.atime;
+ finfo.ctime = def_finfo.ctime;
++ finfo.name = def_finfo.name;
+ }
+
+ if (dry_run)
+ {
+- DEBUG(3,("skipping file %s of size %d bytes\n",
++ DEBUG(3,("skipping file %s of size %12.0f bytes\n",
+ finfo.name,
+- (int)finfo.size));
++ (double)finfo.size));
+ shallitime=0;
+ ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
+ ntarf++;
+@@ -709,9 +711,9 @@
+ }
+ else
+ {
+- DEBUG(3,("getting file %s of size %d bytes as a tar file %s",
++ DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s",
+ finfo.name,
+- (int)finfo.size,
++ (double)finfo.size,
+ lname));
+
+ /* write a tar header, don't bother with mode - just set to 100644 */
+@@ -719,7 +721,7 @@
+
+ while (nread < finfo.size && !close_done) {
+
+- DEBUG(3,("nread=%d\n",nread));
++ DEBUG(3,("nread=%.0f\n",(double)nread));
+
+ datalen = cli_read(cli, fnum, data, nread, read_size);
+
+@@ -736,7 +738,7 @@
+
+ if (nread > finfo.size) {
+ datalen -= nread - finfo.size;
+- DEBUG(0,("File size change - truncating %s to %d bytes\n",
finfo.name, (int)finfo.size));
++ DEBUG(0,("File size change - truncating %s to %.0f bytes\n",
finfo.name, (double)finfo.size));
+ }
+
+ /* add received bits of file to buffer - dotarbuf will
+@@ -756,7 +758,7 @@
+
+ /* pad tar file with zero's if we couldn't get entire file */
+ if (nread < finfo.size) {
+- DEBUG(0, ("Didn't get entire file. size=%d, nread=%d\n",
(int)finfo.size, (int)nread));
++ DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%.0f\n",
(double)finfo.size, (double)nread));
+ if (padit(data, sizeof(data), finfo.size - nread))
+ DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
+ }
+@@ -789,8 +791,8 @@
+
+ if (tar_noisy)
+ {
+- DEBUG(0, ("%10d (%7.1f kb/s) %s\n",
+- (int)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
++ DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n",
++ (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
+ finfo.name));
+ }
+
+--- samba-2.2.7a/source/libsmb/clitrans.c Mon Mar 17 10:53:24 2003
++++ samba-2.2.8/source/libsmb/clitrans.c Fri Mar 14 22:34:48 2003
+@@ -25,18 +25,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;
+@@ -84,14 +85,13 @@
+ 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;
+@@ -124,7 +124,8 @@
+ 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;
+@@ -134,17 +135,17 @@
+ 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;
+@@ -171,9 +172,8 @@
+ */
+ 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);
+@@ -210,21 +210,59 @@
+ 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;
+
+@@ -243,27 +281,35 @@
+ 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 */
+@@ -302,14 +348,13 @@
+ 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;
+@@ -341,7 +386,8 @@
+ 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;
+@@ -356,13 +402,14 @@
+ /****************************************************************************
+ 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;
+@@ -424,25 +471,65 @@
+
+ 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)
+- 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 + *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) {
++ 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;
+
+@@ -463,6 +550,14 @@
+ !(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);
+--- samba-2.2.7a/source/smbd/ipc.c Thu Mar 13 23:16:38 2003
++++ samba-2.2.8/source/smbd/ipc.c Fri Mar 14 22:34:49 2003
+@@ -368,52 +368,69 @@
+ uint16 *setup=NULL;
+ int outsize = 0;
+ uint16 vuid = SVAL(inbuf,smb_uid);
+- int tpscnt = SVAL(inbuf,smb_vwv0);
+- int tdscnt = SVAL(inbuf,smb_vwv1);
+- int mprcnt = SVAL(inbuf,smb_vwv2);
+- int mdrcnt = SVAL(inbuf,smb_vwv3);
+- int msrcnt = CVAL(inbuf,smb_vwv4);
++ unsigned int tpscnt = SVAL(inbuf,smb_vwv0);
++ unsigned int tdscnt = SVAL(inbuf,smb_vwv1);
++ unsigned int mprcnt = SVAL(inbuf,smb_vwv2);
++ unsigned int mdrcnt = SVAL(inbuf,smb_vwv3);
++ unsigned int msrcnt = CVAL(inbuf,smb_vwv4);
+ BOOL close_on_completion = BITSETW(inbuf+smb_vwv5,0);
+ BOOL one_way = BITSETW(inbuf+smb_vwv5,1);
+- int pscnt = SVAL(inbuf,smb_vwv9);
+- int psoff = SVAL(inbuf,smb_vwv10);
+- int dscnt = SVAL(inbuf,smb_vwv11);
+- int dsoff = SVAL(inbuf,smb_vwv12);
+- int suwcnt = CVAL(inbuf,smb_vwv13);
++ unsigned int pscnt = SVAL(inbuf,smb_vwv9);
++ unsigned int psoff = SVAL(inbuf,smb_vwv10);
++ unsigned int dscnt = SVAL(inbuf,smb_vwv11);
++ unsigned int dsoff = SVAL(inbuf,smb_vwv12);
++ unsigned int suwcnt = CVAL(inbuf,smb_vwv13);
+ START_PROFILE(SMBtrans);
+
+ memset(name, '\0',sizeof(name));
+ fstrcpy(name,smb_buf(inbuf));
+
+- if (dscnt > tdscnt || pscnt > tpscnt) {
+- exit_server("invalid trans parameters\n");
+- }
++ if (dscnt > tdscnt || pscnt > tpscnt)
++ goto bad_param;
+
+ if (tdscnt) {
+ if((data = (char *)malloc(tdscnt)) == NULL) {
+- DEBUG(0,("reply_trans: data malloc fail for %d bytes !\n",
tdscnt));
++ DEBUG(0,("reply_trans: data malloc fail for %u bytes !\n",
tdscnt));
+ END_PROFILE(SMBtrans);
+ return(ERROR_DOS(ERRDOS,ERRnomem));
+ }
++ if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
++ goto bad_param;
++ if (smb_base(inbuf)+dsoff+dscnt > inbuf + size)
++ goto bad_param;
++
+ memcpy(data,smb_base(inbuf)+dsoff,dscnt);
+ }
+
+ if (tpscnt) {
+ if((params = (char *)malloc(tpscnt)) == NULL) {
+- DEBUG(0,("reply_trans: param malloc fail for %d bytes !\n",
tpscnt));
++ DEBUG(0,("reply_trans: param malloc fail for %u bytes !\n",
tpscnt));
++ SAFE_FREE(data);
+ END_PROFILE(SMBtrans);
+ 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;
++
+ memcpy(params,smb_base(inbuf)+psoff,pscnt);
+ }
+
+ if (suwcnt) {
+ int i;
+ if((setup = (uint16 *)malloc(suwcnt*sizeof(uint16))) == NULL) {
+- DEBUG(0,("reply_trans: setup malloc fail for %d bytes !\n", (int)(suwcnt
* sizeof(uint16))));
+- END_PROFILE(SMBtrans);
+- return(ERROR_DOS(ERRDOS,ERRnomem));
+- }
++ DEBUG(0,("reply_trans: setup malloc fail for %u bytes !\n",
(unsigned int)(suwcnt * sizeof(uint16))));
++ SAFE_FREE(data);
++ SAFE_FREE(params);
++ END_PROFILE(SMBtrans);
++ return(ERROR_DOS(ERRDOS,ERRnomem));
++ }
++ if (inbuf+smb_vwv14+(suwcnt*SIZEOFWORD) > inbuf + size)
++ goto bad_param;
++ if ((smb_vwv14+(suwcnt*SIZEOFWORD) < smb_vwv14) ||
(smb_vwv14+(suwcnt*SIZEOFWORD) < (suwcnt*SIZEOFWORD)))
++ goto bad_param;
++
+ for (i=0;i<suwcnt;i++)
+ setup[i] = SVAL(inbuf,smb_vwv14+i*SIZEOFWORD);
+ }
+@@ -425,13 +442,13 @@
+ outsize = set_message(outbuf,0,0,True);
+ show_msg(outbuf);
+ if (!send_smb(smbd_server_fd(),outbuf))
+- exit_server("reply_trans: send_smb failed.\n");
++ exit_server("reply_trans: send_smb failed.");
+ }
+
+ /* receive the rest of the trans packet */
+ while (pscnt < tpscnt || dscnt < tdscnt) {
+ BOOL ret;
+- int pcnt,poff,dcnt,doff,pdisp,ddisp;
++ unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
+
+ ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
+
+@@ -451,8 +468,11 @@
+
+ show_msg(inbuf);
+
+- tpscnt = SVAL(inbuf,smb_vwv0);
+- tdscnt = SVAL(inbuf,smb_vwv1);
++ /* Revise total_params and total_data in case they have changed
downwards */
++ if (SVAL(inbuf,smb_vwv0) < tpscnt)
++ tpscnt = SVAL(inbuf,smb_vwv0);
++ if (SVAL(inbuf,smb_vwv1) < tdscnt)
++ tdscnt = SVAL(inbuf,smb_vwv1);
+
+ pcnt = SVAL(inbuf,smb_vwv2);
+ poff = SVAL(inbuf,smb_vwv3);
+@@ -465,18 +485,38 @@
+ pscnt += pcnt;
+ dscnt += dcnt;
+
+- if (dscnt > tdscnt || pscnt > tpscnt) {
+- exit_server("invalid trans parameters\n");
+- }
++ if (dscnt > tdscnt || pscnt > tpscnt)
++ goto bad_param;
+
+- if (pcnt)
++ if (pcnt) {
++ 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 (params + pdisp < params)
++ goto bad_param;
++
+ memcpy(params+pdisp,smb_base(inbuf)+poff,pcnt);
+- if (dcnt)
++ }
++
++ if (dcnt) {
++ if (ddisp+dcnt >= tdscnt)
++ goto bad_param;
++ if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt))
++ goto bad_param;
++ if (smb_base(inbuf) + doff + dcnt >= inbuf + bufsize)
++ goto bad_param;
++ if (data + ddisp < data)
++ goto bad_param;
++
+ memcpy(data+ddisp,smb_base(inbuf)+doff,dcnt);
++ }
+ }
+
+
+- DEBUG(3,("trans <%s> data=%d params=%d setup=%d\n",
++ DEBUG(3,("trans <%s> data=%u params=%u setup=%u\n",
+ name,tdscnt,tpscnt,suwcnt));
+
+ /*
+@@ -525,4 +565,14 @@
+
+ END_PROFILE(SMBtrans);
+ return(outsize);
++
++
++ bad_param:
++
++ DEBUG(0,("reply_trans: invalid trans parameters\n"));
++ SAFE_FREE(data);
++ SAFE_FREE(params);
++ SAFE_FREE(setup);
++ END_PROFILE(SMBtrans);
++ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+--- samba-2.2.7a/source/smbd/nttrans.c Mon Mar 17 10:55:36 2003
++++ samba-2.2.8/source/smbd/nttrans.c Fri Mar 14 22:34:49 2003
+@@ -28,7 +28,7 @@
+ extern BOOL case_preserve;
+ extern BOOL short_case_preserve;
+
+-static char *known_nt_pipes[] = {
++static const char *known_nt_pipes[] = {
+ "\\LANMAN",
+ "\\srvsvc",
+ "\\samr",
+@@ -1889,8 +1889,7 @@
+ if(CVAL(inbuf, smb_wct) != 19 + (setup_count/2)) {
+ DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
+ CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
+- END_PROFILE(SMBnttrans);
+- return ERROR_DOS(ERRSRV,ERRerror);
++ goto bad_param;
+ }
+
+ /* Allocate the space for the setup, the maximum needed parameters and data */
+@@ -1904,9 +1903,9 @@
+
+ if ((total_parameter_count && !params) || (total_data_count && !data) ||
+ (setup_count && !setup)) {
+- safe_free(setup);
+- safe_free(params);
+- safe_free(data);
++ SAFE_FREE(setup);
++ SAFE_FREE(params);
++ SAFE_FREE(data);
+ DEBUG(0,("reply_nttrans : Out of memory\n"));
+ END_PROFILE(SMBnttrans);
+ return ERROR_DOS(ERRDOS,ERRnomem);
+@@ -1918,21 +1917,38 @@
+ num_data_sofar = data_count;
+
+ if (parameter_count > total_parameter_count || data_count > total_data_count)
+- exit_server("reply_nttrans: invalid sizes in packet.");
++ goto bad_param;
+
+ if(setup) {
+- memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
+ DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count));
++ if ((smb_nt_SetupStart + setup_count < smb_nt_SetupStart) ||
++ (smb_nt_SetupStart + setup_count < setup_count))
++ goto bad_param;
++ if (smb_nt_SetupStart + setup_count > length)
++ goto bad_param;
++
++ memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
+ dump_data(10, setup, setup_count);
+ }
+ if(params) {
+- memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
+ DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count));
++ 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)
++ goto bad_param;
++
++ memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
+ dump_data(10, params, parameter_count);
+ }
+ if(data) {
+- memcpy( data, smb_base(inbuf) + data_offset, data_count);
+ 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)
++ goto bad_param;
++
++ memcpy( data, smb_base(inbuf) + data_offset, data_count);
+ dump_data(10, data, data_count);
+ }
+
+@@ -1945,6 +1961,8 @@
+
+ while( num_data_sofar < total_data_count || num_params_sofar <
total_parameter_count) {
+ BOOL ret;
++ uint32 parameter_displacement;
++ uint32 data_displacement;
+
+ ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
+
+@@ -1956,27 +1974,59 @@
+ DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
+ (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
+ }
+- SAFE_FREE(params);
+- SAFE_FREE(data);
+- SAFE_FREE(setup);
+- END_PROFILE(SMBnttrans);
+- return ERROR_DOS(ERRSRV,ERRerror);
+- }
++ goto bad_param;
++ }
+
+- /* Revise total_params and total_data in case they have changed downwards */
+- total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
+- total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
+- num_params_sofar += (parameter_count = IVAL(inbuf,smb_nts_ParameterCount));
+- num_data_sofar += ( data_count = IVAL(inbuf, smb_nts_DataCount));
+- if (num_params_sofar > total_parameter_count || num_data_sofar >
total_data_count)
+- exit_server("reply_nttrans2: data overflow in secondary nttrans packet");
+-
+- memcpy( ¶ms[ IVAL(inbuf, smb_nts_ParameterDisplacement)],
+- smb_base(inbuf) + IVAL(inbuf, smb_nts_ParameterOffset),
parameter_count);
+- memcpy( &data[IVAL(inbuf, smb_nts_DataDisplacement)],
+- smb_base(inbuf)+ IVAL(inbuf, smb_nts_DataOffset), data_count);
+- }
+- }
++ /* Revise total_params and total_data in case they have
changed downwards */
++ if (IVAL(inbuf, smb_nts_TotalParameterCount) <
total_parameter_count)
++ total_parameter_count = IVAL(inbuf,
smb_nts_TotalParameterCount);
++ if (IVAL(inbuf, smb_nts_TotalDataCount) < total_data_count)
++ total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
++
++ parameter_count = IVAL(inbuf,smb_nts_ParameterCount);
++ parameter_offset = IVAL(inbuf, smb_nts_ParameterOffset);
++ parameter_displacement = IVAL(inbuf,
smb_nts_ParameterDisplacement);
++ num_params_sofar += parameter_count;
++
++ data_count = IVAL(inbuf, smb_nts_DataCount);
++ data_displacement = IVAL(inbuf, smb_nts_DataDisplacement);
++ data_offset = IVAL(inbuf, smb_nts_DataOffset);
++ num_data_sofar += data_count;
++
++ if (num_params_sofar > total_parameter_count || num_data_sofar
> total_data_count) {
++ DEBUG(0,("reply_nttrans2: data overflow in secondary
nttrans packet"));
++ goto bad_param;
++ }
++
++ if (parameter_count) {
++ if (parameter_displacement + parameter_count >=
total_parameter_count)
++ goto bad_param;
++ 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)
++ goto bad_param;
++ if (params + parameter_displacement < params)
++ goto bad_param;
++
++ memcpy( ¶ms[parameter_displacement],
smb_base(inbuf) + parameter_offset, parameter_count);
++ }
++
++ if (data_count) {
++ if (data_displacement + data_count >= total_data_count)
++ goto bad_param;
++ 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)
++ goto bad_param;
++ if (data + data_displacement < data)
++ goto bad_param;
++
++ memcpy( &data[data_displacement], smb_base(inbuf)+
data_offset, data_count);
++ }
++ }
++ }
+
+ if (Protocol >= PROTOCOL_NT1)
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_IS_LONG_NAME);
+@@ -2051,4 +2101,12 @@
+ return outsize; /* If a correct response was needed the call_nt_transact_xxxx
+ calls have already sent it. If outsize != -1 then it is
+ returning an error packet. */
++
++ bad_param:
++
++ SAFE_FREE(params);
++ SAFE_FREE(data);
++ SAFE_FREE(setup);
++ END_PROFILE(SMBnttrans);
++ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+--- samba-2.2.7a/source/smbd/trans2.c Mon Mar 17 10:55:35 2003
++++ samba-2.2.8-withoutdeleteonclose/source/smbd/trans2.c Fri Mar 14 22:34:49
2003
+@@ -3202,7 +3186,7 @@
+ unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
+ unsigned int tran_call = SVAL(inbuf, smb_setup0);
+ char *params = NULL, *data = NULL;
+- int num_params, num_params_sofar, num_data, num_data_sofar;
++ unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
+ START_PROFILE(SMBtrans2);
+
+ if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
+@@ -3241,10 +3225,10 @@
+ (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
+ DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
+ } else {
+- DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
++ DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
+ DEBUG(2,("Transaction is %d\n",tran_call));
+ END_PROFILE(SMBtrans2);
+- return ERROR_DOS(ERRSRV,ERRerror);
++ ERROR_DOS(ERRDOS,ERRinvalidparam);
+ }
+ }
+
+@@ -3270,10 +3254,22 @@
+ if (num_params > total_params || num_data > total_data)
+ exit_server("invalid params in reply_trans2");
+
+- if(params)
+- memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
+- if(data)
+- memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
++ if(params) {
++ 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)
++ goto bad_param;
++ memcpy( params, smb_base(inbuf) + psoff, num_params);
++ }
++ if(data) {
++ 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)
++ goto bad_param;
++ memcpy( data, smb_base(inbuf) + dsoff, num_data);
++ }
+
+ if(num_data_sofar < total_data || num_params_sofar < total_params) {
+ /* We need to send an interim response then receive the rest
+@@ -3285,6 +3281,10 @@
+ while (num_data_sofar < total_data ||
+ num_params_sofar < total_params) {
+ BOOL ret;
++ unsigned int param_disp;
++ unsigned int param_off;
++ unsigned int data_disp;
++ unsigned int data_off;
+
+ ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
+
+@@ -3296,25 +3296,55 @@
+ else
+ DEBUG(0,("reply_trans2: %s in getting
secondary trans2 response.\n",
+ (smb_read_error == READ_ERROR) ?
"error" : "timeout" ));
+- SAFE_FREE(params);
+- SAFE_FREE(data);
+- END_PROFILE(SMBtrans2);
+- return ERROR_DOS(ERRSRV,ERRerror);
++ goto bad_param;
+ }
+
+ /* Revise total_params and total_data in case
+ they have changed downwards */
+- total_params = SVAL(inbuf, smb_tpscnt);
+- total_data = SVAL(inbuf, smb_tdscnt);
+- num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
+- num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
++ if (SVAL(inbuf, smb_tpscnt) < total_params)
++ total_params = SVAL(inbuf, smb_tpscnt);
++ if (SVAL(inbuf, smb_tdscnt) < total_data)
++ total_data = SVAL(inbuf, smb_tdscnt);
++
++ num_params = SVAL(inbuf,smb_spscnt);
++ param_off = SVAL(inbuf, smb_spsoff);
++ param_disp = SVAL(inbuf, smb_spsdisp);
++ num_params_sofar += num_params;
++
++ num_data = SVAL(inbuf, smb_sdscnt);
++ data_off = SVAL(inbuf, smb_sdsoff);
++ data_disp = SVAL(inbuf, smb_sdsdisp);
++ num_data_sofar += num_data;
++
+ if (num_params_sofar > total_params || num_data_sofar >
total_data)
+- exit_server("data overflow in trans2");
++ goto bad_param;
+
+- memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
+- smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
+- memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
+- smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
++ if (num_params) {
++ if (param_disp + num_params >= total_params)
++ goto bad_param;
++ 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)
++ goto bad_param;
++ if (params + param_disp < params)
++ goto bad_param;
++
++ memcpy( ¶ms[param_disp], smb_base(inbuf) +
param_off, num_params);
++ }
++ if (num_data) {
++ if (data_disp + num_data >= total_data)
++ goto bad_param;
++ 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)
++ goto bad_param;
++ if (data + data_disp < data)
++ goto bad_param;
++
++ memcpy( &data[data_disp], smb_base(inbuf) + data_off,
num_data);
++ }
+ }
+ }
+
+@@ -3427,4 +3457,11 @@
+ return outsize; /* If a correct response was needed the
+ call_trans2xxx calls have already sent
+ it. If outsize != -1 then it is returning */
++
++ bad_param:
++
++ SAFE_FREE(params);
++ SAFE_FREE(data);
++ END_PROFILE(SMBtrans2);
++ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+--- samba-2.2.7a/source/smbd/vfs-wrap.c Mon Mar 17 10:55:37 2003
++++ samba-2.2.8/source/smbd/vfs-wrap.c Fri Mar 14 22:34:49 2003
+@@ -213,8 +213,9 @@
+ static int copy_reg(const char *source, const char *dest)
+ {
+ SMB_STRUCT_STAT source_stats;
+- int ifd;
+- int ofd;
++ int saved_errno;
++ int ifd = -1;
++ int ofd = -1;
+
+ if (sys_lstat (source, &source_stats) == -1)
+ return -1;
+@@ -222,42 +223,44 @@
+ if (!S_ISREG (source_stats.st_mode))
+ return -1;
+
+- if (unlink (dest) && errno != ENOENT)
+- return -1;
+-
+ if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
+ return -1;
+
+- if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 ) {
+- int saved_errno = errno;
+- close (ifd);
+- errno = saved_errno;
++ if (unlink (dest) && errno != ENOENT)
+ return -1;
+- }
+
+- if (transfer_file(ifd, ofd, (size_t)-1) == -1) {
+- int saved_errno = errno;
+- close (ifd);
+- close (ofd);
+- unlink (dest);
+- errno = saved_errno;
+- return -1;
+- }
++#ifdef O_NOFOLLOW
++ if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) <
0 )
++#else
++ if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
++#endif
++ goto err;
+
+- if (close (ifd) == -1) {
+- int saved_errno = errno;
+- close (ofd);
+- errno = saved_errno;
+- return -1;
+- }
+- if (close (ofd) == -1)
+- return -1;
++ if (transfer_file(ifd, ofd, (size_t)-1) == -1)
++ goto err;
++
++ /*
++ * Try to preserve ownership. For non-root it might fail, but that's ok.
++ * But root probably wants to know, e.g. if NFS disallows it.
++ */
++
++ if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno !=
EPERM))
++ goto err;
+
+ /*
+- * chown turns off set[ug]id bits for non-root,
++ * fchown turns off set[ug]id bits for non-root,
+ * so do the chmod last.
+ */
+
++ if (fchmod (ofd, source_stats.st_mode & 07777))
++ goto err;
++
++ if (close (ifd) == -1)
++ goto err;
++
++ if (close (ofd) == -1)
++ return -1;
++
+ /* Try to copy the old file's modtime and access time. */
+ {
+ struct utimbuf tv;
+@@ -267,21 +270,19 @@
+ utime (dest, &tv);
+ }
+
+- /*
+- * Try to preserve ownership. For non-root it might fail, but that's ok.
+- * But root probably wants to know, e.g. if NFS disallows it.
+- */
+-
+- if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno !=
EPERM))
+- return -1;
+-
+- if (chmod (dest, source_stats.st_mode & 07777))
+- return -1;
+-
+ if (unlink (source) == -1)
+ return -1;
+
+ return 0;
++
++ err:
++ saved_errno = errno;
++ if (ifd != -1)
++ close(ifd);
++ if (ofd != -1)
++ close(ofd);
++ errno = saved_errno;
++ return -1;
+ }
+
+ int vfswrap_rename(connection_struct *conn, const char *oldname, const char
*newname)
@@ .
patch -p0 <<'@@ .'
Index: openpkg-src/samba/samba.spec
============================================================================
$ cvs diff -u -r1.35.2.1.2.1 -r1.35.2.1.2.2 samba.spec
--- openpkg-src/samba/samba.spec 18 Jan 2003 17:22:36 -0000 1.35.2.1.2.1
+++ openpkg-src/samba/samba.spec 17 Mar 2003 19:32:17 -0000 1.35.2.1.2.2
@@ -33,7 +33,7 @@
Group: Filesystem
License: GPL
Version: 2.2.7a
-Release: 1.2.0
+Release: 1.2.1
# package options
%option with_pam no
@@ -43,6 +43,7 @@
Source1: smb.conf
Source2: smb.hosts
Source3: rc.samba
+Patch0: samba.patch
# build information
Prefix: %{l_prefix}
@@ -62,6 +63,7 @@
%prep
%setup -q
+ %patch -p1
%build
( cd source
@@ .
______________________________________________________________________
The OpenPKG Project www.openpkg.org
CVS Repository Commit List [EMAIL PROTECTED]