一种云平台中检测DPDK应用程序内存越界访问的方法与流程

文档序号:20700102发布日期:2020-05-12 15:34阅读:615来源:国知局
一种云平台中检测DPDK应用程序内存越界访问的方法与流程

本发明属于云计算领域,具体涉及一种云平台中检测dpdk应用程序内存越界访问的方法。



背景技术:

典型的llvm编译器包括三大部分:前端(和实际编程语言相关),后端(和实际芯片或硬件平台相关)以及中间语言ir(intermediaterepresentation)。一般来说,编译器会将源语言翻译为一种“中间语言(ir)”,之后再由中间语言,利用后端程序和设备翻译为目标平台的汇编语言。不同编译器的中间语言ir是不一样的,ir集中体现了编译器的主要特征——算法,优化方式,汇编流程等等。在llvm的架构中,pass的作用就是优化llvmir,pass作用于llvmir,用来处理ir,分析ir,寻找优化的机会并修改ir,从而产生优化的代码。

dpdk是一个linux基金会的开源项目。是在数据平面应用中为快速的数据包处理提供一个简单而完善的架构,并通过大页技术使用了自身的一套内存管理机制。因此dpdk对提高网络通信的效率起着至关重要的作用。c语言是一种非内存安全的系统编程语言,常见的内存问题就是内存越界,其危害非常大,容易产生安全漏洞,严重的时候甚至影响系统的稳定运行。为了防止这些问题的发生,在通过glibc编写的软件场景下,可以在软件编译的时候,通过asan来获取标准的glibc的内存管理函数来进行内存监控。同样类似的可以运用valgrind来检测内存。但是由于valgrind的依赖太多,同时高版本gcc支持asan内存检测,与valgrind相比asan消耗非常低,甚至可以直接在生产环境中启用asan。asan由于使用了编译时检测,所以速度更快。

在云平台中的虚拟机之间通信流量一般使用软转发,由于软转发远达不到硬件的吞吐量和时延等。为了提高软转发的高性能,所以在虚拟交换机程序上通过调用dpdk链接库来实现高性能转发。由于调用了dpdk链接的程序其内存管理由dpdk托管,但是如果虚拟交换程序出现内存污染问题,由于使用了dpdk大页内存,正常情况下的由于asan是检测标准的glibc函数,导致dpdk场景无法通过asan来检测出内存问题。



技术实现要素:

针对现有技术的以上缺陷或改进需求,本发明提供了一种云平台中检测dpdk应用程序内存越界访问的方法,其通过在dpdk链接库的内存访问指令中插入检测代码,通过截获dpdk初始化函数获取初始化的内存虚拟地址范围,利用asan的影子内存区标记所述内存虚拟地址范围;运行内存访问指令时,通过上述检测代码标记检测内存是否标记于asan的影子内存区,从而解决dpdk应用场景下无法通过asan来检测出内存问题。

为实现上述目的,按照本发明的一个方面,提供了一种云平台中检测dpdk应用程序内存越界访问的方法,包括如下步骤:

在dpdk链接库的内存访问指令中插入检测代码,以实现访问内存前核实该内存状态是否可访问;

虚拟机调用dpdk链接库对目标应用程序进行初始化时,通过截获dpdk初始化函数获取初始化的内存虚拟地址范围,利用asan的影子内存区标记所述内存虚拟地址范围;

运行内存访问指令时,通过上述检测代码标记检测内存是否标记于asan的影子内存区,内存已标记时不可访问。

作为本发明的进一步改进,在dpdk链接库的内存访问指令中插入检测代码具体为:

在目标应用程序的代码编译阶段利用编译器中间语言对asanpass进行优化。

作为本发明的进一步改进,对asanpass进行优化的具体优化方式为:

针对所述目标应用程序进行多种等价交换以生成占用存储空间更小的目标代码。

作为本发明的进一步改进,“通过截获dpdk初始化函数获取初始化的内存虚拟地址范围,利用asan的影子内存区标记该内存虚拟地址范围”具体为:

