diff --git a/ChangeLog b/ChangeLog
index 7a6e935f08f73bab14d1f70fae96d1d4df3b11b6..adf20a906dc64871ffd6ae03c5ba1b6010c09aa3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -190,5 +190,7 @@
 	  on thread/task exit.
 	* Add environment variables APIs:  environ, getenv, putenv, clearenv, setenv,
 	  unsetenv
+	* Correct an error in realloc() when the block is extended "down" in memory.
+	  In this case, the old memory contents need to be copied to the new location.
 	* Started m68322
 
diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html
index 0aa964dc90b6b79a0aa348690920598747eaf5c2..e19cf3d0d30c24e7977549b5ad1e785155923fc9 100644
--- a/Documentation/NuttX.html
+++ b/Documentation/NuttX.html
@@ -627,6 +627,8 @@ Other memory:
 	  unsetenv
 	* Add environment variables APIs:  environ, getenv, putenv, clearenv, setenv,
 	  unsetenv
+	* Correct an error in realloc() when the block is extended "down" in memory.
+	  In this case, the old memory contents need to be copied to the new location.
 	* Started m68322
 </pre></ul>
 
diff --git a/mm/mm_realloc.c b/mm/mm_realloc.c
index 52dd56bb7d8f9e557cc23751f3ba604b2f2b5fe1..e7d07d65b7ee72fac605104eecf641a22b5887a1 100644
--- a/mm/mm_realloc.c
+++ b/mm/mm_realloc.c
@@ -81,6 +81,7 @@ FAR void *realloc(FAR void *oldmem, size_t size)
   size_t oldsize;
   size_t prevsize = 0;
   size_t nextsize = 0;
+  FAR void *newmem;
 
   /* If oldmem is NULL, then realloc is equivalent to malloc */
 
@@ -261,64 +262,67 @@ FAR void *realloc(FAR void *oldmem, size_t size)
 
       if (takenext)
         {
-           FAR struct mm_freenode_s *newnode;
-           FAR struct mm_allocnode_s *andbeyond;
+          FAR struct mm_freenode_s *newnode;
+          FAR struct mm_allocnode_s *andbeyond;
 
-           /* Get the chunk following the next node (which could be the tail chunk) */
+          /* Get the chunk following the next node (which could be the tail chunk) */
 
-           andbeyond = (FAR struct mm_allocnode_s*)((char*)next + nextsize);
+          andbeyond = (FAR struct mm_allocnode_s*)((char*)next + nextsize);
 
-           /* Remove the next node.  There must be a predecessor,
-            * but there may not be a successor node.
-            */
+          /* Remove the next node.  There must be a predecessor,
+           * but there may not be a successor node.
+           */
 
-           DEBUGASSERT(next->blink);
-           next->blink->flink = next->flink;
-           if (next->flink)
-             {
-               next->flink->blink = next->blink;
-             }
+          DEBUGASSERT(next->blink);
+          next->blink->flink = next->flink;
+          if (next->flink)
+            {
+              next->flink->blink = next->blink;
+            }
 
-           /* Extend the node into the previous next chunk */
+          /* Extend the node into the next chunk */
 
-           oldnode->size = oldsize + takenext;
-           newnode       = (FAR struct mm_freenode_s *)((char*)oldnode + oldnode->size);
+          oldnode->size = oldsize + takenext;
+          newnode       = (FAR struct mm_freenode_s *)((char*)oldnode + oldnode->size);
 
-           /* Did we consume the entire preceding chunk? */
+          /* Did we consume the entire preceding chunk? */
 
-           if (takenext < nextsize)
-             {
-               /* No, take what we need from the next chunk and return it
-                * to the free nodelist.
-                */
+          if (takenext < nextsize)
+            {
+              /* No, take what we need from the next chunk and return it
+               * to the free nodelist.
+               */
 
-               newnode->size        = nextsize - takenext;
-               newnode->preceding   = oldnode->size;
-               andbeyond->preceding = newnode->size | (andbeyond->preceding & MM_ALLOC_BIT);
+              newnode->size        = nextsize - takenext;
+              newnode->preceding   = oldnode->size;
+              andbeyond->preceding = newnode->size | (andbeyond->preceding & MM_ALLOC_BIT);
 
-               /* Add the new free node to the nodelist (with the new size) */
+              /* Add the new free node to the nodelist (with the new size) */
 
-               mm_addfreechunk(newnode);
-             }
-           else
-             {
-               /* Yes, just update some pointers. */
+              mm_addfreechunk(newnode);
+            }
+          else
+            {
+              /* Yes, just update some pointers. */
 
-               andbeyond->preceding = oldnode->size | (andbeyond->preceding & MM_ALLOC_BIT);
-             }
+              andbeyond->preceding = oldnode->size | (andbeyond->preceding & MM_ALLOC_BIT);
+            }
         }
 
+      /* Now we have to move the user contents 'down' in memory.  memcpy should
+       * should be save for this.
+       */
 
+      newmem = (FAR void*)((FAR char*)oldnode + SIZEOF_MM_ALLOCNODE);
+      memcpy(newmem, oldmem, oldsize - SIZEOF_MM_ALLOCNODE);
       mm_givesemaphore();
-      return (FAR void*)((FAR char*)oldnode + SIZEOF_MM_ALLOCNODE);
+      return newmem;
     }
 
   /* The current chunk cannot be extended.  Just allocate a new chunk and copy */
 
   else
     {
-       FAR void *newmem;
-
        /* Allocate a new block.  On failure, realloc must return NULL but
         * leave the original memory in place.
         */