busybox The pointer 'ch' is referenced after being freed if FEATURE_CLEAN_UP is enabled. If FEATURE_CLEAN_UP is defined, then delete_eth_table() frees the previously allocated memory for the pointer 'ch'. However, after that (in a for loop), a statement 'ch->next' dereferences already freed memory.

Bug fixed by commit bc0ffc0e971
Type UseAfterFree
Config FEATURE_CLEAN_UP (1st degree)
C-features Structs
Fix-in code
Location networking/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define IFNAMSIZ 16

typedef struct ethtable_s {
  struct ethtable_s *next;
  char *ifname;
} ethtable_t;

#ifdef ENABLE_FEATURE_CLEAN_UP
static void delete_eth_table(ethtable_t *ch)
{
  free(ch->ifname);
  free(ch);
};
#else
void delete_eth_table(ethtable_t *ch)
{
}
#endif

static void prepend_new_eth_table(ethtable_t **clist, char *ifname)
{
  ethtable_t *ch;
  if (strlen(ifname) >= IFNAMSIZ)
    printf("interface name '%s' too long", ifname);
  ch = malloc(sizeof(*ch));
  ch->ifname = ifname;
  ch->next = *clist;
  *clist = ch;
}

int main(int argc, char** argv)
{
  ethtable_t *clist = NULL;
  ethtable_t *ch;
  
  prepend_new_eth_table(&clist, argv[0]);
  
#ifdef ENABLE_FEATURE_CLEAN_UP
  for (ch = clist; ch; ch = ch->next) // ERROR
    delete_eth_table(ch);
#endif
  return 0;
}
diff --git a/simple/bc0ffc0.c b/simple/bc0ffc0.c
--- a/simple/bc0ffc0.c
+++ b/simple/bc0ffc0.c
@@ -39,8 +39,11 @@
   prepend_new_eth_table(&clist, argv[0]);
   
 #ifdef ENABLE_FEATURE_CLEAN_UP
-  for (ch = clist; ch; ch = ch->next) // ERROR
+  ethtable_t *next;
+  for (ch = clist; ch; ch = next) { // ERROR
+    next = ch->next;
     delete_eth_table(ch);
+  }  
 #endif
   return 0;
 }
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define IFNAMSIZ 16

typedef struct ethtable_s {
  struct ethtable_s *next;
  char *ifname;
} ethtable_t;

int main(int argc, char** argv)
{
  ethtable_t *clist = NULL;
  ethtable_t *ch;
  
//  prepend_new_eth_table(&clist, argv[0]);
  if (strlen(ifname) >= IFNAMSIZ)
    printf("interface name '%s' too long", ifname);
  ch = malloc(sizeof(*ch));
  ch->ifname = ifname;
  ch->next = *clist;
  *clist = ch;
  
#ifdef ENABLE_FEATURE_CLEAN_UP
  for (ch = clist; ch; ch = ch->next) { // ERROR
//    delete_eth_table(ch);
    free(ch->ifname);
    free(ch);
  }
#else

#endif
  return 0;
}
. call networking/nameif.c:240:prepend_new_eth_table()
.. 194:ch = xzalloc(sizeof(*ch));
. [FEATURE_CLEAN_UP] call networking/nameif.c:319:delete_eth_table()
.. [FEATURE_CLEAN_UP] 212:free(ch);
. ERROR [FEATURE_CLEAN_UP] 318:ch = ch->next;