----- "Garrett Cooper" <[email protected]> wrote:

> On Tue, Sep 7, 2010 at 8:13 AM, Caspar Zhang <[email protected]>
> wrote:
> >
> > ----- "Garrett Cooper" <[email protected]> wrote:
> >
> >> On Tue, Sep 7, 2010 at 5:18 AM, Caspar Zhang <[email protected]>
> >> wrote:
> >> > Hi all,
> >> >  When I run testcases/network/nfs/nfsstress/ test, I found
> sometimes
> >> the
> >> > test failed due to buffered I/O, in detail, for example, there
> are
> >> the following
> >> > lines in make_tree.c :
> >> >
> >> > 544     numchar[0] = sprintf(prog_buf,
> >> > 545                 "main()\n{\n\t printf(\"hello
> world\");\n}\n");
> >> >
> >> > sometimes the generated .c file will be:
> >> > ^...@ain() // <- strange ASCII char '^@' appears instead of 'm'
> >> > {
> >> >        printf("hello world");
> >> > }
> >> >
> >> > And running with this .c file will cause error.
> >> >
> >> > That is to say, string 'prog_buf' gets a mistake during sprintf.
> And
> >> there're
> >> > somewhere else using buffered I/O in this test as well. Do we
> have
> >> an
> >> > unbuffered solution to this test?
> >>
> >> That seems a bit odd. Is the NFS mount/server TCP or UDP?
> >
> > Hi Garrett, it's UDP.
> 
>     Ok. Something else that might be good to note is whether or not
> it's v2, v3, or v4 on the client and server side.
>     Could you please try with TCP and see whether or not the issue
> persists? I'm just curious if it's a potentially real issue with NFS
> code in the kernel, random networking infrastructure issues, etc.
> Thanks,

Hi Garrett, sorry for late reply. I tried all combinations of TCP/UDP 
and v2/v3/v4 but the error still existed. I wrote a workaround patch
and re-tested with the combinations above, the issue seemed to be solved.

This patch have 2 fixes:

a) extend malloc length from 1024 to 2048. If we keep both default dir num
and file num as 100, the string length of dirname/filename length will be 
easily > 1024 bytes. This will cause string buffer overflow and the main.c 
may be filled with such wrong chars: 
'19123.97/19123.98/19123.99/19123.99.0.cmain()...'

b) add tmpdirname var in some sprintf sentences. According the man page of
sprintf:

NOTES
       Some programs imprudently rely on code such as the following
           sprintf(buf, "%s some further text", buf);
       to append text to buf.  However, the standards explicitly note
 that the results are undefined if source  and  destination buffers  
 overlap  when  calling  sprintf(),  snprintf(), vsprintf(), and 
 vsnprintf().  Depending on the version of gcc(1) used, and the 
 compiler options employed, calls such as the above will not produce 
 the expected results.

Signed-off-by: Caspar Zhang <[email protected]>

Thanks,
Caspar

-- 
Quality Assurance Associate (Kernel) in
Red Hat Software (Beijing) Co., R&D Branch

TEL: +86-10-62608150
WEB: http://www.redhat.com/
--- a/testcases/network/nfs/nfsstress/make_tree.c	2010-04-01 14:23:11.000000000 +0800
+++ b/testcases/network/nfs/nfsstress/make_tree.c	2010-09-25 00:43:37.470000001 +0800
@@ -266,13 +266,13 @@
     char	*dirname;	/* location where compile is initated         */
     char	*command;	/* make or make clean command.                */
 
-    if ((dirname = malloc(sizeof(char) * 1024)) == NULL) /* just paranoid */
+    if ((dirname = malloc(sizeof(char) * 2048)) == NULL) /* just paranoid */
     {
         perror("init_compile(): dirname malloc()");
         return 1;
     }
 
