CN110989997A - 基于定理证明的形式化验证方法 - Google Patents
基于定理证明的形式化验证方法 Download PDFInfo
- Publication number
- CN110989997A CN110989997A CN201911225125.3A CN201911225125A CN110989997A CN 110989997 A CN110989997 A CN 110989997A CN 201911225125 A CN201911225125 A CN 201911225125A CN 110989997 A CN110989997 A CN 110989997A
- Authority
- CN
- China
- Prior art keywords
- function
- theorem
- proof
- formal
- variable
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/30—Creation or generation of source code
- G06F8/31—Programming languages or programming paradigms
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Computing Systems (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Devices For Executing Special Programs (AREA)
Abstract
本发明公开一种基于定理证明的形式化验证方法,应用于安全操作***领域,针对现有的操作***存在的安全性问题,本发明基于定理证明的形式化验证方法,包括:对源代码重构、对函数进行形式化建模、对函数进行定理描述、最后进行形式化证明;本发明采用人机交互的半自动化证明,利用类型***和逻辑之间的同构关系,将构造证明的过程转化为编写程序的过程,而证明的正确性检查也变成了类型检查问题,尽管需要大量手工劳动来构造证明,但是本发明提出的方法无需牺牲规约和代码的表达能力,特别是程序中可以使用表达能力很强的逻辑来表示,且证明自身在机器中都有显示表示,其正确性可以被自动检查,验证的结论也就更加可信。
Description
技术领域
本发明属于计算机操作***领域,特别涉及一种安全操作***的形式化验证技术。
背景技术
1946年,世界上诞生了第一台电子数字式计算机,该计算机即ENIAC,ENIAC的出现奠定了电子计算机的发展基础,同时,这也是第一代电子管计算机的诞生标志,之后,随着晶体管技术、大小规模集成电路以及超大规模集成电路的发展,计算机又经历了几次更新换代过程,从第二代的晶体管计算机发展为了现在的***大规模集成电路计算机。直到目前为止,计算机仍然在不断地发展,从实际应用的角度出发,向着微型化以及智能化等多个方向在不断地前进。并且,伴随着互联网的发展,计算机更是变得无处不在,小到人们生活中使用的手机、电脑、以及家电等,大到航空航天***、核电能源***、以及导弹发射等军用***,计算机的功能正在变得日益强大,其所带来的影响也是极其巨大的。
在接受由计算机和互联网的飞速发展所带来的便利的同时,我们又不得不承受与之而来的危害,正是由于计算机***的无处不在,因此,一旦这些***出现问题,我们将在第一时间感受到他们所带来的切身危害。比如,2017年在150多个国家和地区肆虐的比特币勒索病毒“WannaCry”,其利用了Windows安全漏洞“EternalBlue”,通过邮件、程序木马等多种方式传播,对许多行业造成了严重危害,最终造成损失高达80亿美元。而去年区块链行业中BEC合约平台所爆出的整型溢出攻击漏洞则是因为源代码中未采用Safemath库进行约束,导致溢出问题绕过代码检查,造成了数以万计的代币流失,最终损失数十亿美元。上述介绍的安全攻击每次出现所带来的后果都非常严重。当然,针对这些威胁,相关机构及人士也提出了很多的应对办法,比如及时发布漏洞补丁、更新病毒库、以及各种杀毒软件等,但是诸如此类的方法都无法从根本上解决问题,通常都是在危险事件已经发生后才能提出应对的方法,因此,为了从根本上解决这些安全问题,必须从操作***本身的角度去考虑,提高操作***本身的安全性以应对诸多未知的安全威胁,其根本问题是如何去开发一个安全可靠的软硬件***。
根据CCF中国计算机科学技术发展报告,形式化方法越来越受到国际国内计算机学术界重视。形式化方法已经被许多国际标准化组织列为安全有关***必备的技术手段。在软件安全等级的SIL1-4中,安全级别最高的SIL3和SIL4要求必须使用形式化方法。而在IT产业界,微软开发了一系列形式化验证工具来对众多软件的正确性分析;Facebook将给予分离逻辑的验证工具Infer广泛用于其Android应用的开发过程中;国内的华为公司成立形式化验证团队,使用定理证明辅助工具验证操作***内核正确性和安全性等。
近些年来,对于实际***进行代码级的形式化证明主要分为操作***内核验证和编译器验证。操作***内核验证的工作有seL4微内核的形式化证明,这是由国外NICTA工作室完成的,主要通过构建机器模型,证明抽象规范每一步的状态变换,可执行规范都会产生唯一对应状态转换。经过形式化证明的seL4内核可以针对缓冲区溢出、引用空指针、指针类型错误以及内存泄漏等问题进行有效防御,国内方面主要是中科大团队对μC/OS-Ⅱ的验证。在编译器方面,最出名的便是INRIA对CompCert的证明以及后续工作。该编译器提供了数学上的、经过机器检查的证明,即证明生成的可执行代码的行为完全符合源程序的语义规定。经过该编译器编译的C代码可以排除编译器引入错误的可能性。也就是说该编译器生成的可执行代码被证明与源代码C程序的语义所指定行为完全一致。
发明内容
为解决上述技术问题,本发明采用基于定理证明的形式化验证方法,从根本上解决了安全***所存在的危险事件问题。
本发明采用的技术方案为:基于定理证明的形式化验证方法,包括:对源代码重构、对函数进行形式化建模、对函数进行定理描述、最后进行形式化证明;
所述对源代码重构,具体为:
A1、整理函数的调用关系,并将证明函数中调用的所有函数及数据类型导入到一个文件夹中;
A2、对函数中不能被CompCert C编译器识别或者转换不完善的数据类型进行重构;
A3、对代码中复杂的结构进行分离操作;
A4、删去代码中不影响函数逻辑及变量状态的函数;
所述对函数进行形式化建模,具体为:通过CompCert C编译器和VST工具自动对函数进行形式化建模;
对函数进行定理描述,具体为:所述定理采用Hoare逻辑结构表示,得到的形式化描述的定理能够反映函数执行前与执行后的各部分状态变化;
所述定理证明,具体为:使用证明策略对形式化描述的定理进行推导证明。
进一步地,所述形式化描述的定理满足VST的规范。
更进一步地,所述对函数进行定理描述的过程为:
A1、通过DECLARE将该定理描述与原函数形式化模型绑定,后接函数形式化模型名字;
A2、采用WITH语句列举出整个函数执行过程中可能出现的变量,同时规定其类型;
A3、前置条件,内部结构为“PROP()LOCAL()SEP()”,PROP()表示表示函数执行之前所要满足的约束条件;LOCAL()表示函数执行前必须具有的局部变量或者全局变量;SEP()是一个空间谓词,表示函数执行前,某操作变量地址上的实际初始值情况;
A4、后置条件,内部结构为“PROP‘()LOCAL‘()SEP’()”,PROP‘()表示表示函数执行之后所要满足的约束条件;LOCAL‘()表示表示函数的返回值;SEP’()是一个空间谓词,表示函数执行后,函数胡执行后某操作变量地址上上的具体值情况。
进一步地,所述证明策略包括:rewrite改写策略、apply策略、forward策略以及entailer策略,所述rewrite改写策略将当前目标中的目标变量替换为前提中的要求变量;所述apply策略将当前目标中的目标变量替换为前提中的要求变量,并对证明目标进行化简;所述forward策略用于推动Hoare逻辑证明的正向执;所述entailer策略用来完成对于蕴含语句的推导工作。
本发明的有益效果:本发明提出的基于定理证明的形式化验证方法,采用人机交互的半自动化证明,利用类型***和逻辑之间的同构关系,将构造证明的过程转化为编写程序的过程,而证明的正确性检查也变成了类型检查问题,尽管需要大量手工劳动来构造证明,但是本发明提出的方法无需牺牲规约和代码的表达能力,特别是程序中可以使用表达能力很强的逻辑来表示,且证明自身在机器中都有显示表示,其正确性可以被自动检查,因此本发明无需依赖自动定理证明算法的正确性,验证的结论也就更加可信。
附图说明
图1为本发明实施例提供的形式化证明过程模块图;
图2为本发明实施例提供的定理描述过程结构示意图。
具体实施方式
为便于本领域技术人员理解本发明的技术内容,下面结合附图1-2对本发明内容进一步阐释。
形式化方法最显著的作用是能够对形式规约进行验证.形式验证常见的有两种形式:一种是推理“***模型规约是否满足其性质规约”,这时,模型规约偏向操作型,性质往往是说明型的;另一种是推理“***的一个模型规约是否与另一模型规约有精化或等价关系”。这些推理过程给出了一套静态方法来预测***的行为:用户可以描述***行为的所期望性质或者开发过程中不同抽象之间关系的猜想,形式验证通过机械化的方式来证实或者证伪这个性质或者猜想,从而提高用户对规约和***的可信程度.形式验证方法主要包括算法式的模型检测和演绎式的定理证明。
1模型检测
模型检测就是用形式化方法精确地证明一个***能够按照预定目标正确工作。模型检测技术是一种有限状态反应式***的自动检验技术。模型检测的主要思想是首先将给定的***和***属性分别用有穷状态模型描述出来,然后采用高效搜索程序(模型检测器)来判断***模型是否满足原先的设计需求(***属性)。为了确保搜索的终止性,模型的状态空间通常会被限制为有穷。在模型检测中,可以使用各种形式化规范语言作为建模语言,而一般使用时序逻辑作为性质描述语言。模型检测是一种自动化的验证方法,能够在模型不满足性质时。给出反例,便于定位和修改模型。但是模型检测存在状态空间***问题,因此它会可能存在未能检测出的***缺陷,并不能证明***是完全正确的。
2定理证明
定理证明方法能够处理无限制状态空间问题,因此克服了状态空间***问题。基于定理证明的形式化验证将“***满足其规约”这一论断作为逻辑命题,通过一组的推理规则,以演绎推理的方式对该命题开展证明,基于定理证明的验证大部分是以程序逻辑为理论基础的,但是程序逻辑并非唯一的证明方法,例如,可以基于程序的操作予以直接表达程序执行的安全性、正确性等各种性质并证明相关定理。
按照证明方式和自动化程度的不同,基于定理证明的验证***可以分为自动定理证明器的自动验证和人机交互的半自动验证。
2.1基于自动定理证明器的自动验证
基于自动定理证明的证明的目前常见的程序证明器包括why3、smallfoot等,大多都是基于某种具体的程序逻辑,给定程序及其规约,证明器能够自动决定针对程序的每条语句使用程序逻辑中的何种公理或规则,并产生相应的验证条件作为证明义务.最终,产生的验证条件被送到自动定理证明器中,由定理证明器完成对验证条件的证明。
这种基于自动定理证明的验证工作有点在于验证的效率较高,不需要人手工写证明.然而,由于自动定理证明中很多问题是不可判定问题,而且各个定理证明器又有各自的能力限制,因此能够表达和证明的性质有限。为了能够实现自动证明,很多时候需要对待证明的性质和待验证的代码本身都进行重写,甚至为了迁就验证的自动化而牺牲待验证的性质以及代码的功能,因此这种方法并不适合我们本次验证工作。
2.2人机交互的半自动化证明
基于定理证明的另一类验证工作,则不强调使用计算机实现验证的自动化,而是利用计算机来解决证明在计算机中的表示问题以及自动检查证明的正确性的问题,证明的构造则由人手工和机器交互,以半自动化的方式完成.很多辅助定理证明工具,例如本次证明工作使用的Coq,这类工具往往都是利用类型***和逻辑之间的同构关系,将构造证明的过程转化为编写程序的过程,而证明的正确性检查也变成了类型检查问题。
半自动化验证工作尽管需要大量手工劳动来构造证明,但是这种方法无需牺牲规约和代码的表达能力,特别是程序中可以使用表达能力很强的逻辑来表示,且证明自身在机器中都有显示表示,其正确性可以被自动检查,因此无需依赖自动定理证明算法的正确性,验证的结论也就更加可信。
本发明采用的证明方法为半自动的定理证明方法,主要使用到了CompCert C编译器,VST工具以及Coq辅助定理证明工具:
CompCert C编译器是由法国INRIA研究所完成的经过形式化证明的编译器。该编译器提供了数学上的、经过机器检查的证明,即证明生成的可执行代码的行为完全符合源程序的语义规定。经过该编译器编译的C代码可以排除编译器引入错误的可能性。也就是说该编译器生成的可执行代码被证明与源代码C程序的语义所指定行为完全一致。
CompCert C编译器架构一共包括3个部分:
第一部分可以对代码进行解析、类型检查以及预处理,即将C代码转换为CompCertC语言的抽象语法树。在这部分中,一些不被CompCert C编译器支持的结构被扩展,例如块作用域的局部变量会被重命名并且提升到函数的局部范围等,但是还有一些不被支持的结构,例如变量函数声明是被拒绝的。这一部分是没有进行形式化证明的,但是因为Compecert C就相当于C的子集,因此编译器可以根据C语言具体语法输出生成CompCert C代码,所以可以人为检查这部分转换结果。另外,大多数用于C静态分析和程序验证的工具都使用类似于CompCert C简化C语言运行,通过直接在CompCert C表单上进行分析或者程序验证,就可以检测到这一部分架构可能引入的错误。
第二部分为将CompCert C语法树转换为汇编语法树,这一部分在Coq工具中被证明是正确的。它由16个通道构成,并使用了10种中间语言。
第二部分所有中间语言都被赋予了形式语义,并且每个转换过程都被证明保留了语义。
第三部分为组装和链接,即将第二部分所生成的汇编语言抽象语法树以具体汇编语法打印,然后调用***汇编工具以及链接器分别生成目标文件和可执行文件。
VST实质是一套工具链,里面包括检查程序断言的静态分析工具、将程序编译为机器语言的优化编译器、为程序验证提供环境的语义***与库。这一套经过证明的工具链能够确保当运行于操作***上下文中时,在工具链顶部声明的断言在机器语言程序中确实成立。使用该工具链去验证C程序又被称为Verifiable C,Verifiable C是一种用于对C程序功能正确性进行推理的语言和程序逻辑,这种语言是Compcert C light的一个子类。是一种C语言的抽象描述,将C语言中的其他意义以及负载的含义从表达式中分离出来。这种程序逻辑是一种高阶分离逻辑,即Hoare逻辑,能够较好地支持指针数据结构、函数指针和数据抽象的推理。
Coq是一个形式化证明管理***,它设计的目的就是开发数学证明,特别是书写形式化规约、程序以及去证明程序在这些规约方面是正确的。它提供了一种名为“Gallina”的规范语言,这种语言可以用来表示程序结构,以及程序属性,还有对程序的证明过程。这种语言库中所有的逻辑判断都被归纳为类型判断,证明的正确性是通过类型检查算法来推导证明,这也是整个***的核心。另外,为了方便人机交互,Coq提供了一种交互式定理证明辅助工具Coqide,所谓交互式定理证明即通过用户和计算机相互协助完成形式化证明。对不同程序的证明都可以使用该工具来构建证明过程。
如图1所示,本发明的方法包括以下四个步骤:
1、代码重构操作
因为我们的形式化工具对于C语言中的一些语法是不支持或者并不完善的,而且对函数逻辑进行简化能够简化证明过程,因此我们需要对部分函数及数据类型进行重构操作。
代码重构部分的主要内容如下:
导入工作,整理函数的调用关系,并将证明函数中调用的所有函数及数据类型导入到一个文件夹中。
因为我们只是针对单个函数进行证明,因此我们需要将每个函数调用的所有函数及数据类型单独整理出来,从而保证整理出来的代码可以被成功编译。
在这一部分工作中,包含有很多的宏选择定义:#if……#else,会根据某个属性的值,对定义的结果进行选择,这一部分主要是和具体配置(***平台、***位数等)有关。因此为了确定宏选择定义结果,在实际操作中,通过添加#error来对宏选择定义进行测试,通过输出结果进而判断,代码在实际执行中所选择的宏定义。
另外,因为在Xen代码中,包含了多个平台的功能代码实现,所以根据平台的不同,会包含许多重名函数,这里我们平台统一选择为arm64位。
代码语句重构,对函数中不能被CompCert C编译器识别或者转换不完善的数据类型进行重构,例如goto语句等。
CompCert编译器无法识别某些语句结构,因此为了能够顺利编译,对于一些特定结构,需要在保证结构功能不变的前提下进行重构。例如goto语句,在代码分析过程中,需要考虑到goto跳转的位置,对于跳转到函数内部位置的goto语句可以使用if…else…语句来代替,而对于跳转到函数外部位置的goto语句,则需要谨慎分析,必要时添加函数调用。在证明函数中,所有goto语句均为跳转到函数内部位置。下面为一个goto结构示例:
该函数是对调度器进行分配,这里“goto found”跳转到了found位置,对于其重构可以如下所示:
将函数复杂结构分离,对代码中复杂的结构进行分离操作,即将复杂结构封装成新的函数,简化函数逻辑,进而简化证明过程。
将函数中某些复杂的操作分离出去是一种证明的技巧。如果函数包含有复杂数据类型,则证明过程又冗长又复杂,甚至可能出现证明策略无法适配的问题。为了解决这个问题,可以通过将复杂数据类型分离出来,作为一个独立函数单独进行证明。在最终函数中,该复杂操作只是去调用这个独立函数,即在证明最终函数时,不需要再去证明复杂操作,只需要证明函数调用关系,从而简化证明过程。下面为一个普通函数的证明操作:
该函数用来记录当前正在运行的vcpu,这里包含复杂数据结构嵌套指针操作“d.vcpu=v->vcpu_id”以及“d.domain=v->domain->domain_id”,这里将指针操作封装到函数里面,达到简化代码目的:
进行证明时,需要将上述3个分离函数分别证明,最后在trace_contiue_running中引用3个证明即可,而不需要针对指针结构在写证明过程。
其它操作,删去代码中不影响函数逻辑及变量状态的函数。
对于函数中包含的一些记录跟踪函数以及断言函数,在整个函数执行过程中并没有影响到函数变量的状态,只是相当于记录变量相关信息或者输出断言,因此在实际过程中可以删去这些代码;另外CompCert C编译器和VST证明工具对于互斥锁的证明策略不完善,因此对于互斥锁问题暂时也没有办法进行证明。
2、对函数进行形式化建模
形式化建模工作即对模块函数进行形式化描述,这一部分工作主要是通过CompCert C编译器和VST工具自动对函数进行形式化建模。这两种工具的自动化建模提高了证明过程的效率,但是自动化建模不够灵活,函数中的一些特定结构仍然需要人为去描述。
对于结构体类型VST里面定义为“Tstruct_name noattr”,但是该类型定义无法表示结构体变量的内部结构。结构体类型,可以理解为是一个不同类型的集合表示,因此在描述结构体类型的时候,需要考虑其内部变量类型该如何去表示,然后结构体名字就作为这些变量的集合名。
上述代码表示vcpu结构体类型的部分内部变量,当描述该结构体结构之前需要先介绍下VST对于C语言简单类型的表示方法,如下表1。
表1 C语言简单类型与VST库mapping表
C语言基本类型 | VST库中对应类型 |
unsigned int | tuint |
unsigned short | tushort |
unsigned long | tulong |
unsigned long long | tulong |
int | tint |
signed long | tlong |
signed long long | tlong |
struct a{…} | Tstruct_a noattr |
char | tschar |
上述表是一些简单类型在VST库中的表示方式,这种表示方式可以用来表示描述函数参数或者中间变量以及返回值的类型,例如参数类型为int,则函数模型中会表示为tint,返回类型为unsigned int,则表示为tuint,但是当涉及到具体操作的时候,可能需要使用其他方式来描述,例如对于C程序里面的一些算术操作,因为在Coq中对于整数表示只有Z,其中的加减乘除也都是以Z为单位来进行计算,所以在整个过程中,我们需要表示变量类型为Z,当最后表示在某个地址上存储的值为什么类型时,通过辅助函数,进行类型转换,将Z转换为需要类型。
在对结构体进行描述时,实际是要表示内部变量的值,而在函数操作中,对结构体进行操作,也是对这些值进行操作,因此对于整型变量类型的,都可以通过Z类型来表示,而在上述例子中包含有“struct domain*domain”和“struct vcpu_runstate_inforunstate”,两种结构体类型成员,这里就需要特殊处理。
对于结构体内部嵌套结构体类型指针,就相当于对于结构体的间接引用,指针的值就是指向另一个结构体的地址,而这传递地址实质也是一串整型类型的数字,相当于该类型为“Z->struct”,也就是这串地址就可以表示该结构体变量,后续对该结构体的操作,都可以通过该地址来定位结构体进行操作。
Definition domain_pool:ZMap.t domain_abs. |
上述代码就是对所有domain结构体类型的一个集合抽象,定义domain_pool之后,可以通过ZMap.get或者ZMap.set来对指定地址上面的结构体内部成员进行操作。
对于结构体内部嵌套结构体变量,实质上是在内存中直接引用了该结构体成员,这个变量地址上面存储了该结构体全部成员,因此这里对其的描述就是另一个结构体类型定义。
最终上述结构体可以形式化描述为:
在其他地方去表示某个具体结构体时,比如表示一个id为1,domain地址为2,runstate的值为(1,2,3)的结构体时,就可以表示为“Vcpu 1 2(1,2,3)___”横线表示is_urgent,pause_flags,processor的值可以为任意整型。
3、定理描述
定理描述部分是证明中的关键,定理描述的正确性决定了整个证明过程的正确性。描述的定理被要求要符合VST的规范,即该部分定理必须使用Hoare逻辑结构表示,且能够反映函数执行前与执行后的各部分状态变化。
在VST工具规定了定理描述结构的规范为:
上述规范中,DECLARE将该定理描述与原函数的形式化模型绑定,它的后面跟的是函数的形式化模型的名字;WITH语法是将所有可能出现在前置和后置条件中的变量使用Coq语法表示出来;PRE和PROP分别代表函数的前置条件和后置条件,其内部结构均为“PROP()LOCAL()SEP()”,PROP中描述的是函数约束,所描述的都是与程序状态无关的命题,而LOCAL中描述的是对局部类型的定义,并将其绑定到具体变量上,SEP里面是空间谓词,表示在具体地址上所存在的具体类型及具体值。下面我们将对这个结构进行详细介绍。
通过上述结构规范,可以得到定理描述过程的结构示意图,如图2所示(所有定理后缀均表示为spec):
在进行定理描述时,首先通过DECLARE将该定理描述与原函数形式化模型绑定,后接函数形式化模型名字,例如A,即宣称这个定理描述的是A模型。
WITH语句会列举出整个函数执行过程中可能出现的变量,同时规定其类型,这些变量包括函数参数以及全局变量等。注意,WITH列举的变量实际是对函数原来的这些变量进行形式化描述之后的变量,在后续操作中,需要将这些变量与原函数变量进行绑定。该语句用来表示哪些变量的状态在函数执行过程中可能会改变。
PRE部分,表示该函数执行前的状态,它的主体部分是“PROP()LOCAL()SEP(),”也就是图中的①部分,PRE部分在进入主体之前,首先需要将参数形参列举出来,同时与形参类型的形式化描述绑定,这里的形参名字是与定理所绑定的形式化模型中的形参名字一致。形参的名字是证明工具通过在原函数参数名字前加一道下划线来表示。PRE中的“PROP()”即函数执行前应该满足的约束条件,通常包括WITH所列举变量所要满足的范围约束,类型约束以及简化证明所需要的恒等约束等;PRE中的“LOCAL()”表示函数执行前必须具有的局部变量或者全局变量,例如形参。同时会将该变量的形式化描述与形式化模型中的变量名绑定。PRE中的“SEP()”是一个空间谓词,表示函数执行前,某操作变量地址上的实际初始值情况,这里通常来表示结构体或者指针等数据类型。
POST部分,与PRE相对,表示函数执行后的状态情况,主体部分仍然是“PROP()LOCAL()SEP()”,也就是图中的②部分,POST后需要接函数的返回类型。POST中的“PROP()”表示函数执行之后所要满足的约束条件;POST中的“LOCAL()”通常是表示函数的返回值;PST中的“SEP()”同样表示空间谓词的分离链接情况,即函数胡执行后某操作变量地址上上的具体值情况。
因为我们证明方式是正向证明即由前置条件推后置条件成立,所以PRE可以作为前提条件辅助证明,我们最终需要证明的就是函数执行后的状态与所预期执行之后状态是否一致,函数执行后的状态由函数的形式化模型决定,预期执行状态则需要我们根据函数的预期功能描写相关定理。如果两者一致则函数不存在问题,如果不一致则说明程序存在问题或者形式化规约的描述存在问题。
另外,我们在进行定理描述时,一个函数要进行两次定理描述,一次是对函数的抽象逻辑进行描述;另一次是对函数具体逻辑进行描述。抽象逻辑就是函数的简化逻辑,不会涉及对函数中存在的复杂结构进行描述。在证明时,我们证明程序逻辑的正确性之后,再证明具体逻辑和抽象逻辑的一致性。这样做的好处是,当我们证明一个函数的具体逻辑和抽象逻辑一致性之后,如果其他函数当中包含了该函数的调用,则在其他函数证明时,可以直接使用该函数的抽象逻辑代替具体逻辑。进而简化证明过程。
4、定理证明
定理证明工作就是使用证明策略对形式化描述的定理进行推导证明,我们进行的证明都是正向推理,即根据函数执行顺序来推导证明。在证明过程中,具体定理中的PRE部分的PROP里面的命题均作为前置条件,而放到证明的上下文中,而POST当中的PROP命题,则会放在POSTCONDITION结构当中,当前一个语句证明结束之后,POSTCONDITION将释放下一个语句作为证明目标,并在POSTCONDITION结构中删掉该语句。
整个证明的思想都依托于Hoare逻辑和分离逻辑,因此证明推理过程的最终结果就是证明{P}c{Q}是否成立。因为证明的过程与函数自身语句有关,因此在下一节中我们将根据具体函数来介绍证明过程,本小节主要介绍在证明过程中使用到的重要证明策略。
rewrite改写策略,其作用就是将当前目标中的目标变量替换为前提中的要求变量。例如前提中假设了n=m,通过rewrite策略可以将证明目标中的n变量改为m变量,通过添加箭头符号,可以指示其改写的方向,例如如果为“rewrite<-”,则是将证明目标中的m变量改为n变量。
apply策略,也是一个替换策略,不过与rewrite策略的区别是,该策略提供了替换之后的化简运算操作,例如对于“n=m”的证明目标,前提中刚好有命题m=n,如果使用rewrite,则证明目标被简化为m=m,而apply策略则会在在替换以后对证明目标进行化简,从而证明该目标。
forward策略用来推动Hoare逻辑证明的正向执行,例如对于Hoare逻辑证明{P}i=0;more{R},首先需要应用顺序规则,对于推导出来的断言Q语句,其中的赋值、返回、中断、继续等类型的语句都可以通过forward策略自动推导,forward策略应用了一个强后置条件类型的证明规则推导Q。另外对于不同的C语句,forward策略也有不同的几种形式:forward_if策略,用于对if…else…语句的推导;forward_while策略,是对于while循环的推导;forward_call策略是当涉及到函数调用时,所进行的推导策略。
entailer策略,是用来完成对于蕴含语句的推导工作。蕴含语句表示“对于P、Q两个命题,如果P成立则Q成立”,记做P→Q,P为蕴含式前件,Q为蕴含式后件。在程序中该语句表示任何满足P语句的状态也一定满足Q语句,VST中表示为“ENTAIL△, ”,“△”表示上下文全局类型,用来提供状态所附加的约束条件。“entailer”策略主要通过对“△”内容进行推导,并结合前置条件,判断约束条件在满足P语句的同时是否满足Q语句,如果都满足,则推导结束。
以下以具体函数的证明过程为例对本发明的内容进一步阐述:
基于MILS架构的安全操作***,中rtsc2_vcpu_insert函数的形式化证明
根据第四节内容,该函数重构以后代码如下所示:
在该代码中,涉及到指针的变量,例如“svc->sdom__elem”等,通过函数“get_”来得到变量值并赋给新的变量,然后在判断条件中使用新变量代替指针结构,同时将第二个if语句中三个判断条件拆成三条if语句,这是为了在证明时将3个判断条件拆分出来进行证明。
在VST环境下,通过执行“clightgen-normailize A.c”命令可以得到A程序的形式化模型,这里得到目标函数形式化模型可在附件中可见,其命名规则均为函数名前加“f_”。另外对于结构体的抽象描述如下:
这里“Inductive”表示归纳的意思,这里通过该语句来对结构体进行抽象描述,括号里面的内容即为结构体内部成员;“_pool”表示为某个域,可以理解为同一类型的结构体的集合,通过结构体地址可以在该集合中找到该结构体。
进行定理描述时,首先需要分析该函数执行前已经满足的条件,即前置条件:
1.形式参数满足其类型要求范围。
2.这个函数当中调用的其他已经证明完成的函数,它们是正确的,即满足功能正确性。
3.证明过程中恒成立的条件,为了简化证明,可以列举出来。
根据上述3条前置条件,可以得到PRE中的“PROP()”语句。
分析该函数功能需求,得到该函数抽象功能描述:
“rtsc2_vcpu_insert”函数的功能是将处于转移domain中的vcpu***到调度器运行队列,其主要通过调用“__runq_insert”函数以及“list_add_tail”函数实现其功能,在该函数的抽象功能描述中,“match…with…”匹配源代码中的“if…else…”语句,而“_abs”分别代表了其他函数的抽象功能描述。在该函数中,除了调用的函数之外,其他地方并没有涉及状态变化,因此在其功能描述中,要保证其他函数的功能描述是准确的。
“__runq_insert”函数的功能描述如下:
当vcpu的属性“virq_flags”大于零时,该函数处于中断状态,执行中断队列***函数,对应功能描述就是“match Zgt_bool vf 0with”,“vf”是通过函数“get_vcpu_virq_flag”函数得到,其功能描述
“av”表示其传入地址,该地址表示在vcpu类型的结构体域中目标结构体的地址,通过“ZMap.get”进行查找,结合之前vcpu结构体类型的抽象描述“vcpu_abs”,可以得到其内部成员变量“avirq_flag”,并输出vcpu域“vpool”和“avirq_flag”的值。
其他“get_…”函数的功能抽象描述和上面一致,都是在域中查找具体结构体,再得到其成员变量的值。“__runq_insert”函数中通过判断语句分支执行“_irqq_insert”函数,该函数包含循环结构,循环结构的功能抽象需要单独描述:
“Fixpoint”表示递归方法,在Coq中,递归定义必须是递减的,因此这里需要给循环添加一个递归条件,即“match n with”,当调用该循环描述时,我们会传入一个很大的值作为n,即实际循环次数永远比n小,保证该递归条件不影响原循环,原循环的作用是寻找中断序列找那个第一个优先级比svc低的vcpu的位置,因此最终输出值就是该vcpu位置。有了该循环描述之后,得到“irqq_insert_abs”的功能抽象描述:
“iter’”即循环结束时返回优先级比svc低的vcpu位置,通过“list_add_tail”函数将svc***到其前面。
以上就是“rtsc2_vcpu_insert”的功能描述情况,该函数执行之后输出情况应该与功能描述一致,于是最终可以得到函数的定理描述:
PRE中的“PROP”包括了其调用函数的所有前置条件,可以在附件查看。PRE中的其他部分内容情况,第四节中已经有过介绍。POST中的“PROP”,“loop’”即函数执行之后应该list结构体域的变化情况,因为该函数实际就是在vcpu列表中添加一个新的vcpu,list域状态发生变化,并且变化情况应该和功能描述一致,即“lpool'=rtsc2_vcpu_insert_abs”。另外可以看到该定理描述中“SEP()”部分为空,这是因为其调用函数已经被证明正确性,而涉及到的空间结构均已经在调用函数的证明过程中被证明正确,而且该函数并未涉及其他空间结构,因此这里为空,因为“SEP”已经为空,且该函数已经为最终函数,因此没有必要在去描述一个抽象定理进行证明。
最后得到该定理的证明:
这里列出了该函数的一部分证明过程,“start_function”表示证明的开始,它会将要证明的霍尔三元组提到表达出来;“forward_call()”是对C语言中函数调用的证明,括号里面跟的是被调用函数的定理描述部分中“WITH”语句中的变量“forward_if()”是对于if结构体的证明策略,该策略括号内为“PROP(P)LOCAL(Q)SEP(R)”结构,即表示该函数执行该if语句时所要满足的状态情况。在源代码中,这里是判断vcpu是否是空闲状态,如果空闲,则直接退出,否则执行之后的语句。对应可以理解为如果空闲,则list域并不作任何修改,如果不空闲,则执行接下来的语句操作,即“PROP”中的内容;另外“LOCAL”中列出了这一段if语句所需要的临时变量情况。当该证明结束以后,Coq中会出现3条分支,前两条对应if判断语句的结果分支,第三条描述之后的程序语句。最后“Qed.”表示证明结束。在Coq中,如果一个函数是正确的,则该证明过程可以推导到“Qed”,否则一定会在中间无法进行证明推导,而所有证明目标证明完成之后,右上角会显示没有目标可以证明。
本领域的普通技术人员将会意识到,这里所述的实施例是为了帮助读者理解本发明的原理,应被理解为本发明的保护范围并不局限于这样的特别陈述和实施例。对于本领域的技术人员来说,本发明可以有各种更改和变化。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的权利要求范围之内。
Claims (4)
1.基于定理证明的形式化验证方法,其特征在于,包括:对源代码重构、对函数进行形式化建模、对函数进行定理描述、最后进行形式化证明;
所述对源代码重构,具体为:
A1、整理函数的调用关系,并将证明函数中调用的所有函数及数据类型导入到一个文件夹中;
A2、对函数中不能被CompCert C编译器识别或者转换不完善的数据类型进行重构;
A3、对代码中复杂的结构进行分离操作;
A4、删去代码中不影响函数逻辑及变量状态的函数;
所述对函数进行形式化建模,具体为:通过CompCert C编译器和VST工具自动对函数进行形式化建模;
对函数进行定理描述,具体为:所述定理采用Hoare逻辑结构表示,得到的形式化描述的定理能够反映函数执行前与执行后的各部分状态变化;
所述定理证明,具体为:使用证明策略对形式化描述的定理进行推导证明。
2.根据权利要求1所述的基于定理证明的形式化验证方法,其特征在于,所述形式化描述的定理满足VST的规范。
3.根据权利要求2所述的基于定理证明的形式化验证方法,其特征在于,所述对函数进行定理描述的过程为:
A1、通过DECLARE将该定理描述与原函数形式化模型绑定,后接函数形式化模型名字;
A2、采用WITH语句列举出整个函数执行过程中可能出现的变量,同时规定其类型;
A3、前置条件,内部结构为“PROP()LOCAL()SEP()”,PROP()表示表示函数执行之前所要满足的约束条件;LOCAL()表示函数执行前必须具有的局部变量或者全局变量;SEP()是一个空间谓词,表示函数执行前,某操作变量地址上的实际初始值情况;
A4、后置条件,内部结构为“PROP‘()LOCAL‘()SEP’()”,PROP‘()表示表示函数执行之后所要满足的约束条件;LOCAL‘()表示表示函数的返回值;SEP’()是一个空间谓词,表示函数执行后,函数胡执行后某操作变量地址上上的具体值情况。
4.根据权利要求3所述的基于定理证明的形式化验证方法,其特征在于,所述证明策略包括:rewrite改写策略、apply策略、forward策略以及entailer策略,所述rewrite改写策略将当前目标中的目标变量替换为前提中的要求变量;所述apply策略将当前目标中的目标变量替换为前提中的要求变量,并对证明目标进行化简;所述forward策略用于推动Hoare逻辑证明的正向执;所述entailer策略用来完成对于蕴含语句的推导工作。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201911225125.3A CN110989997A (zh) | 2019-12-04 | 2019-12-04 | 基于定理证明的形式化验证方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201911225125.3A CN110989997A (zh) | 2019-12-04 | 2019-12-04 | 基于定理证明的形式化验证方法 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN110989997A true CN110989997A (zh) | 2020-04-10 |
Family
ID=70089908
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201911225125.3A Pending CN110989997A (zh) | 2019-12-04 | 2019-12-04 | 基于定理证明的形式化验证方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN110989997A (zh) |
Cited By (9)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN111679809A (zh) * | 2020-04-15 | 2020-09-18 | 杭州云象网络技术有限公司 | 一种基于Noesis逻辑的程序开发与验证方法及*** |
CN112099764A (zh) * | 2020-08-13 | 2020-12-18 | 南京航空航天大学 | 基于形式化转换规则的航电领域需求的规范化方法 |
CN112199913A (zh) * | 2020-10-15 | 2021-01-08 | 湖南泛联新安信息科技有限公司 | 一种基于Coq的超大规模集成电路RTL漏洞形式化分析方法 |
CN112506516A (zh) * | 2020-11-30 | 2021-03-16 | 广州市智能软件产业研究院 | 一种安全协议的代码生成方法、计算机及存储介质 |
CN113379051A (zh) * | 2021-06-10 | 2021-09-10 | 江西理工大学 | 基于单元结果演绎的自动定理证明方法、装置及存储介质 |
CN114118423A (zh) * | 2021-11-29 | 2022-03-01 | 西南交通大学 | 基于符号权重的前提选择方法、***及电子设备 |
CN115460297A (zh) * | 2022-09-06 | 2022-12-09 | 中国科学技术大学 | 一种网络安全协议的自动形式化验证方法 |
CN115658549A (zh) * | 2022-12-08 | 2023-01-31 | 浙江望安科技有限公司 | 一种对源代码形式化验证方法 |
CN116069669A (zh) * | 2023-03-07 | 2023-05-05 | 中国科学技术大学 | 全自动分布式一致性的分析方法、***、设备及存储介质 |
Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
FR2815434A1 (fr) * | 2000-10-17 | 2002-04-19 | Trusted Logic | Procede de verification de coherence de codes destines a un systeme embarque, notamment une carte a puce |
CN108536445A (zh) * | 2018-03-28 | 2018-09-14 | 成都链安科技有限公司 | 面向区块链智能合约的高度自动化形式化验证***及方法 |
CN109240907A (zh) * | 2018-07-26 | 2019-01-18 | 华东师范大学 | 基于霍尔逻辑的嵌入式实时操作***的自动化验证方法 |
CN110347405A (zh) * | 2019-07-01 | 2019-10-18 | 电子科技大学 | 一种schedule调度模块的形式化验证方法 |
-
2019
- 2019-12-04 CN CN201911225125.3A patent/CN110989997A/zh active Pending
Patent Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
FR2815434A1 (fr) * | 2000-10-17 | 2002-04-19 | Trusted Logic | Procede de verification de coherence de codes destines a un systeme embarque, notamment une carte a puce |
CN108536445A (zh) * | 2018-03-28 | 2018-09-14 | 成都链安科技有限公司 | 面向区块链智能合约的高度自动化形式化验证***及方法 |
CN109240907A (zh) * | 2018-07-26 | 2019-01-18 | 华东师范大学 | 基于霍尔逻辑的嵌入式实时操作***的自动化验证方法 |
CN110347405A (zh) * | 2019-07-01 | 2019-10-18 | 电子科技大学 | 一种schedule调度模块的形式化验证方法 |
Cited By (17)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN111679809A (zh) * | 2020-04-15 | 2020-09-18 | 杭州云象网络技术有限公司 | 一种基于Noesis逻辑的程序开发与验证方法及*** |
CN112099764B (zh) * | 2020-08-13 | 2022-03-15 | 南京航空航天大学 | 基于形式化转换规则的航电领域需求的规范化方法 |
CN112099764A (zh) * | 2020-08-13 | 2020-12-18 | 南京航空航天大学 | 基于形式化转换规则的航电领域需求的规范化方法 |
CN112199913A (zh) * | 2020-10-15 | 2021-01-08 | 湖南泛联新安信息科技有限公司 | 一种基于Coq的超大规模集成电路RTL漏洞形式化分析方法 |
CN112199913B (zh) * | 2020-10-15 | 2023-12-12 | 湖南泛联新安信息科技有限公司 | 一种基于Coq的超大规模集成电路RTL漏洞形式化分析方法 |
CN112506516A (zh) * | 2020-11-30 | 2021-03-16 | 广州市智能软件产业研究院 | 一种安全协议的代码生成方法、计算机及存储介质 |
CN112506516B (zh) * | 2020-11-30 | 2024-04-30 | 广州市智能软件产业研究院 | 一种安全协议的代码生成方法、计算机及存储介质 |
CN113379051A (zh) * | 2021-06-10 | 2021-09-10 | 江西理工大学 | 基于单元结果演绎的自动定理证明方法、装置及存储介质 |
CN113379051B (zh) * | 2021-06-10 | 2023-08-25 | 江西理工大学 | 基于单元结果演绎的自动定理证明方法、装置及存储介质 |
CN114118423A (zh) * | 2021-11-29 | 2022-03-01 | 西南交通大学 | 基于符号权重的前提选择方法、***及电子设备 |
CN114118423B (zh) * | 2021-11-29 | 2023-04-21 | 西南交通大学 | 基于符号权重的前提选择方法、***及电子设备 |
CN115460297A (zh) * | 2022-09-06 | 2022-12-09 | 中国科学技术大学 | 一种网络安全协议的自动形式化验证方法 |
CN115460297B (zh) * | 2022-09-06 | 2023-06-30 | 中国科学技术大学 | 一种网络安全协议的自动形式化验证方法 |
CN115658549A (zh) * | 2022-12-08 | 2023-01-31 | 浙江望安科技有限公司 | 一种对源代码形式化验证方法 |
CN115658549B (zh) * | 2022-12-08 | 2023-03-07 | 浙江望安科技有限公司 | 一种对源代码形式化验证方法 |
CN116069669B (zh) * | 2023-03-07 | 2023-06-16 | 中国科学技术大学 | 全自动分布式一致性的分析方法、***、设备及存储介质 |
CN116069669A (zh) * | 2023-03-07 | 2023-05-05 | 中国科学技术大学 | 全自动分布式一致性的分析方法、***、设备及存储介质 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN110989997A (zh) | 基于定理证明的形式化验证方法 | |
CN111062038B (zh) | 一种基于状态空间的智能合约形式化验证***及方法 | |
Ni et al. | Certified assembly programming with embedded code pointers | |
Blazy et al. | Verifying constant-time implementations by abstract interpretation | |
Deng et al. | Bogor/kiasan: A k-bounded symbolic execution for checking strong heap properties of open systems | |
Feldthaus et al. | Semi-automatic rename refactoring for JavaScript | |
Yang et al. | A hybrid formal verification system in coq for ensuring the reliability and security of ethereum-based service smart contracts | |
Bouajjani et al. | Analysis of recursively parallel programs | |
Monteiro et al. | Model checking C++ programs | |
Davis et al. | The reflective Milawa theorem prover is sound (down to the machine code that runs it) | |
Bodin et al. | A trustworthy mechanized formalization of R | |
Apt et al. | Verification of object-oriented programs: A transformational approach | |
Garis et al. | Translating Alloy specifications to UML class diagrams annotated with OCL | |
Besson et al. | Certified static analysis by abstract interpretation | |
CN115310095A (zh) | 一种区块链智能合约混合形式化验证方法及*** | |
Tan et al. | Construction of a semantic model for a typed assembly language | |
Tan et al. | [Retracted] A Formal Verification Method of Compilation Based on C Safety Subset | |
Dévai et al. | A tool for formally specifying the C++ Standard Template Library | |
Arusoaie | A generic framework for symbolic execution: theory and applications | |
Meinicke | JML-based verification for feature-oriented programming | |
Semeráth et al. | Validation of Derived Features and Well-Formedness Constraints in DSLs: By Mapping Graph Queries to an SMT-Solver | |
Scherer | Engineering of Reliable and Secure Software via Customizable Integrated Compilation Systems | |
Veschetti et al. | SmartML: Enhancing Security and Reliability in Smart Contract Development | |
Nguyen et al. | Integrating pattern matching and abstract interpretation for verifying cautions of microcontrollers | |
Marticorena et al. | Refactoring generics in JAVA: a case study on Extract Method |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
WD01 | Invention patent application deemed withdrawn after publication | ||
WD01 | Invention patent application deemed withdrawn after publication |
Application publication date: 20200410 |