kukks: [Samba] OS/2 client crash on "Find Close2"

Jeremy Allison jra at samba.org
Sat Aug 12 02:04:18 GMT 2006


On Fri, Aug 11, 2006 at 07:02:00PM -0700, Jeremy Allison wrote:
> On Sat, Aug 12, 2006 at 01:42:19AM +0200, Guenter Kukkukk (sambaos2) wrote:
> > 
> > Could it be, that samba is sending too much data into a small buffer?
> 
> Ok, can you try this patch. It applies against SAMBA_3_0 and
> 3.0.23b. Let me know if this fixes it for OS/2. Volker, you might want
> to look at this also !

One more time with a slight extra paranoia fix ( max_data_bytes > 0 :-).

Jeremy.
-------------- next part --------------
Index: smbd/blocking.c
===================================================================
--- smbd/blocking.c	(revision 17496)
+++ smbd/blocking.c	(working copy)
@@ -458,7 +458,8 @@
 	construct_reply_common(inbuf, outbuf);
 	SCVAL(outbuf,smb_com,SMBtrans2);
 	SSVAL(params,0,0);
-	send_trans2_replies(outbuf, max_send, params, 2, NULL, 0);
+	/* Fake up max_data_bytes here - we know it fits. */
+	send_trans2_replies(outbuf, max_send, params, 2, NULL, 0, 0xffff);
 	return True;
 }
 
Index: smbd/error.c
===================================================================
--- smbd/error.c	(revision 17496)
+++ smbd/error.c	(working copy)
@@ -81,9 +81,8 @@
  If the override errors are set they take precedence over any passed in values.
 ****************************************************************************/
 
-int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
+void error_packet_set(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
 {
-	int outsize = set_message(outbuf,0,0,True);
 	BOOL force_nt_status = False;
 	BOOL force_dos_status = False;
 
@@ -125,6 +124,11 @@
 			  eclass,
 			  ecode));
 	}
+}
 
+int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
+{
+	int outsize = set_message(outbuf,0,0,True);
+	error_packet_set(outbuf, eclass, ecode, ntstatus, line, file);
 	return outsize;
 }
Index: smbd/trans2.c
===================================================================
--- smbd/trans2.c	(revision 17496)
+++ smbd/trans2.c	(working copy)
@@ -573,7 +573,8 @@
 			char *params, 
 			int paramsize,
 			char *pdata,
-			int datasize)
+			int datasize,
+			int max_data_bytes)
 {
 	/* As we are using a protocol > LANMAN1 then the max_send
 	 variable must have been set in the sessetupX call.
@@ -594,6 +595,18 @@
 	
 	set_message(outbuf,10,0,True);
 
+	/* Modify the data_to_send and datasize and set the error if
+	   we're trying to send more than max_data_bytes. We still send
+	   the part of the packet(s) that fit. Strange, but needed
+	   for OS/2. */
+
+	if (max_data_bytes > 0 && datasize > max_data_bytes) {
+		DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
+			max_data_bytes, datasize ));
+		datasize = data_to_send = max_data_bytes;
+		error_packet_set(outbuf,ERRDOS,ERRbufferoverflow,STATUS_BUFFER_OVERFLOW,__LINE__,__FILE__);
+	}
+
 	/* If there genuinely are no parameters or data to send just send the empty packet */
 
 	if(params_to_send == 0 && data_to_send == 0) {
@@ -932,7 +945,7 @@
 	}
 
 	/* Send the required number of replies */
-	send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0);
+	send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0, max_data_bytes);
 
 	return -1;
 }
@@ -1858,7 +1871,7 @@
 	SSVAL(params,6,0); /* Never an EA error */
 	SSVAL(params,8,last_entry_off);
 
-	send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
+	send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata), max_data_bytes);
 
 	if ((! *directory) && dptr_path(dptr_num))
 		slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
@@ -2140,7 +2153,7 @@
 	SSVAL(params,4,0); /* Never an EA error */
 	SSVAL(params,6,last_entry_off);
 
-	send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
+	send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata), max_data_bytes);
 
 	if ((! *directory) && dptr_path(dptr_num))
 		slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
@@ -2503,7 +2516,7 @@
 	}
 
 
-	send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
+	send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len, max_data_bytes);
 
 	DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
 
@@ -3633,7 +3646,7 @@
 			return ERROR_NT(NT_STATUS_INVALID_LEVEL);
 	}
 
-	send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
+	send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size, max_data_bytes);
 
 	return(-1);
 }
