(计算机软件与理论专业论文)cc类型转换和控制流相关安全漏洞的分析与检查.pdf_第1页
(计算机软件与理论专业论文)cc类型转换和控制流相关安全漏洞的分析与检查.pdf_第2页
(计算机软件与理论专业论文)cc类型转换和控制流相关安全漏洞的分析与检查.pdf_第3页
(计算机软件与理论专业论文)cc类型转换和控制流相关安全漏洞的分析与检查.pdf_第4页
(计算机软件与理论专业论文)cc类型转换和控制流相关安全漏洞的分析与检查.pdf_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

摘要 c c + + 语言开发者追求的是语言的高效性、灵活性,为此在不同程度上忽略 了语言的安全性。而且由于程序员能力上的不够或者粗心大意,严重地威胁着软 件的安全性。本文主要研究的是c c + + 程序中类型转换和控制流相关安全漏洞。 通过对这些漏洞的深入分析,本文给出了可行的静态检查方法。 对于类型转换漏洞,通过分析各种数据类型的特性,研究它们之间的各种转 换,总结出不安全类型转换的共性。采用语法制导翻译技术对类型转换漏洞进行 了形式化的描述。最后结合自由软件g a s t a ,通过对抽象语法树的遍历和处理, 实现了对该漏洞的检查。同理,对于控制流相关的安全漏洞,通过对程序实例的 分析,先对这些漏洞进行了形式化的描述,再结合程序,给出了可行的检查实现。 关键宇:软件安全静态检查类型转换抽象语法树 a b s t r a c t h i g he f f i c i e n c ya n df l e x i b i l i t ya r et h ea i m so f t h ed e v e l o p e r so fc c + + l a n g u a g e b u ts o m es a f e t i e sa r en e g l e c t e dm o r eo rl e s s b e c a u s eo f t h ep r o g r a m m e r si n a b i l i t yo r c a r e l e s s n e s s ,t h es a f e t yo ft h es o r w a r ei se x t r e m e l yt h r e a t e n e d t y p ec o n v e r s i o na n d c o n t r o lf l o ws a f e t yv u l n e r a b i l i t i e si nc c + + a l es t u d i e di nt h i sp a p e r f e a s i b l es t a t i c d e t e c t i n gm e t h o d sa r eg i v e nb a s e do nd e e pa n a l y s i so f t h e s es a f e t yv u l n e r a b i l i t i e s f o rt y p ec o n v e r s i o ns a f e t yv u l n e r a b i l i t i e s i t sc o m m o n n e s si ss u m m a r i z e dt h r o u g h t h ea n a l y s i so fd a t at y p ec h a r a c t e r i s t i ca n dt h ec o n v e r s i o no ft h e m s y n t a xd i r e c t e d t r a n s l a t i o nt e c h n i q u ei su s e dt od e s c r i b et h et y p ec o n v e r s i o ns a f e t yv u l n e r a b i l i t i e s f o r m a l l y f i n a l l y , t h e s ev u l n e r a b i l i t i e s a r ed e t e c t e dw i mt h eu s eo ff o r e i g nf r e e s o f t w a r eg a s t aa n dt h eh a n d l eo ft h ea s t ( a b s t r a c ts y n t a xt r e e ) t h ec o w x o lf l o w r e l m i v es a f e t yv u l n e r a b i l i t i e sa r eh a n d l e ds i m i l a r l y k e y w o r d :s o f t w a r es a f e t y s t a t i cc h e e k t y p ec o n v e r s i o n a b s t r a c t s y n t a xt r e e 创新性声明 本人声明所呈交的论文是我个人在导师的指导下进行的研究工作及取得的研 究成果。尽我所知,除了文中特别加以标注和致谢中所罗列的内容以外,论文中 不包含其他人已经发表或撰写过的研究成果,也不包含为获得西安电子科技大学 或其他教育机构的学位或证书而使用过的材利。与我一同 作的同志对本研究工 作所做的任何贡献均己在论文中作了明确的说明并表示了谢意。 申请学位论文若有不实之处,本人承担一切相关责任。 本人签名:黾鱼塞! ,2 曰期:2 塑g 兰f7 关于论文使用授权的说明 本人完全了解西安电子科技大学有关保留和使用学位论文的规定,即:研究 牛在校攻读学位期间论文工作的知识产权单位属西安电子科技人学。本人保证毕 业离校后,发表论文或使用论文工作成果时署名单位仍然为两安电子利技大学。 学校有权保留送交论文的复印件,允许查阅和借阅论文;学校可以公布论文的争 部或部分内容,叮以允许采用影印、缩印或其他复制手段保存论文。( 保密的论文 在解密后遵守此规定) 本学位论文属j i 保密在年解密后适用本授权书。 本人签名:氢盔 日期 导师签名 2 。e6 2 日期:塑互g j 矽 第章绪论 第一章绪论 1 1 研究背景 本文工作源自于“十五”预研课题“软件安全性故障模式分析”。该课题主要研究 c c 抖语言的程序分析技术和面向不同领域的软件安全模式构建技术。最终提供一 组与安全分析相关的方法,并研制一个基于静态分析的软件系统安全检查工具。 随着计算机技术和网络技术的飞速发展,计算机软件系统被广泛地应用于社 会的各个方面,涉及到国家的政治、经济、文化等诸多领域。其中有一些系统是 企业业务运作的基础。有一些系统存储和管理着十分重要的信息,甚至是国家机 密。因此,软件的安全问题成为一个日益突出的问题,特别是军事领域软件的安 全已越来越受到人们的重视。 计算机的安全性隐患大量存在于软件系统中,有系统外部的攻击如系统入侵、 信息窃取、病毒等,也有系统自身问题造成的各种安全漏洞。这些都会使得软件 在使用阶段出现意想不到的错误,从而造成重大损失。本文主要研究系统自身的 问题,由于c c + + 程序设计语言本身问题造成的各种安全漏洞。 在过去的二十年中,c c + + 作为工程应用中重要的程序设计语言,在软件开发 领域中得到了广泛的应用。c 语言最初在操作系统开发领域的应用背景导致了其在 设计上倾向于向程序员暴露机器细节。c 语言的运行时环境通常不提供任何形式的 保护机制,也不提供任何资源自动释放机制。这些特性使得c 程序员在开发程序时 必须对程序中的各种资源操作细节进行全面考虑,否则就容易引发各种错误。 c 抖是在c 的基础上设计的,由于需要保持与c 语言的兼容性,因此也具有c 语言的大多数缺点。同时,由于c + + 的设计者选择在c 语言的基础上构造c + 十的面 向对象机制,这使得c + + 最终采用了一种不同于一般面向对象理论的对象模型。 c + + 特殊的对象模型导致许多面向对象程序设计方法并不完全适用于c h 。而习惯 于一般面向对象程序设计风格的程序员在开始使用c + + 时,往往会由于对c + + 对象 模型的错误理解而导致代码中出现各种程序错误。由于上述两个原因,使得c c + + 一直以来被认为是一种不安全的语言。 c ,c + + 中可能出现的安全漏洞主要分为如下几类: ( 1 ) 由于c 语言没有提供保护机制而导致的程序错误,如缓冲区访问越界。 ( 2 ) 由于c 语言没有提供自动资源释放机制而导致的程序错误,例如各种形 式的资源泄漏错误。 ( 3 ) 由于c c + + 语言提供了灵活的类型转换机制,但语言本身并不保证转换 的安全性和正确性。例如不同表示范围的类型进行转换造成的精度损失。 2 c ,c + + 类型转换和控制流相关漏洞的分析与检查 ( 4 ) 由于错误理解c + + 对象模型而导致的程序设计错误,例如在使用了指针 的对象中由于对象复制操作定义不当而导致的资源泄漏或者重复释放错 误。 对于自主开发的软件,主要通过测试的方法检查所有可能的不安全因素。这 需要对软件的功能、特性等具有深刻了解,并且根据软件特性设计完备的测试集, 但这种方法需要消耗大量的人力和物力。我们实现的是在程序静态不运行时自动 检测出软件源程序中存在的各种安全性问题。 1 2 论文的主要工作 本论文的主要工作是:1 对c c + + 不严格的类型转换机制所带来的安全漏洞进 行分析和检查;2 对控制流相关的漏洞进行分析和检查。使用语法制导翻译技术抽 象地描述出这些漏洞的安全规则,结合国外自由软件g a s t a ( 在4 1 节中有详细的介 绍) 构造类型和控制流检查模块,完成对这些安全漏洞的程序自动检测。 本论文的组织结构如下: 第一章为绪论,介绍本课题产生的背景和国内外相关工作的状况。第二章对 静态安全检查工具x d c h e c k 进行简单的介绍。第三章对类型转换和控制流相关 安全漏洞进行分析,并使用语法制导翻译技术抽象地描述出这些漏洞的安全规则。 第四章讲述对类型转换和控制流相关漏洞进行检查的具体实现:结合国外自由软 件g a s t a ,通过在抽象语法树节点上绑定处理函数,最终完成对这些安全漏洞的 程序自动检测。 第二章x d c h e c k 静态检查工具介绍 3 第二章x d c h e c k 静态检查工具介绍 安全分析模型主要由两个部分组成:程序分析和安全分析。 程序分析是安全性检查的基础。根据不同的安全漏洞和对应的安全模式,程 序分析可以在词法、语法、语义等任何级别上进行。基于过程的传统程序分析方 法已经很成熟,如词法分析、语法分析、控制流分析、数据流分析等。分析工具 x d c h e c k 的前端是程序分析,通过对c c + + 源程序进行分析处理,从程序中提取 信息,并为安全分析提供使用这些信息的接口。 安全分析是安全性检查的核心。安全分析的目的是利用程序分析从程序源代 码中得到的信息,也可以直接使用从程序源代码中提取的信息,使用语法分析和 语义分析,并结合从安全漏洞中抽象出来的安全规则,检查程序源代码中可能的 潜在的安全漏洞。分析工具x d c h e c k 的后端是安全分析,主要是根据安全规则来 完成对程序中各种安全漏洞的检测。 4 c ,c 十+ 类型转换和控制流相关漏洞的分析与检查 x d c h e c k 的整体结构图如图2 1 所示。 图2 1x d c h e c k 的整体结构图 x d c h e c k 分为两大部分,即一个前端和一个后端。 x d c h e c k 前端负责向程序员提供一个命令行界面,并从程序员提供的命令 行输入中获得项目的源代码文件列表。当获得源代码文件列表之后,x d c h e c k 前端调用g c c 编译器对源代码文件列表中的源代码文件进行编译,获取它们的 中间表示抽象语法图。最后将抽象语法图文件列表提交给x d c h e c k 后端。 x d c h e c k 后端负责实际的安全检查,主要分为如下五个模块: ( 1 ) 契约分析模块:该模块负责从外部文件中读取程序的安全模式描述( 在 x d c h e c k 中,这种模式被称为“契约”) ,并根据该描述构造安全模式的内部表示。 第二章x d c h e c k 静态检查工具介绍 ( 2 ) 符号表提取模块:该模块负责遍历所有的程序中间表示,从中提取程序 中的各种符号的信息,建立类型系统和函数纪录。同时该模块也负责根据得到的 类型信息构造变量信息生成器,该生成器可以在后续的安全检查过程中被用于构 造变量记录节点。 ( 3 ) 函数调用关系分析模块:该模块负责分析并处理整个项目中所有函数的 调用依赖关系,并根据该依赖关系确定后续安全检查过程中各个函数的分析顺序。 ( 4 ) 主安全检查模块:该模块负责遍历每一个抽象语法树,在遍历过程中收 集各种信息,在契约关系表和符号表的配合下进行安全检查。该模块是x d c h e c k 安全检查功能的主要实现部分。内部包含六个子模块,分别对各类程序安全漏洞 进行安全检查。 ( 5 ) 错误报告模块:该模块负责接收安全检查器分析过程中得到的错误信息, 并根据程序员制定的格式将错误信息整理为错误报告并输出。共有三种错误报告 输出方式:1 默认情况下x d c h e c k 将所有的错误报告输出到屏幕。2 x d c h e c k 将错误报告输出到文件中。3 x d c h e c k 把错误报告以注释的方式植入到复制得 到的源代码副本中。 本文实现的是安全检查模块中的控制流安全性检查子模块,在其它模块的配 合下,实现了对类型转换和控制流相关漏洞的检查。具体的实现将在第四章作详 细的说明。 第三章c ,c + + 中类型转换和控制流相关漏洞的分析 第三章c c + + 中类型转换和控制流相关安全漏洞的分析 3 1 c , c c 抽象语法树简介 由于c + + 语言的语法十分复杂,自主开发它的分析器的工作量很大,并且还需 要进行大量的测试以保证其完备性和正确性。又考虑到一般的编译系统都是先将 程序语言转换成中间代码形式如语法树或三地址代码,再进行代码生成和优化。 因此可以寻找一个合适的编译系统,利用其前端得到源程序的中间表示,再在这 个中间表示上进行处理。 在第二章中对检查工具x d c h e c k 的介绍中就已经提到,在x d c h e c k 的 前端,通过g c c 编译器对源程序进行分析,生成抽象语法树。各个安全检查模 块从全局类型信息或者抽象语法树中提取所需要的信息进行安全检查。 g c c 是美国自由软件基金会( f r e es o f t w a r ef o u n d a t i o n ) 开发且被广泛应用的 编译程序集合的简称( g n uc o m p i l e rc o l l e c t i o n ) 1 2 4 。在目前已有的开放源代码的 c + + 编译器中,它的影响力最广,最为稳定和成熟。该编译程序集合是一个向上 可接收多种语言,向下可支持多种平台的编译系统。它所接收的语言有c 、c + + 、 o b j e c tc + + 、f o r t ra n 、a d a 和j a v a 。 g c c 编译系统主要由三部分组成:与语言相关的前端、与语言无关的后端以 及与硬件相关的机器描述。g c c 的前端由与源语言关系密切的语法分析、语义分 析部分组成,它对源程序进行分析后将其转换为抽象语法树。g c c 的后端为编译 系统的主体部分,它将抽象语法树转换成后端中间语言r t l ( r e g i s t e r t r a n s f e r l a n g u a g e ) ,在此中间语言基础上进行各种优化,并完成代码生成。机器描述部分 则描述g c c 所运行的宿主机和目标机的操作系统、体系结构、指令系统等有关系 统与硬件的情况,并提供给编译程序的后端使用。这样,采用不同的机器描述, 将得到适合于在不同机器与系统上运行的g c c 编译器。g c c 的三个部分既相对分 离又相互配合,完美地实现了g c c 面向多语种、支持多平台的思想。由于g c c 的 抽象语法树对多种语言具有通用性,又经过了广泛的测试,使得不会因为语法树 的错误而引发后续分析的失败,且g c c 的树结构十分稳定,因此我们利用g c c 编 译系统的前端来完成词法分析和语法分析,将源程序转换为抽象语法树。 g c c 的抽象语法树作为一种通用的层次化的中间表示,不仅可以表示各种语 言通用的语法结构,同时也包含表示各种语言特有语法结构的特定类型的树节点。 同c + + 语言中的语法嵌套相对应,各级语法结构对应的抽象语法树也是嵌套的。 ( 1 ) c + + 中的各种声明在抽象语法树中有相应类型的树节点与之对应。v a rd e e l 与变量声明对应,c o n s td e e l 与常量声明对应,p a r a m 3c ,c + + 类型转换和控制流相关漏洞的分析与检查 t e m p l a t e _ d e e l 与模板声明对应,t y p e _ d e c l 与t y p e d e f 声明相对应等。 ( 2 ) 对于c + + 中的函数和成员函数,g c c 抽象语法树中的f u n c t i o nd e c l 类型树 节点与之对应。 ( 3 ) c + + 中的各种语句在抽象语法树中有相应类型的树节点与之对应。 e x p l s t m t m 应各种表达式语句( 赋值语句,函数调用语句) 等,s w i t c h s t i l l t 对应s w “c h 语句,f o l g t r n t 对应f o r 语句,w h i l e _ s t m t 3 t 寸应w h i l e 语句,i f _ s t m t 对应i f - e l s e 语句。 ( 4 ) c 十+ 中各种表达式在g c c 抽象语法树中有相应的表达式类型树节点与之对 应。c a l l e x p r 对应函数调用表达式,m o d i 母e x p r 对应赋值表达式,p l u s _ e x p r 揪 学表达式中加法表达式等。 ( 5 ) c + + 中的标识符( 变量名,函数名等) 在g c c 的抽象语法树中有相应类型的树 节点i d e n t i f i e rn o d e 。 ( 6 ) c h 中的各种类型在抽象语法树中有相应类型的树节点与之对应。 r e c o r d _ t y p e 和s t r u e t 、c l a s s 对应,t m i o n _ t y p e 和u n i o n 对应,a m y p e 和数组对应, f u n c t i o nt y p e 和函数的返回类型对应,m e t h o d _ t y p e 和类中成员函数的返回类型对应 等。 1# i n c l u d e 2 i n t m a i n ( ) 3 4i n t i = o : 5 p r i n t f ( “d l l ”,i ) ; 6r e t u m o : 7 以上简单的的例子得到的抽象语法树文件如附录b 所示,可见其复杂性。 下面详细介绍几个关键节点的具体情况: 1 1 函数声明节点( f u n c t i o n d e c l ) : g c c 抽象语法树中用f u n c t i o nd e c l 对应c + + 中的函数和成员函数。属性节点 n a l n e ;、t y p e :、a r g s :和b o d y :记录着该节点通向其子树的路径。跟踪n a m e :属性节点 指向的子树路径可以找到该函数的名字,例如下图中函数的名字m a i n 。同理,跟 踪t y p e :属性节点就可以找到该函数的类型:跟踪a r g s :属性节点就可以知道该函数 参数的情况;跟踪b o a y :属性节点就可以找到该函数的函数体。例子如下: 1 i n t m a i n ( ) 2 3r e t u r no : 4 得到的m a i n 函数的声明节点如下图所示: 第三章c c + + 中类型转换和控制流相关漏洞的分析 9 图3 1m a i n 函数的f u n c t i o n _ d e c l 节点 2 ) 变量声明节点( v a r _ d e c l ) 对应c ,c + + 中的变量声明语句,抽象语法树中是变量的声明节点v a r _ d e c l 。该 节点中记录着变量的各种信息。通过n a m e :属性节点可以取得变量的名字;通过t y p e 属性节点可以取得变量的类型等。例如:声明语句f l o a t f p ;变量f p 的声明节点 v a r _ d e c l 查d 下图所示: v a td e e l ,7 彩心弋 i d e n t i f i e r _ n o d e p o i n t e r t y p e f u n cd e c l i n t e g e r _ c s t f p 图3 2 声明语句f l o a t + f p 的v a r _ d e c l 节点 l oc c + + 类型转换和控制流相关漏洞的分析与检查 3 ) 函数调用表达式( c a l l e x p r ) 程序中出现的库函数或者用户自定义函数的调用,表现为抽象语法树上的 c a l l _ e x p r 节点。此节点有三个指向子树的属性节点,分别标记为:t y p e 、f n 和a r g s 。 其中f n 属性节点指向被调用函数子树;a r g s 属性节点指向参数子树。例如:函数 s t r e m p ( ) 的c a l l _ e x p r 节点如下图所示: c a l le x p r t y p ” , : f m ip 。i n t e rt y p ea d d r e x p r t r e el i s t o d 0 : , f u n c d e c l i d e n t i f i e r n o d e 图3 3 声明语句f l o a t + 印的v a rd e c l 节点 3 2 类型转换漏洞的分析 3 2 1c ,c + + 中的类型转换 数据类型( d a t a t y p e ) 用来定义存储空间( 内存) 使用的方式。通过定义数据类型, 编译器知道如何创建一块特定的存储空间,以及怎样操纵这块存储空间。数据类 型可以是内部的或者是用户自定义的。类型机制是程序设计语言的核心。类型转 换是将数据从一种类型的值映射为另一种类型的值,不同的类型之间允许进行类 型转换。类型转换包含隐式( 也称为强制) 和显式两种。前者由编译器自动完成,后 第三章c ,c 抖中类型转换和控制流相关漏洞的分析 者则需要编程人员进行显式的说明。 1 显示类型转换。c 语言提供了一种强制类型转换运算符,将一个类型的变 量强制转换为另一种类型。显式转换实际上是一种元运算。各种数据类型的标 识符都可以用作显式转换运算符。对一个变量进行显式转换后,得到一个新的类 型的数据,原来变量的类型并不改变。此类转换的般形式为:( 类型标识符) 表 达式。例如: i n ti = ( i n 0 3 1 4 1 5 9 2 6 ; 严浮点数显式转换j o i n t 类型+ c h a rc = ( c h a r ) ( 9 5 1 2 ) ; 产整型数显式转换c h a r 类型+ , d o u b l ed = ( d o u b l e ) i + ( d o u b l e ) c ;+ i n t 和c h a r 类型的数显式转换为d o u b l e 类型+ , 由于c + + 语言兼容了c 语言,因而c h 中保留了上述c 的特性。同时,标准c + + 对于类型转换进行了改进,增加了四个类型转换运算符( e a s to p e r a t o r s ) :s t a t i c _ c a s t , d y n a m i c _ c a s t ,c o n s t _ e a s t ,r e i n t e r p r e t _ c a s t 。例如: 1 i n t m a i n ( ) 2 3f l o a tf = 1 1 2 3 ; 4 c o n s tc h a r + p e _ s t r2 、e “: 5i n ti = s t a t i ce a s t ( f ) ; 6 c h a r p _ s t r = c o n s t _ c a s t ( p cs t r ) ; 7r e t u r n0 ; 81 2 隐式类型转换。在c ,c + + 语言中,当不同类型的值进行运算等时,需要转 换到同一类型上才能进行,如果程序编写者没有显式地写清楚需要转换的类型, 则编译器就会自动地进行隐式类型转换。c 抖语言编译系统提供的基本数据类型的 隐式转换规则如下: ( 1 ) 程序在执行算术运算时,表示范围小的类型转换为表示范围大的类型; 在( 1 ) 中,执行算术运算时的隐式类型转换由一组称作普通算术转换的规则确 定( 参照附录a ) 。该规则所完成的转换是安全的,并没有精度的损失。 ( 2 ) 在赋值表达式中,赋值号右边表达式的值隐式地转换为左边变量的类型; 在该规则中,赋值表达式右边的表达式的值是被强制性地从原来的类型转换 为左边变量的类型,安全性并没有得到保证,可能出现错误。例子如下: l i m m a i n ( ) 2 3 l o n gl = 1 2 3 4 5 6 7 8 ; 4 i n ti = l :严变量l 的值隐式转换为i n t 类型+ 5 r e t u r n o : 2c ,c + + 类型转换和控制流相关漏洞的分析与检查 6 ) 在例子的第4 行中,变量l 的值被强制转换为i m 类型后才赋值给变量i ,造成了 精度的损失。 ( 3 ) 发生函数调用时,系统隐式地将实参转换为形参的类型; 在该规则中,实参的类型是被强制性地转换为形参的类型。因此,转换的正 确性并没有得到保证,可能出现错误。例子如下: l# i n c l u d e 2v o i df u n c ( i n ti ) 3 4 p r i n t f ( “i = d 、l l ”,i ) ; 5 ) 6 i n t m a i n ( ) 7 8 f l o a t f = 1 2 3 ; 9 f u n c ( f ) ; 产实参f 的值隐式转换为i n t 类型+ 1 0r e t u r no ; 1 1 ) 在例子的第9 行中,实参f 的值被强制转换为i n t 类型后才赋值给形参i ,并没有 得到准确的值。 ( 4 ) 函数有返回值时,系统隐式地将返回表达式的类型转换为函数返回值的类 型。 在该规则中,函数返回表达式的类型是被强制性地转换为函数返回值的类型。 因此,转换的安全性并没有得到保证。可能得不到期望的结果。例子如下: 1i n tf u n c ( d o u b l ed 、 2 3 r e t u m d + 1 2 3 4 5 ;,宰返回表达式的值隐式转换为i n t 类型+ , 4 5 i n t m a i n ( ) 6 7 d o u b l e d = 1 1 1 ; 8 i n t i = f u n c ( d ) ; 9r e t u r no : 1 0, 在例子的第8 行函数f u n c 的调用中,返回表达式d 十1 2 3 4 5 的值隐式地转换为i n t 类型后才被返回,变量i 得到了不精确的值。 第三章c ,c + + 中类型转换和控制流相关漏洞的分析1 3 从安全的角度考虑,基本数据类型的转换应该以不丢失数据精度为前提,根 据上面每种类型的特性,它们之间安全的转换应按下图箭头所示: d o u b l ef l o a t j l o n g 1 i r l t j c h a r ,s h o f t 3 2 2 类型转换漏洞的分析 图3 4 安全的类型转换 d c + + 语言提供了灵活的类型转换机制,但在使用的过程中很容易出现错误。 特别是隐式转换,是编译器内部所做的转换,可能并不是程序员的本意。由于程 序员的能力不足或疏忽,造成程序中存在很多类型转换的错误或安全隐患。 ( 1 1 不同表示范围类型之间转换引起的精度损失 由于计算机的表示有限,每个基本类型的值表示都有一个范围。c 中提供的基 本数据类型有:c h a r 、s h o r t 、i m 、u n s i g n e d 、l o n g 、u n s i g n e dl o n g 、f l o a t 、d o u b l e 、 l o n gd o u b l e 等。 它们的可表示范围一般如下表所示: 类型说明符分配字节数可袭叫数的范网 亨伯:掣c h a r lc 亨符集 知整型s h wl 23 2 7 6 8 3 2 7 6 7 献本整犁i n t 4 2 14 7 4 8 3 6 4 8 2 14 7 4 8 3 6 4 7 无符号型u n s ig n e d40 4 2 9 4 9 6 7 2 9 5 长整型l o n g 4 - 2 14 7 4 8 3 6 4 8 2 t 4 7 4 8 3 6 4 7 印精度实型f l o a t 4 3 4 e 一:糯3 4 e 一: 8 破裕度实型c i ( ) u 】1e 8t 7 e :j 0 8 l 7 e - 3 0 8 3 1 数据类型的表示范围 当程序员将表示范围小的类型转型后赋给表示范围较大的类型时,这种转换 1 4 c c 什类型转换和控制流相关漏洞的分析与检查 是安全的;但如果是将表示范围大的类型转型后赋给表示范围较小的类型,就可 能因为表示范围有限而造成精度损失。例如将一个浮点数转型成整型数之后,就 会造成小数点后的数位丢失。实例如下: 1 # i n c l u d e 2i n tm a i n ( i n ta r g c ,c h a r + a r g v 【】) 3 4c h a r c d a t a = ( e h a t ) 1 1 2 8 ;产1 2 8 超出了c h a r 的可表示范围+ 5 i n t i d a t a = ( i n t ) 1 2 3 4 5 6 ;1 2 3 4 5 6 小数点后的数位将会被丢弃 6 p r i n f f ( “d ,d k n ”,( i n t ) c d a t a ,i d a t a ) ; 7r e t u r n o : 8l 从输出的结果可以看出数据经过转换后造成了精度的损失。 ( 2 ) 不相容指针进行转型的潜在危险 数据类型( d a t at y p e ) 用来定义存储空间使用的方式。不同类型的指针规定了 对所指向内存空间的不同解释方式。在通常情况下,c c 斗+ 语言中不同的类型数 据使用不同的内存存储方式,因此指向不同类型的指针原则上是不应当相互赋值 的。不同类型的指针赋值实际上改变了指针对所指向的空间的解释方式,就可能 造成程序执行时通过指针获取数据的混乱。 指针类型转换造成错误的简单例子如下: l # i n c l u d e 2i n tm a i n ( i n ta r g e ,c h a r + a r g v ) 3 4 i n ta = 1 0 ; 5 i n t b = 2 0 ; 6 d o u b l e + p t r2 ( d o u b l e + ) ( & b ) ; 7 p r i n t f ( ”e n ”,+ p t r ) ;严出现获取数据错误+ 8r e t u r n o : 9 以上程序中,一个d o u b l e 类型指针指向的应该是一个8 个字节长的空间,但 第三章c c + + 中类型转换和控制流相关漏洞的分析 是实际上i m 变量b 只有4 个字节长,因此,p t r 指针指向的空间实际上是堆栈中 的a 和b 两个变量占据的空间,对p t r 指向的双精度浮点数的解释结果依赖于a 和b 两个变量的值。 ( 3 ) 有符号数和无符号数之间的转换引起的错误 无符号数与有符号数进行各种运算时,编译器会先将有符号数转换为无符号 数,再进行运算。这些转换发生时,实际的二进制位数据并没有改变,但是数据 的解释方式被改变了。若有符号数为负数,则这个负数会被重新解释为一个值很 大的无符号数,而这往往导致了错误的结果。 一个循环变量为无符号数,和有符号数比较产生错误的例子如下: 1 u n s i g n e di n ti ; 2 i n t a = 一5 : 3 f o r ( i = 1 0 ;i a ;i - ) 无符号数和有符号数进行比较+ 4 5 c o u t i e n d l ; 6 ) 上述程序段原意是输出数字l o 到4 ,但实际上由于i 为无符号数,在i a 的 比较中,编译器会把有符号整型变量a 转成无符号数,得到一个大于i 的正数, 导致程序没有按预想的运行。 以上三神情况都是一种类型转换为另一种不兼容类型所造成的错误,下面用 语法制导翻译对这种错误进行分析并给出进行安全检查的安全规则。 语法制导翻译基本思想是将语言结构的语义以属性( a t t r i b u t e ) 的形式赋予代表 此结构的文法符号,而属性的计算以语义规贝j j ( s e m a n t i cr u l e s ) 的形式赋予由文法符 号组成的产生式。在语法分析推导或规约的每一步骤中,通过语义规则实现对属 性的计算,以达到对语义的处理。1 1 9 1 显式和隐式的类型转换在g c c 的抽象语法树中都对应着三种转换语句节点 n o p _ _ e x p r 、f l o a te x p r 和c o n v e r t _ c x p r e 下面使用两个属性:变量类型t y p e 和变量 名称l l a n l e ,进行安全规则的语法制导翻译: ( 1 ) m o d i f y _ e x p r _ v a r i a b l e = n o p _ e x p r ; ,赋值语句 lv a r i a b l e = f l o a t _ e x p r ; iv a r i a b l e ;c o n v e r t e x p r ; 以上是一个赋值语句节点,三种类型转换语句节点n o p _ e x p r 、f l o a t _ e x p r 和 c o n v e r te x p r 的作用是将一个数据从种类型转换为另一种类型后,赋值给变量 v a r i a b l e 。变量v a r i a b l e 得到的值就不一定是原数据的精确值。 ( 2 ) n o p _ e x p r t y p eo p o ; i 类型转换语句 t y p e t y p e = g e t _ f u l l _ n a m e _ f r o mn o d e ( t y p e ) ;取得t y p e 的类型 1 6c ,c + + 类型转换和控制流相关漏洞的分析与检查 i n t 4l a t e r _ t y p e 2 9 _ h a s h _ t a b l e _ l o o k u p ( c _ t y p e _ v a l u e ,t y p et y p e ) ; i n t 4b e f o r e _ t y p e = g _ h a s h _ t a b l e _ l o o k u p ( c f l y p e _ v a l u e ,o p o t y p e ) ; i f ( t y p e l ! = n u l l & & t y p e 2l _ n u l l ) i f ( + l a t e r _ t y p e + b e f o r e _ t y p e ) p r i m f _ _ e r r o r ( o p o n a m e ) ;r e t u r n ; 警告有转换危险 i f ( i s f i r s t _ t i n f o _ e o m p a t i b l e w i t hs e c o n d ( t y p e t y p e ,o p 0 t y p e ) 1 2 1 ) ,比较两个类型是否相兼容 p r i n t f _ e r r o r ( o p 0 n a m e ) ; 如果不兼容则警告有转换危险 ) ( 3 ) f l o a t _ e x p r t y p eo p o ; i x 型转换语句 ( t y p e t y p e = g e tf u l l _ n a m e _ f r o m _ n o d e ( t y p e ) ;9 2 得t y p e 的类型 i n t + l a t e r _ t y p e 2g _ h a s ht a b l e _ l o o k u p ( c _ t y p ev a l u e ,t y p e t y p e ) ; i n t b e f o r e _ t y p e = g _ h a s h _ t a b l e _ l o o k u p ( c _ t y p e _ v a l u e ,o p 0 t y p e ) ; i f ( t y p e lbn u l l & & t y p e 2 _ n u l l ) i f ( + l a t e r _ t y p e b e f o r e _ t y p e 、 p r i n t f _ e r r o r ( o p o n a m e ) ;r e t u r n ; 警告有转换危险 i f ( i sf i r s tt i n f o _ _ c o m p a t i b l e _ w i t h _ s e c o n d ( t y p e t y p e ,o p o t y p e ) 1 2 1 ) ,比较两个类型是否相兼容 p r i n t f _ e r r o r ( o p 0 n a m e ) ; 如果不兼容则警告有转换危险 ( 4 ) c o n v e r te x p r _ t y p eo p o ; 类型转换语句 t y p e t y p e = g e t _ f u l ln a m e _ f r o m _ n o d e ( t y p e ) ;取得t y p e 的类型 i n t + l a t e r t y p e = g _ h a s h _ t a b l e _ l o o k u p ( e _ t y p e _ v a l u e ,t y p e t y p e ) ; i n t + b e f o r e _ t y p e 。g _ h a s h _ t a b l e _ l o o k u p ( c _ t y p e _ v a l u e ,o p o t y p e ) ; i f ( t y p e if - n u l l & & t y p e 2 = n u l l ) i f ( + l a t e r _ t y p e b e f o r e _ t y p e 、 p r i n t f _ _ e r r o r ( o p 0 n a m e ) ;r e t u r n ; ,警告有转换危险 i f ( i s _ f i r s t _ t i n f o _ c o m p a t i b l ew i t h s e c o n d ( t y p e t y p e ,o p 0 t y p e ) 1 2 1 ) 比较两个类型是否相兼容 第三章c ,c + + 中类型转换和控制流相关漏洞的分析 1 7 p r i n t f _ e r r o r ( o p o n a m e ) ; 如果不兼容则警告有转换危险 ) 以上三种都是类型转换语句,包括了显式的和隐式的类型转换,对它们的处 理都是一致的。文法符号o p o 是进行类型转型的变量,t y p e 中记录着转换后的类 型信息。 检查的过程如下:从t y p e 中使用算法g e t _ f u l l _ n a m e _ f r o mn o d e ( ) 在全局类型 信息系统中取得变量转换后的类型信息( 此算法在4 2 节中有详细的实现) ,记录到 t y p e t y p e 中。o p o t y p e 记录着变量原来的类型,这是从下面的归约中通过属性t y p e 传递上来的。 以t y p e t y p e 和o p o t y p e 为参数,在一个全局的预先存储着c 中的基本类型和 每一个类型对应的整数值的哈希表c _ t y p e _ v a l u e 中查找这两个类型所对应的整数 值。使用整型指针变量l a t e rt y p e 和b e f o r e _ t y p e 记下查找的结果,如果l a t e r _ t y p e 和b e f o r e _ t y p e 均非空,且l a t e r _ t y p e 中存储的整数值小于b e f o r et y p e 中的整数值, 则警告出现范围较大类型o p o t y p e 转换到范围较小类型t y p e t y p e 的危险。 如果查找结果l a t e r t y p e 和b e f o r et y p e 中任一个为空,表示t y p e t y p e 和 o p o t y p e 中至少有一个不是c 中的基本类型或者是u n s i g n e d 类新,则使用算法 i sf i r s tt i n f o ) 判断这两个类型是否相兼容( 此算法在c o m p a t i b l e w i t hs econd(42 节中有详细的实现) ,如果不兼容,则报告有类型转换的危险。 ( 5 ) o p o - + v a r d e c l ; o p o t y p e = g e t _ f u l l _ n a m e _ f r o mn o d e ( v a r _ d e c l t y p e ) ;取得变量的类型 o p o n a m e = g e tv

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论