通过asan截获dpdk初始化函数rte_eal_init,以获取初始化的内存虚拟地址范围,通过asan的影子内存区将内存虚拟地址范围标记为poison。

作为本发明的进一步改进,通过截获dpdk内存管理库函数,对目标应用程序分配的内存去除在asan的影子内存区标记。

作为本发明的进一步改进,对目标应用程序分配后又释放的内存在asan的影子内存区标记。

为实现上述目的,按照本发明的另一个方面,提供了一种终端设备,包括至少一个处理单元、以及至少一个存储单元,其中,存储单元存储有计算机程序,当程序被处理单元执行时,使得处理单元执行上述方法的步骤。

一种计算机可读介质,其存储有可由终端设备执行的计算机程序,当程序在终端设备上运行时,使得终端设备执行上述方法的步骤。

总体而言,通过本发明所构思的以上技术方案与现有技术相比,具有以下有益效果:

本发明的一种云平台中检测dpdk应用程序内存越界访问的方法,其通过在dpdk链接库的内存访问指令中插入检测代码,通过截获dpdk初始化函数获取初始化的内存虚拟地址范围,利用asan的影子内存区标记所述内存虚拟地址范围;运行内存访问指令时,通过上述检测代码标记检测内存是否标记于asan的影子内存区,通过asan插桩来截获dpdk初始化内存大页的rte_eal_init函数,来获取分配的内存块。将上述asan生成的的libasan.so库中增加dpdk中特有的函数rte_malloc/rte_free等堆操作函数,当截获这些函数之后,运行在调用了dpdk的程序运行时调用这些函数出现内存污染的情况,就会发出错误报告,从而解决dpdk应用场景下无法通过asan来检测出内存问题。

附图说明

图1是本发明实施例的一种云平台中检测dpdk应用程序内存越界访问的方法的示意图。

具体实施方式

为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。

此外,下面所描述的本发明各个实施方式中所涉及到的技术特征只要彼此之间未构成冲突就可以相互组合。下面结合具体实施方式对本发明进一步详细说明。

dpdk:dataplanedevelopmentkit,数据平面开发套件。主要基于linux系统运行,用于快速数据包处理的函数库与驱动集合,可以极大提高数据处理性能和吞吐量,提高数据平面应用程序的工作效率。

gcc:gnucompilercollection,gnu编译器套件。由gnu开发的编程语言译器。gnu编译器套件包括c、c++、objective-c、fortran、java、ada和go语言前端,也包括了这些语言的库(如libstdc++,libgcj等)。

asan:addresssanitizer,是google用于检测内存各种bufferoverflow(heapbufferoverflow,stackbufferoverflow,globalbufferoverflow)的一个非常有用的工具。

llvm:构架编译器(compiler)的框架系统,以c++编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本。

ir:编译器中间语言。

图1是本发明实施例的一种云平台中检测dpdk应用程序内存越界访问的方法的示意图。如图1所示,一种云平台中检测dpdk应用程序内存越界访问的方法,其包括如下步骤:

在dpdk链接库的内存访问指令中插入检测代码,以实现访问内存前核实该内存状态是否可访问;

作为一个优选的实施例,在dpdk链接库的内存访问指令中插入检测代码具体为:可在目标应用程序的代码编译阶段(即将目标应用程序转换为可执行文件的过程),利用编译器中间语言(ir)对asanpass进行优化,作为一个示例,具体优化方式为,针对目标应用程序进行多种等价交换以生成占用存储空间更小的目标代码,从而使得目标代码占用空间更小,运行时间更短。作为一个示例,该方案可在llvm或gcc构架中实现。