-    if ((command = malloc(1024)) == NULL) 		/* just paranoid */
+    if ((command = malloc(sizeof(char) * 1024)) == NULL) /* just paranoid */
     {
         perror("init_compile(): dirname malloc()");
         return 1;
@@ -364,23 +364,29 @@
     int		dircnt;		        /* index into directory tree          */
     int		sindex = numsdir;       /* num subdirectory tree to remove    */
     char	*dirname;		/* name of the directory to chdir()   */
+    char	*tmpdirname;		/* temp name for directory, for swap  */
     char	*filename;		/* name of the cfile to remove        */
     char	*subdir;		/* name of the sub dir to remove      */
 
-    if ((dirname = malloc(sizeof(char) * 1024)) == NULL) /* just paranoid */
+    if ((dirname = malloc(sizeof(char) * 2048)) == NULL) /* just paranoid */
     {
         perror("crte_mk_rm(): dirname malloc()");
 	return 1;
     }
     
+    if ((tmpdirname = malloc(sizeof(char) * 2048)) == NULL) /* just paranoid */
+    {
+        perror("crte_mk_rm(): tmpdirname malloc()");
+	return 1;
+    }
 
-    if ((filename = malloc(sizeof(char) * 1024)) == NULL) /* just paranoid */
+    if ((filename = malloc(sizeof(char) * 2048)) == NULL) /* just paranoid */
     {
         perror("crte_mk_rm(): filename malloc()");
 	return 1;
     }
 
-    if ((subdir = malloc(sizeof(char) * 1024)) == NULL) /* just paranoid */
+    if ((subdir = malloc(sizeof(char) * 2048)) == NULL) /* just paranoid */
     {
         perror("crte_mk_rm(): subdir malloc()");
 	return 1;
@@ -391,9 +397,16 @@
     {
         /* get the name of the last directory created. */
         for (dircnt = 0; dircnt < sindex; dircnt++)
-            (dircnt == 0) ? 
-	       sprintf(dirname, "%s/%s.%ld", base_dir, hname, gettid()) :
-               sprintf(dirname, "%s/%ld.%d", dirname, gettid(), dircnt);
+        {
+            if (dircnt == 0)
+                sprintf(dirname, "%s/%s.%ld", base_dir, hname, gettid());
+            else
+            {
+                 sprintf(tmpdirname, "%s/%ld.%d", dirname, gettid(), dircnt);
+                 sprintf(dirname, "%s", tmpdirname);
+            }
+            sync;
+        }
 
         dprt("pid[%d]: cd'ing to last created dir: %s\n", gettid(), dirname);
 
@@ -410,6 +423,7 @@
             {
                 dprt("pid[%d]: failed removing file: %s\n", gettid(), filename);
                 perror("rm_file_dir(): unlink()");
+                free(tmpdirname);
                 free(dirname);
                 free(filename);
                 free(subdir);
@@ -423,6 +437,7 @@
         if (unlink(filename))
         {
             perror("rm_file_dir() cound not remove makefile unlink()");
+            free(tmpdirname);
             free(dirname);
             free(filename);
             free(subdir);
@@ -442,6 +457,7 @@
             if (rmdir(subdir) == -1)
             {
                 perror("rm_file_dir() rmdir()");
+                free(tmpdirname);
                 free(dirname);
                 free(filename);
                 free(subdir);
@@ -451,6 +467,7 @@
         }
     }
 
+    free(tmpdirname);
     free(dirname);
     free(filename);
     free(subdir);
@@ -484,6 +501,7 @@
     int		filecnt;	/* index to the number of ".c" files created  */
     int		numchar[2];	/* number of characters written to buffer     */
     char 	*dirname;	/* name of the directory/idirectory tree      */
+    char 	*tmpdirname;	/* name of a temporary directory, for swaping */
     char	*cfilename;     /* name of the ".c" file created	      */
     char	*mkfilename;	/* name of the makefile - which is "makefile" */
     char	*hostname;	/* hostname of the client machine             */
@@ -494,19 +512,25 @@
                              (long *)args; 
     volatile int exit_val = 0;  /* exit value of the pthreads		      */
 
-    if ((dirname = malloc(sizeof(char) * 1024)) == NULL) /* just paranoid */
+    if ((dirname = malloc(sizeof(char) * 2048)) == NULL) /* just paranoid */
     {
         perror("crte_mk_rm(): dirname malloc()");
 	PTHREAD_EXIT(-1);
     }
 
-    if ((cfilename = malloc(sizeof(char) * 1024)) == NULL)
+    if ((tmpdirname = malloc(sizeof(char) * 2048)) == NULL)
+    {
+        perror("crte_mk_rm(): tmpdirname malloc()");
+	PTHREAD_EXIT(-1);
+    }
+
+    if ((cfilename = malloc(sizeof(char) * 2048)) == NULL)
     {
         perror("crte_mk_rm(): cfilename malloc()");
 	PTHREAD_EXIT(-1);
     }
 
-    if ((mkfilename = malloc(sizeof(char) * 1024)) == NULL)
+    if ((mkfilename = malloc(sizeof(char) * 2048)) == NULL)
     {
         perror("crte_mk_rm(): mkfilename malloc()");
 	PTHREAD_EXIT(-1);
@@ -547,9 +571,14 @@
     for (dircnt = 0; dircnt < (int)locargptr[0]; dircnt++)
     {
         /* First create the base directory, then create the subdirectories   */
-        (dircnt == 0) ?
-	    sprintf(dirname, "%s.%ld", hostname, gettid()):
-            sprintf(dirname, "%s/%ld.%d", dirname, gettid(), dircnt);
+        if (dircnt == 0)
+            sprintf(dirname, "%s.%ld", hostname, gettid());
+        else
+        {
+            sprintf(tmpdirname, "%s/%ld.%d", dirname, gettid(), dircnt);
+            sprintf(dirname, "%s", tmpdirname);
+        }
+        sync();
           
         dprt("pid[%d] creating directory: %s\n", gettid(), dirname); 
         if (mkdir(dirname, 0777) == -1)
@@ -563,9 +592,14 @@
     usleep(10);
     for (dircnt = 0; dircnt < (int)locargptr[0]; dircnt++)
     {
-        (dircnt == 0) ?
-	    sprintf(dirname, "%s/%s.%ld", pwd, hostname, gettid()):
-            sprintf(dirname, "%s/%ld.%d", dirname, gettid(), dircnt);
+        if (dircnt == 0)
+            sprintf(dirname, "%s/%s.%ld", pwd, hostname, gettid());
+        else
+        {
+            sprintf(tmpdirname, "%s/%ld.%d", dirname, gettid(), dircnt);
+            sprintf(dirname, "%s", tmpdirname);
+        }
+        sync();
         if ((make_buf = malloc(sizeof(char) * 4096)) == NULL)
         {
             perror("crte_mk_rm(): make_buf malloc()");
@@ -641,9 +675,14 @@
 
     for (dircnt = 0; dircnt < (int)locargptr[0]; dircnt++)
     {
-        (dircnt == 0) ?
-	    sprintf(dirname, "%s/%s.%ld", pwd, hostname, gettid()):
-            sprintf(dirname, "%s/%ld.%d", dirname, gettid(), dircnt);
+        if (dircnt == 0)
+            sprintf(dirname, "%s/%s.%ld", pwd, hostname, gettid());
+        else
+        {
+            sprintf(tmpdirname, "%s/%ld.%d", dirname, gettid(), dircnt);
+            sprintf(dirname, "%s", tmpdirname);
+        }
+        sync();
         /* In each directory create N ".c" files and a makefile. */
         for (filecnt = 0; filecnt < (int)locargptr[1]; filecnt++)
         {
------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to