@@ -3782,7 +3795,7 @@
 				DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
 	
 				SSVAL(params,0,0);
-				send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+				send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
 				return(-1);
 			} else
 				return (UNIXERROR(ERRDOS,ERRbadpath));
@@ -3894,7 +3907,7 @@
 				if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
 					/* We're done. We only get EA info in this call. */
 					SSVAL(params,0,0);
-					send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+					send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
 					return(-1);
 				}
 
@@ -3925,7 +3938,7 @@
 
 			/* We're done. We only get EA info in this call. */
 			SSVAL(params,0,0);
-			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
 			return(-1);
 		}
 
@@ -4117,7 +4130,7 @@
 			}
 
 			SSVAL(params,0,0);
-			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
 			return(-1);
 		}
 
@@ -4146,7 +4159,7 @@
 
 			/* We're done. We only get position info in this call. */
 			SSVAL(params,0,0);
-			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
 			return(-1);
 		}
 
@@ -4170,7 +4183,7 @@
 
 			/* We're done. We only get mode info in this call. */
 			SSVAL(params,0,0);
-			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
 			return(-1);
 		}
 
@@ -4285,7 +4298,7 @@
 				inherit_access_acl(conn, fname, unixmode);
 
 				SSVAL(params,0,0);
-				send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+				send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
 				return(-1);
 			}
 
@@ -4368,7 +4381,7 @@
 			if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
 				return(UNIXERROR(ERRDOS,ERRnoaccess));
 			SSVAL(params,0,0);
-			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
 			return(-1);
 		}
 
@@ -4392,7 +4405,7 @@
 			}
 
 			SSVAL(params,0,0);
-			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
 			return(-1);
 		}
 
@@ -4446,7 +4459,7 @@
 			}
 			process_pending_change_notify_queue((time_t)0);
 			SSVAL(params,0,0);
-			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
 			return(-1);
 		}
 
@@ -4497,7 +4510,7 @@
 			}
 
 			SSVAL(params,0,0);
-			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
 			return(-1);
 		}
 #endif
@@ -4603,7 +4616,7 @@
 			}
 
 			SSVAL(params,0,0);
-			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+			send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
 			return(-1);
 		}
 
@@ -4729,7 +4742,7 @@
 	}
 
 	SSVAL(params,0,0);
-	send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+	send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
   
 	return(-1);
 }
@@ -4834,7 +4847,7 @@
 
 	SSVAL(params,0,0);
 
-	send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+	send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
   
 	return(-1);
 }
@@ -4883,7 +4896,7 @@
 	if(fnf_handle == 0)
 		fnf_handle = 257;
 
-	send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
+	send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0, max_data_bytes);
   
 	return(-1);
 }
@@ -4911,7 +4924,7 @@
 	SSVAL(params,0,0); /* No changes */
 	SSVAL(params,2,0); /* No EA errors */
 
-	send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
+	send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0, max_data_bytes);
   
 	return(-1);
 }
@@ -4945,7 +4958,7 @@
 		return UNIXERROR(ERRDOS,ERRbadfile);
     
 	SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
-	send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
+	send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size, max_data_bytes);
 
 	return(-1);
 }
@@ -4983,7 +4996,7 @@
 		SSVAL(pdata,0,fsp->rap_print_jobid);                     /* Job number */
 		srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
 		srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
-		send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
+		send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32, max_data_bytes);
 		return(-1);
 	} else {
 		DEBUG(2,("Unknown TRANS2_IOCTL\n"));
Index: include/doserr.h
===================================================================
--- include/doserr.h	(revision 17496)
+++ include/doserr.h	(working copy)
@@ -44,6 +44,7 @@
 #define ERRnomem 8 /* Out of memory */
 #define ERRbadmem 9 /* Invalid memory block address */
 #define ERRbadenv 10 /* Invalid environment */
+#define ERRbadformat 11 /* Bad Format */
 #define ERRbadaccess 12 /* Invalid open mode */
 #define ERRbaddata 13 /* Invalid data (only from ioctl call) */
 #define ERRres 14 /* reserved */
@@ -60,6 +61,7 @@
 #define ERRfilexists 80 /* File in operation already exists */
 #define ERRinvalidparam 87
 #define ERRcannotopen 110 /* Cannot open the file specified */
+#define ERRbufferoverflow 111
 #define ERRinsufficientbuffer 122
 #define ERRinvalidname 123 /* Invalid name */
 #define ERRunknownlevel 124


More information about the samba-technical mailing list