busybox "Memory leak freeing an array of pointers

There is an array of pointers, the elements of which pointers are all in a linked list. To free the elements, instead of freeing all the elements in the array, array[0..nelements], it frees by iterating the linked list starting at array[0], which it assumes is the head of the list. Unfortunately, if FEATURE_LS_SORTFILES is enabled, then the array is sorted. This way, array[0] is no longer the head, but somewhere in the middle of the linked list."
Bug fixed by commit 2631486f1bf
Type MemoryLeak
Config FEATURE_LS_SORTFILES && FEATURE_LS_RECURSIVE (2nd degree)
C-features Structs
Fix-in code
Location coreutils/
#include<stdio.h>
#include<stdlib.h>

struct dnode {
   int val;
   struct dnode *next;
};

#ifdef CONFIG_FEATURE_LS_RECURSIVE
void dfree(struct dnode **arr)
{
  struct dnode *cur, *next;

  if (arr == NULL)
    return;

  cur = arr[0]; // is no longer the head
  while (cur != NULL) {
    next = cur->next;
    free(cur);
    cur = next;
  }
}
#endif

void showdirs(int **arr)
{
  for (int i = 0; i < 5; ++i) {
    printf("\n%d", *arr[i]->val);
  }
  
#ifdef CONFIG_FEATURE_LS_RECURSIVE
  dfree(arr); //ERROR
#endif
}

#ifdef CONFIG_FEATURE_LS_SORTFILES
void sort(int **arr, int size)
{
  int **temp;
  int i, j;

  if (arr == NULL || size < 1)
    return;

  for(i=0;i<size;i++) {
    for(j=i;j<size;j++) {
      if(*arr[i] > *arr[j]) {
        temp=*arr[i];
        *arr[i]=*arr[j];
        *arr[j]=temp;
      }
    }
  }
}
#endif

int main(int argc, char **argv)
{
  struct dnode *curr, *head;
  int size = 5;
  struct dnode *arr[size];

  for (int i = 0; i < size; i++) {
    curr = (struct dnode *) malloc(sizeof(struct dnode));
    curr->val = rand() % 10;
    curr->next = head;
    head = curr;
    arr[(size-1)-i] = curr;
  }

  if (rand() % 2) {
#ifdef CONFIG_FEATURE_LS_SORTFILES
    sort(arr, size);
#endif
    showdirs(arr);
  }
  return 0;
}
diff --git a/simple/2631486.c b/simple/2631486.c
--- a/simple/2631486.c
+++ b/simple/2631486.c
@@ -8,18 +8,15 @@
 };
 
 #ifdef CONFIG_FEATURE_LS_RECURSIVE
-void dfree(struct dnode **arr)
+void dfree(struct dnode **arr, int nfiles)
 {
-  struct dnode *cur, *next;
 
   if (arr == NULL)
     return;
 
-  cur = arr[0]; // is no longer the head
-  while (cur != NULL) {
-    next = cur->next;
+  for (i = 0; i < nfiles; i++) {
+    struct dnode *cur = arr[i];
     free(cur);
-    cur = next;
   }
 }
 #endif
@@ -31,7 +28,7 @@
   }
   
 #ifdef CONFIG_FEATURE_LS_RECURSIVE
-  dfree(arr); //ERROR
+  dfree(arr, 5); //ERROR
 #endif
 }
 
#include<stdio.h>
#include<stdlib.h>

int main(int argc, char **argv)
{
  int size = 5;
  int *arr[size];

  for (int i = 0; i < size; i++) {
//    setArr(arr, i);
    int *p = malloc(sizeof(int));
    *p = rand() % 11;
    num[index] = p;
  }

  if (rand() % 2) {
#ifdef CONFIG_FEATURE_LS_SORTFILES
//    sort(arr, size);
    int **temp;
    int i, j;

    if (arr == NULL || size < 1)
      return;

    for(i=0;i<size;i++) {
      for(j=i;j<size;j++) {
        if(*arr[i] > *arr[j]) {
          temp=*arr[i];
          *arr[i]=*arr[j];
          *arr[j]=temp;
        }
      }
    }
#endif
//    showdirs(arr);
    for (int k = 0; k < 5; ++k) {
      printf("\n%d", *arr[k]);
    }
  
#ifdef CONFIG_FEATURE_LS_RECURSIVE
//  dfree(arr); //ERROR
    int index = 1;
    int *cur;

    cur = arr[0]; // is no longer the head

    while(i < 5) {
      free(cur);
      cur = arr[index++];
    }
#endif
  }
  return 0;
}
. 1132:dnp = dnalloc(nfiles);
. [FEATURE_LS_SORTFILES] 1157:shellsort(dnp, nfiles);
. 1159:showdirs(dnd, dndirs, dnfiles == 0);
. call coreutils/ls.c:523:showdirs(struct dnode **dn, int ndirs, int first)
.. [FEATURE_LS_RECURSIVE] 564:dfree(subdnp);
.. call coreutils/ls.c:341:dfree(struct dnode **dnp)
... ERROR 348:cur = dnp[0];