Postgresql中检测内存越界或use after free的简便方法

news/2024/7/9 21:05:51 标签: 数据库, postgresql, aset, 内存越界

1 使用场景

在Postgresql的内存管理模块中,最常用的aset.c提供的内存池实现,该实现提供了两个非常实用的开关来解决常见的内存越界问题:

memdebug.c

 *	About CLOBBER_FREED_MEMORY:
 *
 *	If this symbol is defined, all freed memory is overwritten with 0x7F's.
 *	This is useful for catching places that reference already-freed memory.
 *
 *	About MEMORY_CONTEXT_CHECKING:
 *
 *	Since we usually round request sizes up to the next power of 2, there
 *	is often some unused space immediately after a requested data area.
 *	Thus, if someone makes the common error of writing past what they've
 *	requested, the problem is likely to go unnoticed ... until the day when
 *	there *isn't* any wasted space, perhaps because of different memory
 *	alignment on a new platform, or some other effect.  To catch this sort
 *	of problem, the MEMORY_CONTEXT_CHECKING option stores 0x7E just beyond
 *	the requested space whenever the request is less than the actual chunk
 *	size, and verifies that the byte is undamaged when the chunk is freed.

简单总结如下:

  • CLOBBER_FREED_MEMORY:
    • 如果定义了这个符号,所有释放的内存都会被覆盖为0x7F。这对于捕捉引用已释放内存的地方非常有用。
  • MEMORY_CONTEXT_CHECKING:
    • 由于我们通常将请求的大小舍入到下一个2的幂,所以在请求的数据区域之后通常会有一些未使用的空间。因此,如果有人犯了常见的错误,超出了他们请求的范围,问题可能会被忽视…直到更换平台后,没有这种空间未使用空间,导致内存越界使用的问题才被发现。

其实这两个宏在打开USE_ASSERT_CHECKING的使用就默认会生效。所以建议configure时记得打开enable_cassert。

/*
 * Define this to cause pfree()'d memory to be cleared immediately, to
 * facilitate catching bugs that refer to already-freed values.
 * Right now, this gets defined automatically if --enable-cassert.
 */
#ifdef USE_ASSERT_CHECKING
#define CLOBBER_FREED_MEMORY
#endif

/*
 * Define this to check memory allocation errors (scribbling on more
 * bytes than were allocated).  Right now, this gets defined
 * automatically if --enable-cassert or USE_VALGRIND.
 */
#if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND)
#define MEMORY_CONTEXT_CHECKING
#endif

2 原理

2.1 MEMORY_CONTEXT_CHECKING

下面讲讲这两宏的原理,也比较简单:

正常我们申请内存都是会向上对齐到2的幂上,比如申请5个字节实际上会分配8个字节出来,但是你只应该使用5个字节。
在这里插入图片描述
但是如果你内存越界访问到第六个字节后,实际上是不会发生任何破坏的,因为这第六个字节也没有人会用,释放时也不可能发现。这就造成了隐患(这类问题都比较难差会有奇怪的逻辑报错)。

如果打开MEMORY_CONTEXT_CHECKING宏后:

在这里插入图片描述

2.2 CLOBBER_FREED_MEMORY

还有use after free的场景,因为在pfree时,内存块中的内容不会立即被覆盖或重写,很可能发生上面已经free了,但后面还能正常用的场景,在某些串行逻辑下,貌似一直都不会出现问题,这也埋下了隐患(这类问题都比较难差会有奇怪的逻辑报错)。

打开CLOBBER_FREED_MEMORY后,释放时会调用wipe_mem将内存覆盖成0X7F

static inline void
wipe_mem(void *ptr, size_t size)
{
	VALGRIND_MAKE_MEM_UNDEFINED(ptr, size);
	memset(ptr, 0x7F, size);
	VALGRIND_MAKE_MEM_NOACCESS(ptr, size);
}

后面aset不会对0x7F做任何检查逻辑,因为没准你的数据就全是0x7F。但是memset后,肯定会将pfree的地址的数据立即覆盖掉,让后面使用者能尽早发现问题(看到一堆0x7F就知道是用了free后的地址了)。


http://www.niftyadmin.cn/n/5026485.html

相关文章

发生以下的报错怎么办?

报错问题: 解决办法: 根据你提供的代码和错误信息,问题出在使用了nullptr。这个错误是因为你的编译器不支持C11标准。 nullptr是C11引入的空指针常量。为了解决这个问题,你可以尝试以下两种方法之一: 1. 将nullptr…

Hadoop-Hive

1. hive安装部署 2. hive基础 3. hive高级查询 4. Hive函数及性能优化 1.hive安装部署 解压tar -xvf ./apache-hive-3.1.2-bin.tar.gz -C /opt/soft/ 改名mv apache-hive-3.1.2-bin/ hive312 配置环境变量:vim /etc/profile #hive export HIVE_HOME/opt/soft/hive…

通过stream流实现分页、模糊搜索、按列过滤功能

通过stream实现分页、模糊搜索、按列过滤功能 背景逻辑展示示例代码 背景 在有一些数据通过数据库查询出来后,需要经过一定的逻辑处理才进行前端展示,这时候需要在程序中进行相应的分页、模糊搜索、按列过滤了。这些功能通过普通的逻辑处理可能较为繁琐…

MinGW-W64 下载、安装与配置(支持最新版的GCC,目前 GCC 13.2.0)VSCode配置c/c++环境 彻底删除vscode(包括插件及配置!)

目录 一、简介 二、下载 1 旧版安装(8.1.0) 从 sourceforge.net 下载 2 新版安装(本次采用较新版本~~~) 从 github 下载 从 镜像站点 下载 自己编译 三、安装与配置 1. 在线安装(这里仅作参考了解) 2. 离线安装&…

【项目实战】【已开源】USB2.0 HUB 集线器的制作教程(详细步骤以及电路图解释)

写在前面 本文是一篇关于 USB2.0 HUB 集线器的制作教程,包括详细的步骤以及电路图解释。 本文记录了笔者制作 USB2.0 HUB 集线器的心路历程,希望对你有帮助。 本文以笔记形式呈现,通过搜集互联网多方资料写成,非盈利性质&#xf…

vue前后端分离单点登录,结合长token和短token进行登录

单点登录背景 在公司发展初期,公司拥有的系统不多,通常一个两个,每个系统都有自己的登录模块,运营人员每天用自己的账号登陆,很方便,但是,随着企业的发展,用到的系统随之增加&#x…

什么是MVVM模式?(含示例)

MVVM(Model-View-ViewModel)是一种软件架构模式,旨在帮助开发人员更好地组织和管理用户界面(UI)的代码。MVVM将应用程序的UI分为三个主要组件,每个组件都有其特定的责任: Model(模型…

【深度学习】 Python 和 NumPy 系列教程(十四):Matplotlib详解:1、2d绘图(下):箱线图、热力图、面积图、等高线图、极坐标图

目录 一、前言 二、实验环境 三、Matplotlib详解 1、2d绘图类型 0. 设置中文字体 1-5. 折线图、散点图、柱状图、直方图、饼图 6. 箱线图(Box Plot) 7. 热力图(Heatmap) 8. 面积图(Area Plot) 9. 等…