是否有一个 malloc 变体可以在调用“free()”时将块归零



我想在系统范围内替换标准的malloc(通过LD_PRELOAD或只是替换已安装的libc),将其归零释放块中所有可能的内容。有谁知道现有的解决方案?

在堆的未使用部分具有零将使通过 zram-config 压缩它更加有效。由于我比 CPU 更需要 RAM,因此增加 CPU 使用率不是问题。

您可以修改系统上的 C 库。我不认为你会发现一个修改过的 C 库完全以这种方式进行内存分配,因为它是非标准的。但是修改听起来相对容易。看看你的 C 库的实现,你可以用一个做 free+memset 的包装器代替 free 的实现,而不仅仅是 free。

以防万一有人遇到类似的问题,下面是 eglibc 2.17 的补丁。

--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1424,10 +1424,16 @@
 #define first(b)     ((b)->fd)
 #define last(b)      ((b)->bk)
+#define zero_sizes(P) {                                                
+    P->size = 0;                                                        
+    P->prev_size = 0;                                                   
+}
+
 /* Take a chunk off a bin list */
 #define unlink(P, BK, FD) {                                            
   FD = P->fd;                                                          
   BK = P->bk;                                                          
+  P->bk = 0; P->fd = 0; 
   if (__builtin_expect (FD->bk != P || BK->fd != P, 0))                
     malloc_printerr (check_action, "corrupted double-linked list", P); 
   else {                                                               
@@ -1449,9 +1455,11 @@
       } else {                                                         
         P->fd_nextsize->bk_nextsize = P->bk_nextsize;                       
         P->bk_nextsize->fd_nextsize = P->fd_nextsize;                       
       }                                                                
+      P->fd_nextsize = 0;                                               
+      P->bk_nextsize = 0;                                               
     }                                                                  
   }                                                                    
 }
 /*
@@ -1878,8 +1886,10 @@
 static int perturb_byte;
-#define alloc_perturb(p, n) memset (p, (perturb_byte ^ 0xff) & 0xff, n)
-#define free_perturb(p, n) memset (p, perturb_byte & 0xff, n)
+#define alloc_perturb(p, n) do {} while(0)
+#define free_perturb(p, n) memset (p, 0, n)

 /* ------------------- Support for multiple arenas -------------------- */
@@ -3809,8 +3819,7 @@
       }
     }
-    if (__builtin_expect (perturb_byte, 0))
-      free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
+    free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
     set_fastchunks(av);
     unsigned int idx = fastbin_index(size);
@@ -3892,13 +3901,13 @@
       goto errout;
     }
-    if (__builtin_expect (perturb_byte, 0))
-      free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
+    free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
     /* consolidate backward */
     if (!prev_inuse(p)) {
       prevsize = p->prev_size;
       size += prevsize;
+      unlink_free(p);
       p = chunk_at_offset(p, -((long) prevsize));
       unlink(p, bck, fwd);
     }
@@ -3910,6 +3921,7 @@
       /* consolidate forward */
       if (!nextinuse) {
         unlink(nextchunk, bck, fwd);
+        zero_sizes(nextchunk);
         size += nextsize;
       } else
    clear_inuse_bit_at_offset(nextchunk, 0);
@@ -4069,6 +4081,7 @@
      if (!prev_inuse(p)) {
        prevsize = p->prev_size;
        size += prevsize;
+       zero_sizes(p);
        p = chunk_at_offset(p, -((long) prevsize));
        unlink(p, bck, fwd);
      }
@@ -4079,6 +4092,7 @@
        if (!nextinuse) {
          size += nextsize;
          unlink(nextchunk, bck, fwd);
+         zero_sizes(nextchunk);
        } else
          clear_inuse_bit_at_offset(nextchunk, 0);

为什么不编写自己的free_zero函数呢?

void free_zero(void *p, size_t n)
{
   volatile unsigned char *zp = p;
   if (!p) return;
   while (n--)
   {
       *zp++ = 0;
   }
   free(p);
}

最新更新