fix patches and closes #350
[openwrt.git] / package / samba / patches / 200-security.patch
1 diff -ruN samba-2.0.10.orig/source/include/smb.h samba-2.0.10/source/include/smb.h
2 --- samba-2.0.10.orig/source/include/smb.h 2006-03-06 22:25:08.000000000 +0100
3 +++ samba-2.0.10/source/include/smb.h 2006-03-06 22:25:53.000000000 +0100
4 @@ -272,6 +272,7 @@
5 #define ERRlock 33 /* Lock request conflicts with existing lock */
6 #define ERRunsup 50 /* Request unsupported, returned by Win 95, RJS 20Jun98 */
7 #define ERRfilexists 80 /* File in operation already exists */
8 +#define ERRinvalidparam 87
9 #define ERRcannotopen 110 /* Cannot open the file specified */
10 #define ERRunknownlevel 124
11 #define ERRrename 183
12 @@ -1911,4 +1912,7 @@
13
14 #define SAFE_NETBIOS_CHARS ". -_"
15
16 +#ifndef SAFE_FREE
17 +#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0)
18 +#endif
19 #endif /* _SMB_H */
20 diff -ruN samba-2.0.10.orig/source/include/version.h samba-2.0.10/source/include/version.h
21 --- samba-2.0.10.orig/source/include/version.h 2001-06-23 15:23:59.000000000 +0200
22 +++ samba-2.0.10/source/include/version.h 2006-03-06 22:25:53.000000000 +0100
23 @@ -1 +1 @@
24 -#define VERSION "2.0.10"
25 +#define VERSION "2.0.10-security-rollup"
26 diff -ruN samba-2.0.10.orig/source/smbd/filename.c samba-2.0.10/source/smbd/filename.c
27 --- samba-2.0.10.orig/source/smbd/filename.c 2000-03-16 23:59:44.000000000 +0100
28 +++ samba-2.0.10/source/smbd/filename.c 2006-03-06 22:25:53.000000000 +0100
29 @@ -172,7 +172,7 @@
30 * StrnCpy always null terminates.
31 */
32
33 - StrnCpy(orig_name, full_orig_name, namelen);
34 + StrnCpy(orig_name, full_orig_name, MIN(namelen, sizeof(orig_name)-1));
35 if(!case_sensitive)
36 strupper( orig_name );
37
38 diff -ruN samba-2.0.10.orig/source/smbd/ipc.c samba-2.0.10/source/smbd/ipc.c
39 --- samba-2.0.10.orig/source/smbd/ipc.c 2006-03-06 22:25:08.000000000 +0100
40 +++ samba-2.0.10/source/smbd/ipc.c 2006-03-06 22:25:53.000000000 +0100
41 @@ -3556,18 +3556,18 @@
42 uint16 *setup=NULL;
43 int outsize = 0;
44 uint16 vuid = SVAL(inbuf,smb_uid);
45 - int tpscnt = SVAL(inbuf,smb_vwv0);
46 - int tdscnt = SVAL(inbuf,smb_vwv1);
47 - int mprcnt = SVAL(inbuf,smb_vwv2);
48 - int mdrcnt = SVAL(inbuf,smb_vwv3);
49 - int msrcnt = CVAL(inbuf,smb_vwv4);
50 + unsigned int tpscnt = SVAL(inbuf,smb_vwv0);
51 + unsigned int tdscnt = SVAL(inbuf,smb_vwv1);
52 + unsigned int mprcnt = SVAL(inbuf,smb_vwv2);
53 + unsigned int mdrcnt = SVAL(inbuf,smb_vwv3);
54 + unsigned int msrcnt = CVAL(inbuf,smb_vwv4);
55 BOOL close_on_completion = BITSETW(inbuf+smb_vwv5,0);
56 BOOL one_way = BITSETW(inbuf+smb_vwv5,1);
57 - int pscnt = SVAL(inbuf,smb_vwv9);
58 - int psoff = SVAL(inbuf,smb_vwv10);
59 - int dscnt = SVAL(inbuf,smb_vwv11);
60 - int dsoff = SVAL(inbuf,smb_vwv12);
61 - int suwcnt = CVAL(inbuf,smb_vwv13);
62 + unsigned int pscnt = SVAL(inbuf,smb_vwv9);
63 + unsigned int psoff = SVAL(inbuf,smb_vwv10);
64 + unsigned int dscnt = SVAL(inbuf,smb_vwv11);
65 + unsigned int dsoff = SVAL(inbuf,smb_vwv12);
66 + unsigned int suwcnt = CVAL(inbuf,smb_vwv13);
67
68 memset(name, '\0',sizeof(name));
69 fstrcpy(name,smb_buf(inbuf));
70 @@ -3578,26 +3578,44 @@
71
72 if (tdscnt) {
73 if((data = (char *)malloc(tdscnt)) == NULL) {
74 - DEBUG(0,("reply_trans: data malloc fail for %d bytes !\n", tdscnt));
75 + DEBUG(0,("reply_trans: data malloc fail for %u bytes !\n", tdscnt));
76 return(ERROR(ERRDOS,ERRnomem));
77 }
78 + if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
79 + goto bad_param;
80 + if (smb_base(inbuf)+dsoff+dscnt > inbuf + size)
81 + goto bad_param;
82 +
83 memcpy(data,smb_base(inbuf)+dsoff,dscnt);
84 }
85
86 if (tpscnt) {
87 if((params = (char *)malloc(tpscnt)) == NULL) {
88 - DEBUG(0,("reply_trans: param malloc fail for %d bytes !\n", tpscnt));
89 + DEBUG(0,("reply_trans: param malloc fail for %u bytes !\n", tpscnt));
90 + SAFE_FREE(data);
91 return(ERROR(ERRDOS,ERRnomem));
92 }
93 + if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt))
94 + goto bad_param;
95 + if (smb_base(inbuf)+psoff+pscnt > inbuf + size)
96 + goto bad_param;
97 +
98 memcpy(params,smb_base(inbuf)+psoff,pscnt);
99 }
100
101 if (suwcnt) {
102 int i;
103 if((setup = (uint16 *)malloc(suwcnt*sizeof(uint16))) == NULL) {
104 - DEBUG(0,("reply_trans: setup malloc fail for %d bytes !\n", (int)(suwcnt * sizeof(uint16))));
105 - return(ERROR(ERRDOS,ERRnomem));
106 - }
107 + DEBUG(0,("reply_trans: setup malloc fail for %u bytes !\n", (unsigned int)(suwcnt * sizeof(uint16))));
108 + SAFE_FREE(data);
109 + SAFE_FREE(params);
110 + return(ERROR(ERRDOS,ERRnomem));
111 + }
112 + if (inbuf+smb_vwv14+(suwcnt*SIZEOFWORD) > inbuf + size)
113 + goto bad_param;
114 + if ((smb_vwv14+(suwcnt*SIZEOFWORD) < smb_vwv14) || (smb_vwv14+(suwcnt*SIZEOFWORD) < (suwcnt*SIZEOFWORD)))
115 + goto bad_param;
116 +
117 for (i=0;i<suwcnt;i++)
118 setup[i] = SVAL(inbuf,smb_vwv14+i*SIZEOFWORD);
119 }
120 @@ -3614,7 +3632,7 @@
121 /* receive the rest of the trans packet */
122 while (pscnt < tpscnt || dscnt < tdscnt) {
123 BOOL ret;
124 - int pcnt,poff,dcnt,doff,pdisp,ddisp;
125 + unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
126
127 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
128
129 @@ -3625,19 +3643,19 @@
130 DEBUG(0,("reply_trans: %s in getting secondary trans response.\n",
131 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
132 }
133 - if (params)
134 - free(params);
135 - if (data)
136 - free(data);
137 - if (setup)
138 - free(setup);
139 + SAFE_FREE(params);
140 + SAFE_FREE(data);
141 + SAFE_FREE(setup);
142 return(ERROR(ERRSRV,ERRerror));
143 }
144
145 show_msg(inbuf);
146
147 - tpscnt = SVAL(inbuf,smb_vwv0);
148 - tdscnt = SVAL(inbuf,smb_vwv1);
149 + /* Revise total_params and total_data in case they have changed downwards */
150 + if (SVAL(inbuf,smb_vwv0) < tpscnt)
151 + tpscnt = SVAL(inbuf,smb_vwv0);
152 + if (SVAL(inbuf,smb_vwv1) < tdscnt)
153 + tdscnt = SVAL(inbuf,smb_vwv1);
154
155 pcnt = SVAL(inbuf,smb_vwv2);
156 poff = SVAL(inbuf,smb_vwv3);
157 @@ -3650,17 +3668,36 @@
158 pscnt += pcnt;
159 dscnt += dcnt;
160
161 - if (dscnt > tdscnt || pscnt > tpscnt) {
162 - exit_server("invalid trans parameters\n");
163 - }
164 + if (dscnt > tdscnt || pscnt > tpscnt)
165 + goto bad_param;
166
167 - if (pcnt)
168 + if (pcnt) {
169 + if (pdisp+pcnt >= tpscnt)
170 + goto bad_param;
171 + if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt))
172 + goto bad_param;
173 + if (smb_base(inbuf) + poff + pcnt >= inbuf + bufsize)
174 + goto bad_param;
175 + if (params + pdisp < params)
176 + goto bad_param;
177 +
178 memcpy(params+pdisp,smb_base(inbuf)+poff,pcnt);
179 - if (dcnt)
180 + }
181 +
182 + if (dcnt) {
183 + if (ddisp+dcnt >= tdscnt)
184 + goto bad_param;
185 + if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt))
186 + goto bad_param;
187 + if (smb_base(inbuf) + doff + dcnt >= inbuf + bufsize)
188 + goto bad_param;
189 + if (data + ddisp < data)
190 + goto bad_param;
191 +
192 memcpy(data+ddisp,smb_base(inbuf)+doff,dcnt);
193 + }
194 }
195 -
196 -
197 +
198 DEBUG(3,("trans <%s> data=%d params=%d setup=%d\n",
199 name,tdscnt,tpscnt,suwcnt));
200
201 @@ -3700,4 +3737,12 @@
202 return(ERROR(ERRSRV,ERRnosupport));
203
204 return(outsize);
205 +
206 + bad_param:
207 +
208 + DEBUG(0,("reply_trans: invalid trans parameters\n"));
209 + SAFE_FREE(data);
210 + SAFE_FREE(params);
211 + SAFE_FREE(setup);
212 + return(ERROR(ERRSRV,ERRerror));
213 }
214 diff -ruN samba-2.0.10.orig/source/smbd/nttrans.c samba-2.0.10/source/smbd/nttrans.c
215 --- samba-2.0.10.orig/source/smbd/nttrans.c 2000-04-24 19:27:30.000000000 +0200
216 +++ samba-2.0.10/source/smbd/nttrans.c 2006-03-06 22:25:53.000000000 +0100
217 @@ -2575,11 +2575,14 @@
218 params = (char *)malloc(total_parameter_count);
219 if (total_data_count > 0)
220 data = (char *)malloc(total_data_count);
221 -
222 +
223 if ((total_parameter_count && !params) || (total_data_count && !data) ||
224 (setup_count && !setup)) {
225 + SAFE_FREE(setup);
226 + SAFE_FREE(params);
227 + SAFE_FREE(data);
228 DEBUG(0,("reply_nttrans : Out of memory\n"));
229 - return(ERROR(ERRDOS,ERRnomem));
230 + return ERROR(ERRDOS,ERRnomem);
231 }
232
233 /* Copy the param and data bytes sent with this request into
234 @@ -2588,64 +2591,112 @@
235 num_data_sofar = data_count;
236
237 if (parameter_count > total_parameter_count || data_count > total_data_count)
238 - exit_server("reply_nttrans: invalid sizes in packet.\n");
239 + goto bad_param;
240
241 if(setup) {
242 - memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
243 DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count));
244 - dump_data(10, setup, setup_count);
245 + if ((smb_nt_SetupStart + setup_count < smb_nt_SetupStart) ||
246 + (smb_nt_SetupStart + setup_count < setup_count))
247 + goto bad_param;
248 + if (smb_nt_SetupStart + setup_count > length)
249 + goto bad_param;
250 +
251 + memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
252 }
253 if(params) {
254 - memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
255 DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count));
256 - dump_data(10, params, parameter_count);
257 + if ((parameter_offset + parameter_count < parameter_offset) ||
258 + (parameter_offset + parameter_count < parameter_count))
259 + goto bad_param;
260 + if (smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length)
261 + goto bad_param;
262 +
263 + memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
264 }
265 if(data) {
266 - memcpy( data, smb_base(inbuf) + data_offset, data_count);
267 DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
268 - dump_data(10, data, data_count);
269 + if ((data_offset + data_count < data_offset) || (data_offset + data_count < data_count))
270 + goto bad_param;
271 + if (smb_base(inbuf) + data_offset + data_count > inbuf + length)
272 + goto bad_param;
273 +
274 + memcpy( data, smb_base(inbuf) + data_offset, data_count);
275 +
276 }
277
278 if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
279 /* We need to send an interim response then receive the rest
280 of the parameter/data bytes */
281 outsize = set_message(outbuf,0,0,True);
282 - send_smb(Client,outbuf);
283 + if (!send_smb(Client,outbuf))
284 + exit_server("reply_nttrans: send_smb failed.");
285
286 while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
287 BOOL ret;
288 -
289 + uint32 parameter_displacement;
290 + uint32 data_displacement;
291 +
292 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
293 -
294 +
295 if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
296 - outsize = set_message(outbuf,0,0,True);
297 - if(ret) {
298 - DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
299 - } else {
300 - DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
301 - (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
302 + outsize = set_message(outbuf,0,0,True);
303 + if(ret) {
304 + DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
305 + } else {
306 + DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
307 + (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
308 }
309 - if(params)
310 - free(params);
311 - if(data)
312 - free(data);
313 - if(setup)
314 - free(setup);
315 - return(ERROR(ERRSRV,ERRerror));
316 + goto bad_param;
317 }
318
319 /* Revise total_params and total_data in case they have changed downwards */
320 - total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
321 - total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
322 - num_params_sofar += (parameter_count = IVAL(inbuf,smb_nts_ParameterCount));
323 - num_data_sofar += ( data_count = IVAL(inbuf, smb_nts_DataCount));
324 - if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count)
325 - exit_server("reply_nttrans2: data overflow in secondary nttrans packet\n");
326 -
327 - memcpy( &params[ IVAL(inbuf, smb_nts_ParameterDisplacement)],
328 - smb_base(inbuf) + IVAL(inbuf, smb_nts_ParameterOffset), parameter_count);
329 - memcpy( &data[IVAL(inbuf, smb_nts_DataDisplacement)],
330 - smb_base(inbuf)+ IVAL(inbuf, smb_nts_DataOffset), data_count);
331 + if (IVAL(inbuf, smb_nts_TotalParameterCount) < total_parameter_count)
332 + total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
333 + if (IVAL(inbuf, smb_nts_TotalDataCount) < total_data_count)
334 + total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
335 +
336 + parameter_count = IVAL(inbuf,smb_nts_ParameterCount);
337 + parameter_offset = IVAL(inbuf, smb_nts_ParameterOffset);
338 + parameter_displacement = IVAL(inbuf, smb_nts_ParameterDisplacement);
339 + num_params_sofar += parameter_count;
340 +
341 + data_count = IVAL(inbuf, smb_nts_DataCount);
342 + data_displacement = IVAL(inbuf, smb_nts_DataDisplacement);
343 + data_offset = IVAL(inbuf, smb_nts_DataOffset);
344 + num_data_sofar += data_count;
345 +
346 + if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count) {
347 + DEBUG(0,("reply_nttrans2: data overflow in secondary nttrans packet"));
348 + goto bad_param;
349 + }
350 +
351 + if (parameter_count) {
352 + if (parameter_displacement + parameter_count >= total_parameter_count)
353 + goto bad_param;
354 + if ((parameter_displacement + parameter_count < parameter_displacement) ||
355 + (parameter_displacement + parameter_count < parameter_count))
356 + goto bad_param;
357 + if (smb_base(inbuf) + parameter_offset + parameter_count >= inbuf + bufsize)
358 + goto bad_param;
359 + if (params + parameter_displacement < params)
360 + goto bad_param;
361 +
362 + memcpy( &params[parameter_displacement], smb_base(inbuf) + parameter_offset, parameter_count);
363 + }
364 +
365 + if (data_count) {
366 + if (data_displacement + data_count >= total_data_count)
367 + goto bad_param;
368 + if ((data_displacement + data_count < data_displacement) ||
369 + (data_displacement + data_count < data_count))
370 + goto bad_param;
371 + if (smb_base(inbuf) + data_offset + data_count >= inbuf + bufsize)
372 + goto bad_param;
373 + if (data + data_displacement < data)
374 + goto bad_param;
375 +
376 + memcpy( &data[data_displacement], smb_base(inbuf)+ data_offset, data_count);
377 + }
378 }
379 }
380
381 @@ -2714,4 +2765,10 @@
382 return outsize; /* If a correct response was needed the call_nt_transact_xxxx
383 calls have already sent it. If outsize != -1 then it is
384 returning an error packet. */
385 + bad_param:
386 +
387 + SAFE_FREE(params);
388 + SAFE_FREE(data);
389 + SAFE_FREE(setup);
390 + return ERROR(ERRDOS,ERRinvalidparam);
391 }
392 diff -ruN samba-2.0.10.orig/source/smbd/password.c samba-2.0.10/source/smbd/password.c
393 --- samba-2.0.10.orig/source/smbd/password.c 2006-03-06 22:25:08.000000000 +0100
394 +++ samba-2.0.10/source/smbd/password.c 2006-03-06 22:25:53.000000000 +0100
395 @@ -770,7 +770,7 @@
396 if (!ok && lp_username(snum)) {
397 char *auser;
398 pstring user_list;
399 - StrnCpy(user_list,lp_username(snum),sizeof(pstring));
400 + StrnCpy(user_list,lp_username(snum),sizeof(pstring)-1);
401
402 pstring_sub(user_list,"%S",lp_servicename(snum));
403
404 diff -ruN samba-2.0.10.orig/source/smbd/reply.c samba-2.0.10/source/smbd/reply.c
405 --- samba-2.0.10.orig/source/smbd/reply.c 2006-03-06 22:25:08.000000000 +0100
406 +++ samba-2.0.10/source/smbd/reply.c 2006-03-06 22:25:53.000000000 +0100
407 @@ -1413,6 +1413,9 @@
408
409 for (i=numentries;(i<maxentries) && !finished;i++)
410 {
411 + /* check to make sure we have room in the buffer */
412 + if ( ((PTR_DIFF(p, outbuf))+DIR_STRUCT_SIZE) > BUFFER_SIZE )
413 + break;
414 finished =
415 !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
416 if (!finished)
417 @@ -3122,6 +3125,9 @@
418
419
420 for (i=first;i<first+num_to_get;i++) {
421 + /* check to make sure we have room in the buffer */
422 + if ( (PTR_DIFF(p, outbuf)+28) > BUFFER_SIZE )
423 + break;
424 put_dos_date2(p,0,queue[i].time);
425 CVAL(p,4) = (queue[i].status==LPQ_PRINTING?2:3);
426 SSVAL(p,5,printjob_encode(SNUM(conn),
427 diff -ruN samba-2.0.10.orig/source/smbd/trans2.c samba-2.0.10/source/smbd/trans2.c
428 --- samba-2.0.10.orig/source/smbd/trans2.c 2000-04-24 19:27:31.000000000 +0200
429 +++ samba-2.0.10/source/smbd/trans2.c 2006-03-06 22:25:53.000000000 +0100
430 @@ -201,7 +201,6 @@
431 int16 open_ofun = SVAL(params,12);
432 int32 open_size = IVAL(params,14);
433 char *pname = &params[28];
434 - int16 namelen = strlen(pname)+1;
435
436 pstring fname;
437 mode_t unixmode;
438 @@ -213,7 +212,7 @@
439 BOOL bad_path = False;
440 files_struct *fsp;
441
442 - StrnCpy(fname,pname,namelen);
443 + pstrcpy(fname,pname);
444
445 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
446 fname,open_mode, open_attr, open_ofun, open_size));
447 @@ -2185,7 +2184,7 @@
448 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
449 unsigned int tran_call = SVAL(inbuf, smb_setup0);
450 char *params = NULL, *data = NULL;
451 - int num_params, num_params_sofar, num_data, num_data_sofar;
452 + unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
453
454 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
455 /* Queue this open message as we are the process of an
456 @@ -2203,8 +2202,9 @@
457 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
458 is so as a sanity check */
459 if (suwcnt != 1) {
460 - DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
461 - return(ERROR(ERRSRV,ERRerror));
462 + DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
463 + DEBUG(2,("Transaction is %d\n",tran_call));
464 + ERROR(ERRDOS,ERRinvalidparam);
465 }
466
467 /* Allocate the space for the maximum needed parameters and data */
468 @@ -2215,11 +2215,9 @@
469
470 if ((total_params && !params) || (total_data && !data)) {
471 DEBUG(2,("Out of memory in reply_trans2\n"));
472 - if(params)
473 - free(params);
474 - if(data)
475 - free(data);
476 - return(ERROR(ERRDOS,ERRnomem));
477 + SAFE_FREE(params);
478 + SAFE_FREE(data);
479 + return ERROR(ERRDOS,ERRnomem);
480 }
481
482 /* Copy the param and data bytes sent with this request into
483 @@ -2230,20 +2228,37 @@
484 if (num_params > total_params || num_data > total_data)
485 exit_server("invalid params in reply_trans2");
486
487 - if(params)
488 - memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
489 - if(data)
490 - memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
491 + if(params) {
492 + unsigned int psoff = SVAL(inbuf, smb_psoff);
493 + if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
494 + goto bad_param;
495 + if (smb_base(inbuf) + psoff + num_params > inbuf + length)
496 + goto bad_param;
497 + memcpy( params, smb_base(inbuf) + psoff, num_params);
498 + }
499 + if(data) {
500 + unsigned int dsoff = SVAL(inbuf, smb_dsoff);
501 + if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
502 + goto bad_param;
503 + if (smb_base(inbuf) + dsoff + num_data > inbuf + length)
504 + goto bad_param;
505 + memcpy( data, smb_base(inbuf) + dsoff, num_data);
506 + }
507
508 if(num_data_sofar < total_data || num_params_sofar < total_params) {
509 /* We need to send an interim response then receive the rest
510 of the parameter/data bytes */
511 outsize = set_message(outbuf,0,0,True);
512 - send_smb(Client,outbuf);
513 + if (!send_smb(Client,outbuf))
514 + exit_server("reply_trans2: send_smb failed.");
515
516 while (num_data_sofar < total_data ||
517 num_params_sofar < total_params) {
518 BOOL ret;
519 + unsigned int param_disp;
520 + unsigned int param_off;
521 + unsigned int data_disp;
522 + unsigned int data_off;
523
524 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
525
526 @@ -2255,26 +2270,55 @@
527 else
528 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
529 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
530 - if(params)
531 - free(params);
532 - if(data)
533 - free(data);
534 - return(ERROR(ERRSRV,ERRerror));
535 + goto bad_param;
536 }
537
538 /* Revise total_params and total_data in case
539 they have changed downwards */
540 - total_params = SVAL(inbuf, smb_tpscnt);
541 - total_data = SVAL(inbuf, smb_tdscnt);
542 - num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
543 - num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
544 + if (SVAL(inbuf, smb_tpscnt) < total_params)
545 + total_params = SVAL(inbuf, smb_tpscnt);
546 + if (SVAL(inbuf, smb_tdscnt) < total_data)
547 + total_data = SVAL(inbuf, smb_tdscnt);
548 +
549 + num_params = SVAL(inbuf,smb_spscnt);
550 + param_off = SVAL(inbuf, smb_spsoff);
551 + param_disp = SVAL(inbuf, smb_spsdisp);
552 + num_params_sofar += num_params;
553 +
554 + num_data = SVAL(inbuf, smb_sdscnt);
555 + data_off = SVAL(inbuf, smb_sdsoff);
556 + data_disp = SVAL(inbuf, smb_sdsdisp);
557 + num_data_sofar += num_data;
558 +
559 if (num_params_sofar > total_params || num_data_sofar > total_data)
560 - exit_server("data overflow in trans2");
561 + goto bad_param;
562
563 - memcpy( &params[ SVAL(inbuf, smb_spsdisp)],
564 - smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
565 - memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
566 - smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
567 + if (num_params) {
568 + if (param_disp + num_params >= total_params)
569 + goto bad_param;
570 + if ((param_disp + num_params < param_disp) ||
571 + (param_disp + num_params < num_params))
572 + goto bad_param;
573 + if (smb_base(inbuf) + param_off + num_params >= inbuf + bufsize)
574 + goto bad_param;
575 + if (params + param_disp < params)
576 + goto bad_param;
577 +
578 + memcpy( &params[param_disp], smb_base(inbuf) + param_off, num_params);
579 + }
580 + if (num_data) {
581 + if (data_disp + num_data >= total_data)
582 + goto bad_param;
583 + if ((data_disp + num_data < data_disp) ||
584 + (data_disp + num_data < num_data))
585 + goto bad_param;
586 + if (smb_base(inbuf) + data_off + num_data >= inbuf + bufsize)
587 + goto bad_param;
588 + if (data + data_disp < data)
589 + goto bad_param;
590 +
591 + memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
592 + }
593 }
594 }
595
596 @@ -2367,4 +2411,10 @@
597 return outsize; /* If a correct response was needed the
598 call_trans2xxx calls have already sent
599 it. If outsize != -1 then it is returning */
600 +
601 + bad_param:
602 +
603 + SAFE_FREE(params);
604 + SAFE_FREE(data);
605 + return (ERROR(ERRDOS,ERRinvalidparam));
606 }
This page took 0.06539 seconds and 5 git commands to generate.