Client stuck in an "infinite" loop due to illegal character in name

Jeremy Allison jra at samba.org
Wed Jul 18 01:13:25 GMT 2007


On Mon, Jul 16, 2007 at 10:33:25AM +0300, Shlomi Yaakobovich wrote:
> Hi,
> 
> We're running samba 3.0.20, and we've seen some strange behavior. In our
> configuration, mangling is disabled. The client is in the process of
> reading a directory (i.e. opening an explorer window). If the last file
> returned to the client contains an illegal character (and not just a
> plain illegal, it is below 31 ASCII value), then the resume_name is
> transformed into the "." name, and rewinddir is called. This causes the
> file names from the beginning of the directory to be sent over and over
> again to the client, in what seems like an infinite loop. The client (I
> used Windows XP) does not seem to recover from this or fail, it is just
> showing an empty window with the flashlight sign (browsing...)
> 
> The relevant code of samba that does this is at reply.c - and from the
> latest samba code it seems the check_path_syntax_internal function also
> contains the same issue:
> 	
> 		if (!(*s & 0x80)) {
> 			if (!posix_path) {
> 				if (*s <= 0x1f) {
> 					return
> NT_STATUS_OBJECT_NAME_INVALID;
> 				}
> 
> This seems like too trivial to be overlooked. Could it be that we've
> done something wrong ?  If not, what would be the correct solution for
> this ?

Try this patch against 3.0.25b.

Thanks,

	Jeremy.
-------------- next part --------------
Index: smbd/trans2.c
===================================================================
--- smbd/trans2.c	(revision 23936)
+++ smbd/trans2.c	(working copy)
@@ -1999,10 +1999,14 @@
 		   complain (it thinks we're asking for the directory above the shared
 		   path or an invalid name). Catch this as the resume name is only compared, never used in
 		   a file access. JRA. */
-		if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) {
+		size_t ret = srvstr_pull(inbuf, resume_name, params+12,
+					sizeof(resume_name), total_params - 12,
+					STR_TERMINATE);
+
+		if (ret == 2 && ISDOT(resume_name)) {
+			pstrcpy(resume_name, ".");
+		} else if (ret == 3 && ISDOTDOT(resume_name)) {
 			pstrcpy(resume_name, "..");
-		} else if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_NAME_INVALID)) {
-			pstrcpy(resume_name, ".");
 		} else {
 			return ERROR_NT(ntstatus);
 		}


More information about the samba-technical mailing list