虚拟机调用dpdk链接库对目标应用程序进行初始化时,通过截获dpdk初始化函数获取初始化的内存虚拟地址范围,利用asan的影子内存区标记该内存虚拟地址范围;asan通过影子映射来记录内存状态,追踪受限的内存,验证其合法性。它在进程相应的内存区域固定保存了一个“影子内存区”,影子区通过记录每个字节的状态,可以知道哪些字节被破坏了。影子映射是通过一个简单的规则,即正常内存块每八个字节映射到影子内存的一个字节,那么这个字节就可以追踪八个字节的状态。asan在编译或运行时程序插入额外的代码来检查内存的读写操作,一旦发现内存污染就抛出错误,并发送错误报告。

作为一个优选的实施例,dpdk的场景下,在插桩的时候,通过asan增加dpdk的初始化函数rte_eal_init的插桩,以检测这个程序中调用这个函数时候的内存状态,可通过asan截获dpdk初始化函数rte_eal_init,以获取初始化的内存虚拟地址范围,通过asan的影子内存区将该内存虚拟地址范围标记为poison。rte_eal_init是调用dpdk库的一个初始化函数,里面包含了大页内存的初始地址,通过这个挂载大页路径,以及mmap来生成目标程序的堆栈地址。通过截获该函数可以获取初始化的大页内存虚拟地址范围,然后标记poison该段地址。

作为进一步的优选,目标应用程序运行时,通过截获dpdk内存管理库函数,对该目标应用程序分配的内存去除在asan的影子内存区标记;进一步地,对该目标应用程序分配后又释放的内存在asan的影子内存区标记;具体地,在程序运行的时候,通过asan的libasan.so库增加dpdk只有的库来截获dpdk内存管理库函数rte_malloc_socket,rte_free等,并unpoison分配的内存和posion释放的内存,使得asan可以监控调用dpdk链接库的程序。

运行内存访问指令时,通过上述检测代码标记检测内存是否标记于asan的影子内存区,内存已标记时不可访问。具体地,在目标应用程序运行内存访问指令时候,根据内存访问指令中插桩的指令,在进行访问内存写的时候,由于内存污染该段内存已被使用(shadow内存)不可访问,这时候如果进行访问,那么程序报错并退出,提示具体出错信息。

asan主要包括两部分:插桩(instrumentation)和动态运行库(run-timelibrary)。asan的内存检测原理之一是在编译时插桩,在编译时候回插入检测代码,以检测每个内存访问的影子状态,asan会在局部数组、局部变量、全局变量前后填充特定字段,然后再程序运行过程中,asan会对这些特定字段进行检查,确定是否发生越界。为了检测对全局和栈对象的超出访问,asan必须在这些对象周围创建毒性区域(redzone)。asan的内存检测原理之二是运行时库,asan工具提供了一个运行库,它存在于libasan.so动态库中,运行时,会对glibc的29个函数进行替换一遍检测内存错误。在应用启动时预加载该动态库,替换libc.so标准库,重新实现了malloc/free,memcpy/memset和相关函数增加越界判断。如果发现了操作长度超过了申请内存的范围就会立即进行错误报告。运行时库的主要目的就是管理影子内存。在应用程序启动时候,映射整个阴影区域,以便程序的其他部分不能使用它,影子内存被bad段保护。在动态运行库中,dpdk未使用标准的libc.so库,而是使用了本身自带的rte_malloc以及rte_free等库函数,所以asan无法使用在dpdk的场景下的程序。通过asan插桩来截获dpdk初始化内存大页的rte_eal_init函数,来获取分配的内存块。将上述asan生成的的libasan.so库中增加dpdk中特有的函数rte_malloc/rte_free等堆操作函数。所以当截获这些函数之后,当运行在调用了dpdk的程序运行时调用这些函数出现内存污染的情况,就会发出错误报告。

一种终端设备,包括至少一个处理单元、以及至少一个存储单元,其中,存储单元存储有计算机程序,当程序被处理单元执行时,使得处理单元执行上述方法的步骤。

一种计算机可读介质,其存储有可由终端设备执行的计算机程序,当程序在终端设备上运行时,使得终端设备执行上述方法的步骤。

本领域的技术人员容易理解,以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1