在 Linux 中,malloc 给你谁的数据



当你在 Linux 中恶意移动内存时,根据规范,它不能保证为零。那么,您获得谁的数据呢?

你会得到"随便"。如果进程之前分配并释放了内存,则通常至少会部分填充旧内容。有时内存中会专门填充垃圾,以使错误更加明显。你不会得到的是其他一些进程的旧数据;这将是一个潜在的安全漏洞。

简单的答案:这是你的数据。(从你看到它的那一刻起)由你来做任何你想做的事情。

您的问题的性质是:以前是谁的数据?谁在那里写的?这不是一个容易回答的问题,因为跟踪数据已经丢失。检查数据本身可能会给您提示,但这只是猜测。

现在,怎么会呢?物理内存(逻辑上)按页面划分,MMU(内存管理单元 - CPU 的一部分)按需提供给虚拟内存中的进程。然后,流程可以用数据填充页面。当进程死亡时,其内存页将被回收为不再使用,并且当其他进程需要内存页存在于虚拟内存中时,可以自由地提供给其他进程。但是这些页面之前没有被擦干净 - 它们是按原样给出的。因此,新进程将看到前所有者设置的所有位。但是前任主人本身的所有痕迹都已经消失了......

请注意,我根本没有提到malloc()。这是因为所谓的内存分配器根本不参与此过程。 malloc()只是您的私有进程内事物,与物理级内存页面跟踪无关。请记住,所有进程都有整个可用地址空间(整个 4GB 及以上)可供使用。即使机器中没有那么多的物理内存。这就是为什么它被称为虚拟。即使您的机器中有即 32GB 的内存,也会生成 10 个进程,然后您只是用汇总的虚拟内存来检查您的物理内存。但回到malloc():你的进程需要一种方法来记住它实际使用的内存部分,哪些没有。当然,如果你的需求是静态的,你可以说这个结构在这里,那个结构就在那里。但是,当您按需创建内存结构时?这就是内存分配器库函数(通常已经在标准 C 库中)发挥作用的地方。它为您跟踪已使用的内存块,并可以为您提供指向某些未使用的内存部分的指针。但是这个(虚拟)内存已经存在了。它可能没有附加物理页面,但当您实际尝试访问它时,它会附加。

malloc()还可以将您指向进程已在使用的内存区域,并通过free()调用将其标记为不再使用。那么它仍然是您的数据。如果您正在写入该区域,则这是设置的位。

我们绕了一整圈。

malloc(3) 和 free 都与虚拟内存有关, 它们使用 mmap(2) 和 munmap(2) (也许还有sbrk) 系统调用。

但是使用这些系统调用在某种程度上是昂贵的。

因此,malloc努力重用以前free的-d内存区域(以避免进行过多的mmapmunumap系统调用),并且该内存包含任意数据(称为垃圾)。同样,free不会向内核释放内存(使用 munmap ),但请记住,您拥有的内存free -d 以后可以重用(通过 malloc )它是以前被您自己的应用程序使用(和填充)的数据。

利用Linux是自由软件的优势,研究GNU libc或MUSL libc中malloc&free的实现。

有几种可能发生的情况。

想象一个不断malloc() s和free() s的过程。

第一个malloc()开始从操作系统获得更多内存。此内存很可能填充为 0。你使用它(在其中放一些数据)并最终再次释放它。

现在可能会发生以下情况:

  • 内存位于堆的末尾,可以使用 sbrk() 释放。仅当有足够的释放量时,才会发生这种情况,因为释放在性能方面非常昂贵。堆末尾必须可用的数据量与mallopt()选项M_TRIM_THRESHOLD有关。

  • 但是,如果内存没有立即释放,而是添加到可用内存块列表中,则以后调用 malloc() 可能会返回它(或其中的一部分)。在这种情况下,您之前放在这里的数据可以从那里读出(如果这样做有任何意义的话)。

相关内容

  • 没有找到相关文章

最新更新