• <tr id="yyy80"></tr>
  • <sup id="yyy80"></sup>
  • <tfoot id="yyy80"><noscript id="yyy80"></noscript></tfoot>
  • 99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

    一種基于棧區(qū)內(nèi)存模型的C程序別名判斷算法

    2019-02-15 09:21:38羅奇鳴李薛劍陳意云
    關(guān)鍵詞:斷言賦值指針

    常 歡,羅奇鳴,李薛劍,陳意云

    (中國(guó)科學(xué)技術(shù)大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,合肥 230026) (中國(guó)科大先進(jìn)技術(shù)研究院 中國(guó)科大國(guó)創(chuàng)高可信軟件工程中心,合肥 231283)

    1 引 言

    C語(yǔ)言因靈活高效的特性廣泛應(yīng)用于系統(tǒng)軟件的開(kāi)發(fā)中.C語(yǔ)言的指針操作沒(méi)有任何保護(hù),這給C語(yǔ)言帶來(lái)很多不安全因素,導(dǎo)致C語(yǔ)言程序容易出現(xiàn)缺陷.在軍事、航天、醫(yī)療設(shè)備、交通、能源、金融等安全攸關(guān)的應(yīng)用領(lǐng)域, 任何軟件缺陷都可能導(dǎo)致災(zāi)難性的后果,軟件工程的歷史上多次出現(xiàn)了這樣的案例.對(duì)于這些領(lǐng)域用C語(yǔ)言開(kāi)發(fā)的軟件系統(tǒng),保障其質(zhì)量(尤其是正確性和安全性)是至關(guān)重要的.

    目前在軟件產(chǎn)業(yè)界,主要的質(zhì)量保障方法包括軟件測(cè)試、靜態(tài)分析和形式化驗(yàn)證.軟件測(cè)試和靜態(tài)分析只能發(fā)現(xiàn)軟件中存在的錯(cuò)誤而無(wú)法驗(yàn)證程序功能的正確性.在靜態(tài)分析中,指針?lè)治鍪且粋€(gè)不可判定問(wèn)題[1,2].形式化驗(yàn)證可以驗(yàn)證程序的正確性,主要包括兩種方法:模型檢測(cè)[3]和演繹推理[4].模型檢測(cè)的應(yīng)用被限制在狀態(tài)空間有窮的系統(tǒng).在演繹推理中,通常用斷言表示程序中每條語(yǔ)句處的狀態(tài),由斷言根據(jù)Hoare邏輯[5]、分離邏輯[6]等規(guī)則推理得到驗(yàn)證條件交由Z3[7]等自動(dòng)定理證明器進(jìn)行證明.演繹推理的優(yōu)點(diǎn)是無(wú)誤報(bào),不要求狀態(tài)空間有窮,并且可以模塊化地進(jìn)行驗(yàn)證.

    C語(yǔ)言采用相對(duì)底層的內(nèi)存模型,指針可以指向內(nèi)存的任意位置,并可以在不同類(lèi)型之間自由轉(zhuǎn)換.C語(yǔ)言提供多種內(nèi)存操作,如多級(jí)指針間接訪問(wèn)、任意指針?biāo)阈g(shù)、數(shù)組和結(jié)構(gòu)體數(shù)據(jù)類(lèi)型.因此C語(yǔ)言程序可能發(fā)生空指針、 野指針、數(shù)組越界等多種內(nèi)存安全問(wèn)題.上述原因使得在驗(yàn)證工具內(nèi)建立C的內(nèi)存模型較為困難.

    我們之前實(shí)現(xiàn)了一個(gè)PointerC[8]語(yǔ)言程序驗(yàn)證工具,該工具基于形狀圖邏輯[9]對(duì)堆指針程序進(jìn)行驗(yàn)證.目前我們正在研發(fā)一個(gè)基于Hoare邏輯和形狀圖邏輯的安全C語(yǔ)言(以下簡(jiǎn)稱(chēng)為Safe-C)程序驗(yàn)證工具. Safe-C是C99的一個(gè)子集,是在C99的基礎(chǔ)上所設(shè)計(jì)的面向驗(yàn)證的C語(yǔ)言.

    Hoare邏輯的核心是Hoare三元組,其形式如下:

    {P} C {Q}

    (1)

    這里的P和Q是斷言而C是命令.P稱(chēng)為前斷言,Q稱(chēng)為后斷言.斷言中不同的左值表達(dá)式代表不同的存儲(chǔ)對(duì)象,而C的編程語(yǔ)言的語(yǔ)義允許存在別名,即不同的左值表達(dá)式可以代表同一個(gè)存儲(chǔ)對(duì)象.在使用Hoare邏輯的賦值規(guī)則前必須消除斷言中的別名,否則會(huì)得到錯(cuò)誤的推理結(jié)果.動(dòng)態(tài)檢測(cè)[10-11]可以通過(guò)編譯和運(yùn)行程序來(lái)獲取內(nèi)存對(duì)象的運(yùn)行時(shí)地址,但在程序驗(yàn)證中無(wú)法做到.如何在驗(yàn)證工具中消除斷言中的別名是一個(gè)技術(shù)挑戰(zhàn).

    本文的貢獻(xiàn)在于:第一,根據(jù)C語(yǔ)言的語(yǔ)義提出了一種棧區(qū)內(nèi)存模型,使程序驗(yàn)證工具能夠精確地跟蹤棧區(qū)的多種類(lèi)型的表達(dá)式,包括取地址、多級(jí)解引用、指針關(guān)系運(yùn)算、結(jié)構(gòu)體和數(shù)組等;第二,基于上述內(nèi)存模型,本文提出了一種判斷別名的算法,使得驗(yàn)證條件生成器在應(yīng)用Hoare賦值規(guī)則前準(zhǔn)確完成別名替換.

    2 Safe-C驗(yàn)證工具

    2.1 安全C語(yǔ)言與程序標(biāo)注

    Safe-C在不犧牲C語(yǔ)言靈活性的前提下,對(duì)C語(yǔ)言的各種類(lèi)型增加一些編程約束,使得程序?qū)@些類(lèi)型的變量的操作表現(xiàn)得較為規(guī)矩.約束大都針對(duì)指針類(lèi)型,要點(diǎn)如下:

    1) 把堆分配類(lèi)型及其指針和非堆分配類(lèi)型及其指針進(jìn)行區(qū)分,盡量不出現(xiàn)可同為兩者的類(lèi)型和指針.

    2) 簡(jiǎn)化堆和其他數(shù)據(jù)區(qū)的關(guān)系,盡量避免出現(xiàn)從堆指向其他數(shù)據(jù)區(qū)的指針,不濫用從其他數(shù)據(jù)區(qū)指向堆的指針.

    3) 禁止對(duì)不是指在數(shù)組區(qū)間(包括動(dòng)態(tài)分配的某類(lèi)型的若干個(gè)元素構(gòu)成的區(qū)間)的指針使用指針?biāo)阈g(shù)運(yùn)算.

    被驗(yàn)證的程序由安全C語(yǔ)言源代碼和寫(xiě)在注釋中的程序標(biāo)注兩部分組成.程序標(biāo)注是對(duì)于程序行為的形式化說(shuō)明,可用來(lái)生成驗(yàn)證條件.程序標(biāo)注需要符合形式化的語(yǔ)法和語(yǔ)義規(guī)范,為此我們參考ACSL[12]設(shè)計(jì)了面向程序驗(yàn)證的Safe-C語(yǔ)言的程序標(biāo)注規(guī)范SCSL.

    2.2 驗(yàn)證工具的主要模塊與驗(yàn)證流程

    圖1顯示了驗(yàn)證工具的主要模塊和驗(yàn)證流程見(jiàn)圖1:

    圖1 驗(yàn)證工具的主要模塊和驗(yàn)證流程 Fig.1 Modules and procedures of the Safe-C verifier

    1) 前端檢查源程序中的代碼和標(biāo)注是否符合Safe-C的要求,同時(shí)收集一些必要的全局信息,然后生成語(yǔ)法樹(shù).

    2) 驗(yàn)證條件生成器遍歷語(yǔ)法樹(shù),首先根據(jù)程序入口處的標(biāo)注產(chǎn)生入口處的斷言,隨后根據(jù)每條語(yǔ)句的演算規(guī)則進(jìn)行演算,產(chǎn)生當(dāng)前程序點(diǎn)的斷言.遇到有程序標(biāo)注的地方,會(huì)產(chǎn)生驗(yàn)證條件驗(yàn)證當(dāng)前程序點(diǎn)斷言是否滿(mǎn)足程序標(biāo)注.另外在每條語(yǔ)句的演算規(guī)則內(nèi),驗(yàn)證工具還會(huì)適時(shí)檢查程序是否可能出現(xiàn)內(nèi)存泄漏、空指針解引用、越界訪問(wèn)、運(yùn)算溢出等C語(yǔ)言程序中常見(jiàn)錯(cuò)誤.對(duì)于棧區(qū)變量與棧區(qū)指針的操作在驗(yàn)證條件生成器中處理,而將堆指針相關(guān)的操作交由形狀分析模塊處理,并將驗(yàn)證結(jié)果返回給驗(yàn)證條件生成器模塊.

    3) 驗(yàn)證條件生成器模塊產(chǎn)生的驗(yàn)證條件由斷言翻譯器模塊翻譯為定理證明器Z3可以識(shí)別的smt2文件,最終交由Z3驗(yàn)證得到驗(yàn)證結(jié)果. ·

    3 棧區(qū)內(nèi)存模型

    3.1 Hoare邏輯賦值規(guī)則與別名

    在使用Hoare邏輯對(duì)高級(jí)語(yǔ)言程序進(jìn)行演繹推理的過(guò)程中,每當(dāng)使用賦值規(guī)則

    {Q[E/x]}x=E{Q}

    (2)

    時(shí)必須保證后斷言Q和賦值語(yǔ)句x=E(E是表達(dá)式)中沒(méi)有潛在的別名,否則Q[E/x]是最弱前斷言的結(jié)論不可靠.例如,對(duì)于賦值語(yǔ)句p→data=3和后斷言p→data+q→data== 6使用Hoare邏輯的賦值公理,可得到該語(yǔ)句前斷言q→data== 3;但該語(yǔ)句的最弱前斷言是p== q‖p!= q&&q→data== 3.在此用賦值規(guī)則未能得到最弱前斷言的原因是,訪問(wèn)路徑p→data和q→data被認(rèn)為是代表不同的程序?qū)ο?,而?shí)際上若p等于q時(shí),訪問(wèn)路徑p→data和q→data互為別名,它們代表同一個(gè)程序?qū)ο?當(dāng)對(duì)p→data賦值時(shí),q→data的值也被修改了.由此可見(jiàn),程序中出現(xiàn)別名增加了程序驗(yàn)證的難度,跟蹤每個(gè)程序點(diǎn)的別名信息對(duì)基于演繹推理的程序驗(yàn)證是重要的.考慮如下的C語(yǔ)言代碼:

    int a[3]={1,2,3};

    int *p=a;

    a[2]=4;

    *(p+2)=5;

    在這段代碼中,指針p指向了數(shù)組a的首地址.指針導(dǎo)致了別名的出現(xiàn),也就是兩個(gè)左值表達(dá)式可以代表同一個(gè)內(nèi)存地址.這里*(p+2)與a[2]互為別名.

    3.2 棧區(qū)內(nèi)存模型

    堆分配和堆指針的處理采用形狀圖邏輯處理[9],本文僅討論棧區(qū)分配的變量與指針.在編程語(yǔ)言的語(yǔ)義中,通常用環(huán)境和狀態(tài)來(lái)表示變量名稱(chēng)到值的映射.環(huán)境表示將名字映射到存儲(chǔ)單元的函數(shù),

    Env=Var→loc

    (3)

    而狀態(tài)表示將存儲(chǔ)單元映射到它所保存值的函數(shù).

    Store=Loc→Value

    (4)

    C語(yǔ)言標(biāo)準(zhǔn) 將表達(dá)式分為左值表達(dá)式和右值表達(dá)式.代表內(nèi)存對(duì)象的表達(dá)式是左值表達(dá)式,其余的是右值表達(dá)式.左值相同的表達(dá)式在內(nèi)存中的存儲(chǔ)位置相同,即互為別名.因此消除別名的關(guān)鍵是精確記錄內(nèi)存對(duì)象的左值,從而判斷表達(dá)式的左值是否相同.

    根據(jù)以上思路,我們對(duì)式(3)和式(4)分別進(jìn)行擴(kuò)展,用如下兩個(gè)映射定義Safe-C的棧區(qū)內(nèi)存模型.第一個(gè)映射

    Env=LExpr→LValue

    (5)

    表示將左值表達(dá)式映射到左值的函數(shù),LExpr表示代表內(nèi)存對(duì)象的左值表達(dá)式的集合,LValue表示左值的集合.在驗(yàn)證工具內(nèi),左值不僅表示抽象的內(nèi)存地址,也包含了左值表達(dá)式的類(lèi)型(type)和長(zhǎng)度(length)信息.第二個(gè)映射

    Store=LValue→RValue

    (6)

    表示左值所代表的存儲(chǔ)單元到右值的映射,RValue表示右值的集合.這里的右值和C語(yǔ)言中的右值含義相同,在驗(yàn)證工具內(nèi)用斷言表示.

    我們用一張表來(lái)表示內(nèi)存模型所表示的映射關(guān)系,稱(chēng)作內(nèi)存表.在驗(yàn)證工具內(nèi)部,非指針的右值和指針的右值通常分開(kāi)存放,這樣方便將棧區(qū)變量的賦值與棧區(qū)指針的關(guān)系運(yùn)算分開(kāi)處理.非指針的斷言用符號(hào)斷言Q來(lái)表示,內(nèi)存表用M來(lái)表示.我們?cè)诰哂凶笾档谋磉_(dá)式名字前面加上@作為對(duì)應(yīng)表達(dá)式的左值的名稱(chēng).非數(shù)組類(lèi)型左值@x的長(zhǎng)度默認(rèn)為1,表示在內(nèi)存中占據(jù)1個(gè)x類(lèi)型的長(zhǎng)度.對(duì)于不同的左值表達(dá)式,其左值和右值有不同的產(chǎn)生規(guī)則,以下分別舉例說(shuō)明:

    1) 對(duì)于非指針類(lèi)型的變量x,為其產(chǎn)生左值@x,@x保存有x的類(lèi)型信息和長(zhǎng)度(默認(rèn)是1),x的右值保存在符號(hào)斷言Q中,不出現(xiàn)在內(nèi)存表M中.

    2) 如果是一個(gè)指針類(lèi)型變量p,則除了為其產(chǎn)生其左值@p外,還會(huì)根據(jù)其指向產(chǎn)生不同的右值.如果p是空指針或野指針,則其右值為 ull.如果p指向某個(gè)存儲(chǔ)對(duì)象,則指針的右值為存儲(chǔ)對(duì)象的左值,用函數(shù)形式的三元屬性來(lái)表示.三元屬性的定義是

    pointer(name,length,offset)

    (7)

    在前期工作[13]基礎(chǔ)上進(jìn)行改進(jìn),name不再是程序變量的名字或者是任意的虛擬名字,而是指針?biāo)赶蜃兞康淖笾?,length表示該左值的長(zhǎng)度,offset表示指針的偏移.這樣可以更清晰地記錄指針的指向信息和層級(jí)關(guān)系,從而支持多級(jí)指針間接訪問(wèn).另外,在對(duì)指針的處理中有兩種特殊的情況:

    1) 將數(shù)組名看成指向自身所在內(nèi)存區(qū)間首地址的指針.數(shù)組名本身并不是左值,不能出現(xiàn)在賦值表達(dá)式的左邊.但可以被用于取地址操作符&,所以這里將其視作特殊的左值表達(dá)式,產(chǎn)生的左值表示數(shù)組所占的內(nèi)存區(qū)間,其長(zhǎng)度是數(shù)組長(zhǎng)度.另外數(shù)組名可以像指針一樣出現(xiàn)在指針關(guān)系運(yùn)算中,為處理方便,設(shè)置數(shù)組名右值為三元屬性.其三元屬性所對(duì)應(yīng)的name是其自身對(duì)應(yīng)的左值,length為數(shù)組長(zhǎng)度,由于數(shù)組名代表數(shù)據(jù)塊首地址,故offset固定為0.

    2) 為函數(shù)入口處的形參指針額外產(chǎn)生一個(gè)特殊的左值表示其指向的存儲(chǔ)單元.這是因?yàn)轵?yàn)證工具以函數(shù)為模塊進(jìn)行驗(yàn)證,實(shí)參并不出現(xiàn)在函數(shù)內(nèi),實(shí)參所指向的存儲(chǔ)單元也不在本函數(shù)棧內(nèi).即需要為位于函數(shù)棧外的形參所指向的存儲(chǔ)單元產(chǎn)生一個(gè)特殊的左值,以避免信息的丟失.在本文中,在@和形參名之間加上符號(hào)#來(lái)表示形參指針?biāo)赶虻拇鎯?chǔ)單元.特別的,如果有多個(gè)形參指針指向相同的存儲(chǔ)單元,需要在函數(shù)的前條件中加以說(shuō)明,以確保相同的存儲(chǔ)單元只產(chǎn)生一個(gè)左值.

    3) 對(duì)于結(jié)構(gòu)體變量賦值需要將結(jié)構(gòu)體展開(kāi),看作對(duì)其每一個(gè)域的賦值.因此除了為結(jié)構(gòu)體變量產(chǎn)生左值外,還會(huì)根據(jù)每一個(gè)域的類(lèi)型,遞歸地為其每一個(gè)域產(chǎn)生左值和右值.

    4) 對(duì)于數(shù)組下標(biāo)表達(dá)式如a[i]產(chǎn)生數(shù)組名a的左值和右值信息,但并不會(huì)為a中的每一個(gè)元素產(chǎn)生左值和右值.這里我們采用一種延遲插入的方式,僅當(dāng)a中的某一元素出現(xiàn)在斷言中,我們才為其產(chǎn)生左值.這樣可以減少驗(yàn)證工具內(nèi)插入和查詢(xún)的開(kāi)銷(xiāo).

    5) 對(duì)于解引用表達(dá)式,可以將其轉(zhuǎn)化為上述的某一種左值表達(dá)式,故不再單獨(dú)討論.

    考慮如下的代碼片段:

    int x=5;

    int a[100];

    int* p=a;

    int* q;

    struct {

    int d

    } s;

    則為其產(chǎn)生的符號(hào)斷言Q和內(nèi)存表M如下:

    Q:x== 5

    M:

    LExprLValueRValuex@xa@apointer(@a,100,0)p@ppointer(@a,100,0)q@q ulls@s s.d@s.d

    3.3 驗(yàn)證點(diǎn)斷言與內(nèi)存表的構(gòu)造

    驗(yàn)證點(diǎn)是程序代碼中函數(shù)入口處、循環(huán)入口處以及其他有程序標(biāo)注的地方.當(dāng)驗(yàn)證工具演算到驗(yàn)證點(diǎn)時(shí),需要驗(yàn)證當(dāng)前程序斷言是否滿(mǎn)足驗(yàn)證點(diǎn)的標(biāo)注,然后根據(jù)標(biāo)注產(chǎn)生驗(yàn)證點(diǎn)的內(nèi)存表和程序當(dāng)前點(diǎn)的新斷言.函數(shù)入口、循環(huán)入口與其他驗(yàn)證點(diǎn)略有區(qū)別.

    3.3.1 函數(shù)入口處內(nèi)存狀態(tài)的構(gòu)造

    函數(shù)入口處的協(xié)議稱(chēng)為requires斷言,其經(jīng)過(guò)范式化后可以表示為:

    R1‖R2‖…‖Rn

    (8)

    其中每個(gè)Ri(1≤i≤n)稱(chēng)為析取子式,每一個(gè)析取子式對(duì)應(yīng)于演算過(guò)程中的一個(gè)分支,分支的程序狀態(tài)構(gòu)造如下:

    1) 將所有全局變量,函數(shù)形參變量依次填入內(nèi)存表中,并初始化所有變量的左值信息(包括變量類(lèi)型,所在數(shù)據(jù)塊大小等).

    2) 非指針變量的右值信息不需要填入表中,仍然保存在斷言中.需要修改時(shí),直接遍歷斷言語(yǔ)法樹(shù)修改即可.對(duì)于棧指針變量,需要找出程序標(biāo)注中與其相關(guān)的斷言,產(chǎn)生對(duì)應(yīng)的三元屬性,并填入內(nèi)存表中.

    我們將每一個(gè)分支的符號(hào)斷言稱(chēng)作Qi,對(duì)應(yīng)的內(nèi)存表稱(chēng)作Mi,則入口處的程序狀態(tài)可以用如下形式表示:

    (Q1&&M1)‖(Q2&&M2)‖…‖(Qn&&Mn)

    (9)

    3.3.2 循環(huán)入口處內(nèi)存狀態(tài)的構(gòu)造

    在進(jìn)入循環(huán)之前,首先要驗(yàn)證當(dāng)前斷言是否滿(mǎn)足循環(huán)不變式.即對(duì)斷言的每一個(gè)分支,產(chǎn)生如下的驗(yàn)證條件:

    Qi&&GetAssert(Mi)== >Ii‖I2‖…‖In

    (10)

    其中GetAssert()函數(shù)獲取表中的棧指針相關(guān)斷言,I1‖I2‖…‖In是范式化后的循環(huán)不變式.

    根據(jù)循環(huán)不變式生成循環(huán)入口處斷言和內(nèi)存表的方法與函數(shù)入口處的方法類(lèi)似.不同的是在循環(huán)入口處需要將局部變量也考慮進(jìn)去.其他驗(yàn)證點(diǎn)的構(gòu)造和循環(huán)入口處類(lèi)似,不同的是循環(huán)出口處需要再驗(yàn)證一次是否滿(mǎn)足循環(huán)不變式,而其他驗(yàn)證點(diǎn)通常只需要驗(yàn)證一次.

    3.4 棧區(qū)賦值語(yǔ)句規(guī)則

    3.4.1 取地址和解引用操作

    為了支持多級(jí)指針操作,需要根據(jù)內(nèi)存模型和C的語(yǔ)義定義取地址和解引用的操作規(guī)則,規(guī)則定義如下:

    LValueRValue&exprN/ALValue(expr)*exprRValue(expr)Store(RValue(expr))

    &expr是一個(gè)右值表達(dá)式,不可作為左值表達(dá)式,計(jì)算該表達(dá)式的值得到的是expr的地址(左值).

    *expr既可以是左值表達(dá)式,也可以是右值表達(dá)式,作為左值時(shí)其含義是獲取expr指針?biāo)赶虻拇鎯?chǔ)對(duì)象,作為右值時(shí)其含義是獲取指針?biāo)赶虻拇鎯?chǔ)對(duì)象所保存的值.在計(jì)算*expr表達(dá)式的值時(shí),首先需要查詢(xún)判斷expr指針是否是空指針或野指針,若是則報(bào)錯(cuò).其次需要判斷訪問(wèn)是否越界.例如對(duì)于賦值語(yǔ)句int i=*(q+j); 而言,指針q的右值為pointer(@a,100,k),表示q指向數(shù)組a的第k個(gè)位置上.則需要產(chǎn)生如下驗(yàn)證條件:

    Q&&GetAssert(M)== >0≤(k+j)<100

    如果上述蘊(yùn)含式成立,則表示訪問(wèn)合法;如果不成立,則表示訪問(wèn)越界.

    3.4.2 棧區(qū)變量賦值

    對(duì)棧區(qū)變量賦值,首先需要消除別名.需要消除別名的地方有三處,分別是保存符號(hào)斷言的Qi、內(nèi)存表中Mi中的length字段和offset字段以及賦值表達(dá)式的右子式.遍歷上述三處的每一個(gè)表達(dá)式,根據(jù)本文第4節(jié)提出的判斷別名的算法,將與被賦值表達(dá)式互為別名的表達(dá)式替換為被賦值表達(dá)式.隨后對(duì)賦值語(yǔ)句使用Hoare邏輯賦值規(guī)則在每一個(gè)分支上進(jìn)行演算,演算規(guī)則為:

    {Qi&&Mi}
    x=E
    {(Qi′&&Mi′)[x′/x]&&x== E′[x′/x]}

    (11)

    其中,Qi′、Mi′和E′分別表示消除別名后的符號(hào)斷言、內(nèi)存表和賦值表達(dá)式的右子式.x′是和x同類(lèi)型的虛擬變量, [x′/x]表示將x替換為x′.如果被賦值的表達(dá)式是結(jié)構(gòu)體變量,那么需要遞歸的對(duì)每一個(gè)域做別名替換操作.

    3.4.3 指針關(guān)系運(yùn)算

    指針關(guān)系運(yùn)算可以統(tǒng)一表示為以下形式:

    p=q+e;

    其中p和q是有左值的指針類(lèi)型訪問(wèn)路徑,e是整型表達(dá)式,"+"泛指加減運(yùn)算符.把p=q看成p=q+0的特例.

    在演算過(guò)程中,我們將指針的狀態(tài)保存在內(nèi)存表M中,符號(hào)斷言中Q不出現(xiàn)指針相關(guān)的斷言,從而簡(jiǎn)化指針賦值的處理.只需要將右表達(dá)式中的棧指針p的三元屬性的前兩個(gè)屬性復(fù)制并替換左表達(dá)式q中對(duì)應(yīng)的屬性,將右表達(dá)式指針指向的偏移與表達(dá)式e的計(jì)算結(jié)果填入左邊指針的偏移中.推理規(guī)則是:

    {Mi={…p== pointer(@v1,length1,offset1),

    q== pointer(@v2,length2,offset2)…}}

    p=q+e

    {Mi′={…p== pointer(@v2,length2,offset2+e),

    q== pointer(@v2,length2,offset2)…}}

    (12)

    其中Mi和Mi′表示賦值前后的內(nèi)存表狀態(tài),@v1和@v2分別表示語(yǔ)句執(zhí)行前p和q指向的內(nèi)存對(duì)象的左值.

    4 判斷別名的算法

    3.1節(jié)指出在使用Hoare邏輯的賦值規(guī)則前必須消除斷言中潛在的別名,否則可能導(dǎo)致推理的結(jié)果不正確.要正確的消除別名,首先要判斷兩個(gè)表達(dá)式是否為別名,即判斷兩個(gè)表達(dá)式的左值是否相同.但是內(nèi)存表中并非存有所有的左值表達(dá)式的左值,所以我們基于3.2 節(jié)的棧區(qū)內(nèi)存模型提出一種判斷兩個(gè)左值表達(dá)式是否別名的算法,如圖2 所示.

    圖2 判斷別名的算法Fig.2 Algorithm for judging aliases

    1) 復(fù)雜訪問(wèn)路徑是含多個(gè)域訪問(wèn)符的表達(dá)式,如p→a.b.其中域訪問(wèn)符包括.和→兩種.但其實(shí)p→a是(*p).a的語(yǔ)法美化,所以可以將→表示成.來(lái)統(tǒng)一處理.若兩個(gè)復(fù)雜訪問(wèn)路徑的最后一個(gè)域相同,則判斷兩個(gè)訪問(wèn)路徑的前綴是否別名.如p→a.b和q.c.b這兩個(gè)表達(dá)式的最后一個(gè)域皆為b,則判斷(*p).a和q.c的左值是否相同,若不相同則兩個(gè)表達(dá)式不為別名.

    2) 如果兩個(gè)表達(dá)式是分別是解引用和數(shù)組表達(dá)式,可以將二者統(tǒng)一為數(shù)組表達(dá)式,通過(guò)比較數(shù)組名、數(shù)組表達(dá)式的維數(shù)以及每一維的索引來(lái)判斷兩個(gè)表達(dá)式是否別名.假設(shè)p和q是棧指針,a是數(shù)組,需要比較兩個(gè)表達(dá)式*(p+3)與q[4]是否別名.內(nèi)存表中有斷言p== pointer(@a,10,1)、q== pointer(@a,10,0)和a== pointer(@a,10,0),此時(shí)可以將兩個(gè)表達(dá)式統(tǒng)一成數(shù)組表達(dá)式均為a[4].通過(guò)比較數(shù)組名稱(chēng)以及第一維的索引,可以判斷出兩個(gè)表達(dá)式互為別名.

    3) 如果兩個(gè)表達(dá)式都是簡(jiǎn)單變量,則直接比較二者左值是否相等.簡(jiǎn)單變量在此處包括全局變量、函數(shù)形參變量、局部變量、以及結(jié)構(gòu)體變量的域等.在每個(gè)程序點(diǎn)處構(gòu)造內(nèi)存模型時(shí)已經(jīng)將其加入內(nèi)存表,故可以直接通過(guò)查表判斷二者左值是否相同.

    4) 如果兩個(gè)表達(dá)式是其他類(lèi)型,則不會(huì)互為別名.

    5 驗(yàn)證實(shí)例

    我們以一個(gè)含有結(jié)構(gòu)體和二重指針等復(fù)雜數(shù)據(jù)結(jié)構(gòu)的函數(shù)為例介紹本文提出的棧區(qū)內(nèi)存模型.該函數(shù)的功能是查找一個(gè)數(shù)組中的最大值和最小值并返回,代碼顯示在圖3.我們將重點(diǎn)放在介紹內(nèi)存表的創(chuàng)建、賦值語(yǔ)句的規(guī)則以及如何利用內(nèi)存表來(lái)實(shí)現(xiàn)多級(jí)指針的訪問(wèn)和別名消除.

    圖3 包含二重指針和結(jié)構(gòu)體的函數(shù)Fig.3 Function with double pointer and structure

    在第8行函數(shù)入口處,根據(jù)函數(shù)前條件構(gòu)造函數(shù)入口處的斷言Q和內(nèi)存表M.本例中函數(shù)前條件(requires)中的標(biāo)注為size > 0 && length(a) == size.根據(jù)3.3.1小節(jié)中的規(guī)則,得到函數(shù)入口處斷言和內(nèi)存表:

    Q:size>0

    M:

    LEx-prLValueRValuea@apointer(@#a,size,0)size@size

    第9行處理變量s的聲明,對(duì)其左值進(jìn)行初始化.第10行首先聲明一個(gè)指向結(jié)構(gòu)體的指針p,并用s的地址來(lái)初始化p.第11行聲明一個(gè)二重指針q,并對(duì)數(shù)組名a取地址來(lái)初始化q.帶有初始化的聲明語(yǔ)句可以首先處理聲明,再按賦值語(yǔ)句規(guī)則處理.對(duì)于取地址表達(dá)式,利用3.4節(jié)提出的規(guī)則獲得表達(dá)式左值信息并產(chǎn)生三元屬性作為被賦值指針的右值.

    第12行和13行是兩條棧區(qū)變量的賦值語(yǔ)句,第14行是帶有初始化的聲明語(yǔ)句.對(duì)于被賦值的表達(dá)式,如果沒(méi)有出現(xiàn)在內(nèi)存表中且內(nèi)存表中有與之別名的表達(dá)式,則產(chǎn)生的符號(hào)斷言用該別名表達(dá)式;如果沒(méi)有出現(xiàn)在內(nèi)存表且沒(méi)有與之別名的表達(dá)式,則加入內(nèi)存表中.

    上述語(yǔ)句執(zhí)行結(jié)束后,得到的斷言和內(nèi)存表如下:

    Q: size>0&&s.min== (*q)[0] &&s.max== (*q)[0]&&i== 0

    M:

    LExprLValueRValuea@apointer(@#a,size,0)size@sizes@ss.max@s.maxs.min@s.minp@ppointer(@s,1,0)q@qpointer(@a,1,0)i@i

    對(duì)應(yīng)的函數(shù)的棧區(qū)狀態(tài)可以如圖4所示.

    圖4 棧區(qū)狀態(tài)Fig.4 State of the stack area

    驗(yàn)證到第17行循環(huán)入口處,我們將棧區(qū)的所有非指針變量和指針變量的斷言合并,并將斷言中的解引用表達(dá)式替換成數(shù)組表達(dá)式,驗(yàn)證是否滿(mǎn)足循環(huán)不變式.在循環(huán)入口合并后的斷言如下:

    Q:size>0 &&s.min== a[0] &&s.max== a[0] && i== 0 && a== pointer(@#a,size,0) && p== pointer(@s,1,0) && q== pointer(@a,1,0)

    當(dāng)驗(yàn)證完成后,依據(jù)循環(huán)不變式產(chǎn)生循環(huán)后的斷言和內(nèi)存表,此時(shí)的斷言已經(jīng)存在分支.在此我們以第一個(gè)分支為例繼續(xù)向下演算,這里不再展示此處的斷言和內(nèi)存表.

    第18行是一個(gè)條件語(yǔ)句,這里將產(chǎn)生分支.符合條件語(yǔ)句的分支將會(huì)在斷言中加入s.max < (*q)[i]這個(gè)斷言.在第19行賦值語(yǔ)句前,首先找出斷言中與被賦值表達(dá)式p→max別名的表達(dá)式.利用第4節(jié)提出的判斷別名算法可以判斷出s.max和p→max是別名,產(chǎn)生虛擬變量@v1替換斷言中所有的s.max.因?yàn)閟.max與p→max左值相同,且s.max已經(jīng)出現(xiàn)在內(nèi)存表中(內(nèi)存表中不會(huì)出現(xiàn)兩個(gè)互為別名的左值表達(dá)式),故用s.max替換賦值語(yǔ)句中的p→max.隨后執(zhí)行賦值語(yǔ)句.執(zhí)行完后的本分支的符號(hào)斷言和內(nèi)存表為:

    Q: size >0 && i

    M:

    LExprLValueRValuea@apointer(@#a,size,0)size@sizes@ss.max@s.maxs.min@s.minp@ppointer(@s,1,0)q@qpointer(@a,1,0)i@i

    第20行的條件語(yǔ)句會(huì)再產(chǎn)生兩個(gè)分支.執(zhí)行完第22行的賦值語(yǔ)句后,驗(yàn)證各個(gè)分支的斷言是否滿(mǎn)足循環(huán)不變式.然后以循環(huán)不變式作為程序斷言繼續(xù)演算.第24行是return語(yǔ)句,驗(yàn)證函數(shù)的返回值是否滿(mǎn)足函數(shù)的后條件.

    6 相關(guān)工作對(duì)比

    因?yàn)轵?yàn)證C語(yǔ)言相對(duì)困難,所以國(guó)際上成熟的的C語(yǔ)言驗(yàn)證工具也相對(duì)較少.在學(xué)術(shù)界,相對(duì)有影響力的研究成果有VCC[14]、Toccata[15]和VeriFast[16]等.VCC專(zhuān)注于發(fā)現(xiàn)C并發(fā)程序的中的問(wèn)題,而Toccata則將重點(diǎn)放在了精度驗(yàn)證上,二者對(duì)C的數(shù)據(jù)類(lèi)型的支持不夠完善.VeriFast相對(duì)成熟,該工具基于分離邏輯,支持豐富的斷言數(shù)據(jù)類(lèi)型和用戶(hù)自定義謂詞.而我們的驗(yàn)證工具基于Hoare邏輯和形狀圖邏輯,理論路線與之不同.有些比較有影響的驗(yàn)證工具如Spec#[17]只支持驗(yàn)證C#等沒(méi)有指針的面向?qū)ο笳Z(yǔ)言.

    如何消除C語(yǔ)言中的別名以及支持C語(yǔ)言中種類(lèi)眾多的表達(dá)式是驗(yàn)證C程序的困難之一.文獻(xiàn)[13]提出了一種三元屬性的棧指針表示方法,支持帶有一級(jí)棧指針程序的驗(yàn)證,但其對(duì)多級(jí)指針間接訪問(wèn)以及復(fù)雜數(shù)據(jù)結(jié)構(gòu)沒(méi)有支持.本文與[13]的區(qū)別在于提出了一種適用于C程序驗(yàn)證工具的棧區(qū)內(nèi)存模型,使程序驗(yàn)證工具能夠精確地跟蹤棧區(qū)多種類(lèi)型的表達(dá)式,包括取地址、多級(jí)解引用、指針關(guān)系運(yùn)算、結(jié)構(gòu)體和數(shù)組等.另外本文還給出了基于該內(nèi)存模型的別名判斷算法,使得驗(yàn)證條件生成器在應(yīng)用Hoare賦值公理前準(zhǔn)確完成別名替換.

    7 結(jié)束語(yǔ)

    目前該內(nèi)存模型已經(jīng)在Safe-C驗(yàn)證工具內(nèi)實(shí)現(xiàn).限于篇幅,本文只介紹了一個(gè)驗(yàn)證實(shí)例.Safe-C驗(yàn)證工具已經(jīng)驗(yàn)證通過(guò)了一維數(shù)組、二維數(shù)組、二重指針、易變數(shù)據(jù)結(jié)構(gòu)、棧指針、字符串等77個(gè)經(jīng)典C程序,其中包括快速排序、冒泡排序、字符串匹配等經(jīng)典算法.這些程序已經(jīng)上傳至以下網(wǎng)址:https:.github.com/huanGG/Safe-C.

    猜你喜歡
    斷言賦值指針
    關(guān)于1 1/2 … 1/n的一類(lèi)初等對(duì)稱(chēng)函數(shù)的2-adic賦值
    von Neumann 代數(shù)上保持混合三重η-*-積的非線性映射
    C3-和C4-臨界連通圖的結(jié)構(gòu)
    L-代數(shù)上的賦值
    特征為2的素*-代數(shù)上強(qiáng)保持2-新積
    偷指針的人
    Top Republic of Korea's animal rights group slammed for destroying dogs
    強(qiáng)賦值幺半群上的加權(quán)Mealy機(jī)與加權(quán)Moore機(jī)的關(guān)系*
    為什么表的指針都按照順時(shí)針?lè)较蜣D(zhuǎn)動(dòng)
    利用賦值法解決抽象函數(shù)相關(guān)問(wèn)題オ
    后天国语完整版免费观看| 91精品国产国语对白视频| 午夜福利,免费看| 美女视频免费永久观看网站| 美女高潮到喷水免费观看| 一级毛片我不卡| 视频区图区小说| 99热国产这里只有精品6| 亚洲综合色网址| 熟女少妇亚洲综合色aaa.| 五月开心婷婷网| 中文乱码字字幕精品一区二区三区| 免费久久久久久久精品成人欧美视频| 丰满人妻熟妇乱又伦精品不卡| 我要看黄色一级片免费的| 啦啦啦啦在线视频资源| 久久久欧美国产精品| cao死你这个sao货| 搡老岳熟女国产| 国产三级黄色录像| 国产精品成人在线| 久久久久久亚洲精品国产蜜桃av| 汤姆久久久久久久影院中文字幕| 在线观看一区二区三区激情| 日日夜夜操网爽| 国产亚洲午夜精品一区二区久久| 爱豆传媒免费全集在线观看| 国产成人精品久久二区二区免费| 亚洲少妇的诱惑av| 黄频高清免费视频| 女警被强在线播放| 欧美日韩国产mv在线观看视频| 国产视频一区二区在线看| 日韩一区二区三区影片| 亚洲精品av麻豆狂野| 青草久久国产| 久久精品人人爽人人爽视色| 男女床上黄色一级片免费看| 欧美黄色片欧美黄色片| 老鸭窝网址在线观看| 国产成人欧美在线观看 | 欧美日韩黄片免| 又黄又粗又硬又大视频| 一级毛片 在线播放| 丝袜人妻中文字幕| 最近最新中文字幕大全免费视频 | 久久久久久久久免费视频了| 国产一级毛片在线| 色94色欧美一区二区| 最黄视频免费看| 久久影院123| 啦啦啦在线观看免费高清www| 日本黄色日本黄色录像| 人人妻人人澡欧美一区二区| 大型黄色视频在线免费观看| 老熟妇仑乱视频hdxx| av天堂在线播放| 亚洲熟妇熟女久久| 久久久国产成人免费| 91老司机精品| 99久久久亚洲精品蜜臀av| 99热只有精品国产| 无人区码免费观看不卡| 亚洲专区字幕在线| 在线永久观看黄色视频| 视频在线观看一区二区三区| 国内精品久久久久久久电影| 香蕉国产在线看| 亚洲熟妇熟女久久| 欧美黑人精品巨大| 国产成人系列免费观看| 在线观看一区二区三区| 欧美av亚洲av综合av国产av| 黄色女人牲交| 51午夜福利影视在线观看| 性欧美人与动物交配| 欧美日本视频| 在线观看一区二区三区| 男女视频在线观看网站免费 | 亚洲性夜色夜夜综合| 男女午夜视频在线观看| 国产黄片美女视频| 99精品在免费线老司机午夜| 国产aⅴ精品一区二区三区波| 婷婷丁香在线五月| 日韩欧美国产在线观看| 精品少妇一区二区三区视频日本电影| 99在线人妻在线中文字幕| 别揉我奶头~嗯~啊~动态视频| 日日爽夜夜爽网站| 成人三级黄色视频| 日本a在线网址| 国产精品 国内视频| 日本撒尿小便嘘嘘汇集6| 久久伊人香网站| 色综合欧美亚洲国产小说| 无人区码免费观看不卡| 亚洲五月婷婷丁香| 两个人视频免费观看高清| 日本免费a在线| 国产精品久久视频播放| 日本一本二区三区精品| 欧美日韩黄片免| 日韩欧美三级三区| 亚洲九九香蕉| 亚洲专区中文字幕在线| 免费在线观看影片大全网站| 亚洲色图av天堂| 老熟妇乱子伦视频在线观看| 亚洲精品在线美女| 露出奶头的视频| av片东京热男人的天堂| av免费在线观看网站| 香蕉av资源在线| 99riav亚洲国产免费| 国产av一区在线观看免费| 人人妻人人看人人澡| 午夜激情福利司机影院| 最近最新中文字幕大全免费视频| 成人亚洲精品一区在线观看| 日本a在线网址| 国产麻豆成人av免费视频| 香蕉久久夜色| 欧美激情 高清一区二区三区| 国产成人啪精品午夜网站| 欧美不卡视频在线免费观看 | 免费女性裸体啪啪无遮挡网站| 精品日产1卡2卡| 麻豆成人av在线观看| 国产私拍福利视频在线观看| 男女之事视频高清在线观看| 久久人妻福利社区极品人妻图片| 亚洲国产欧洲综合997久久, | 中文字幕精品亚洲无线码一区 | 亚洲第一电影网av| 亚洲三区欧美一区| 国产精品免费一区二区三区在线| 欧美日韩亚洲综合一区二区三区_| 午夜福利一区二区在线看| 中文字幕av电影在线播放| 欧洲精品卡2卡3卡4卡5卡区| 99久久综合精品五月天人人| 一本精品99久久精品77| 日本免费一区二区三区高清不卡| 国产一区二区三区在线臀色熟女| 女警被强在线播放| 日本三级黄在线观看| 国产97色在线日韩免费| 大香蕉久久成人网| 一个人观看的视频www高清免费观看 | 在线天堂中文资源库| 1024视频免费在线观看| 男女之事视频高清在线观看| 99精品欧美一区二区三区四区| avwww免费| 欧美黑人欧美精品刺激| 久久久精品欧美日韩精品| 中文字幕最新亚洲高清| 麻豆成人午夜福利视频| 美女 人体艺术 gogo| 成人亚洲精品av一区二区| 亚洲一区二区三区不卡视频| 午夜福利一区二区在线看| 色精品久久人妻99蜜桃| 精品欧美一区二区三区在线| 人妻久久中文字幕网| 十八禁人妻一区二区| 两个人视频免费观看高清| 真人一进一出gif抽搐免费| 禁无遮挡网站| 精品久久蜜臀av无| 日日摸夜夜添夜夜添小说| 女性被躁到高潮视频| 色哟哟哟哟哟哟| 欧美av亚洲av综合av国产av| 国产精品二区激情视频| 国产高清视频在线播放一区| 老司机靠b影院| 日韩精品青青久久久久久| 亚洲成av片中文字幕在线观看| 女性生殖器流出的白浆| 色精品久久人妻99蜜桃| 久久青草综合色| 午夜福利18| 久久久久久国产a免费观看| av视频在线观看入口| 午夜影院日韩av| 国产高清激情床上av| 可以在线观看毛片的网站| 日韩大码丰满熟妇| 欧美黄色淫秽网站| 久久精品91蜜桃| 国产精品精品国产色婷婷| 亚洲第一电影网av| 国产av在哪里看| 99久久无色码亚洲精品果冻| 9191精品国产免费久久| 国产成人系列免费观看| 哪里可以看免费的av片| 搡老妇女老女人老熟妇| 欧美激情高清一区二区三区| 人成视频在线观看免费观看| 中国美女看黄片| 成熟少妇高潮喷水视频| 成人精品一区二区免费| 精品电影一区二区在线| 久久亚洲精品不卡| 久9热在线精品视频| 久久精品国产亚洲av高清一级| 男人的好看免费观看在线视频 | 男女那种视频在线观看| 色婷婷久久久亚洲欧美| 日本五十路高清| 亚洲久久久国产精品| 亚洲精品久久成人aⅴ小说| 在线免费观看的www视频| 久久人妻福利社区极品人妻图片| 高潮久久久久久久久久久不卡| 亚洲国产毛片av蜜桃av| 国产亚洲av嫩草精品影院| 久久精品亚洲精品国产色婷小说| 国产精品九九99| 亚洲av电影不卡..在线观看| 人人妻,人人澡人人爽秒播| 一个人观看的视频www高清免费观看 | 国产亚洲精品av在线| 亚洲电影在线观看av| 黑人欧美特级aaaaaa片| 白带黄色成豆腐渣| 日韩 欧美 亚洲 中文字幕| 国产精品二区激情视频| 香蕉国产在线看| 亚洲第一av免费看| 最好的美女福利视频网| 精品乱码久久久久久99久播| 俄罗斯特黄特色一大片| 热99re8久久精品国产| 黄色毛片三级朝国网站| 亚洲专区字幕在线| 老汉色∧v一级毛片| 免费av毛片视频| 久久性视频一级片| 窝窝影院91人妻| 精品人妻1区二区| 日韩高清综合在线| 亚洲午夜精品一区,二区,三区| 变态另类丝袜制服| 日本一本二区三区精品| 午夜福利一区二区在线看| 国产欧美日韩一区二区精品| www日本在线高清视频| 老汉色av国产亚洲站长工具| 中文字幕最新亚洲高清| 草草在线视频免费看| 美女 人体艺术 gogo| 一区二区三区激情视频| 欧美黑人巨大hd| 亚洲国产日韩欧美精品在线观看 | 成人国语在线视频| 此物有八面人人有两片| 午夜免费激情av| 又黄又粗又硬又大视频| 视频区欧美日本亚洲| 久久久久精品国产欧美久久久| 黄网站色视频无遮挡免费观看| 亚洲精品美女久久久久99蜜臀| 国产精品 国内视频| 亚洲免费av在线视频| 日韩大尺度精品在线看网址| 看片在线看免费视频| 老汉色∧v一级毛片| 久久精品国产亚洲av香蕉五月| 精品久久久久久久毛片微露脸| 欧美成人一区二区免费高清观看 | 久久精品国产亚洲av香蕉五月| 99久久国产精品久久久| 好看av亚洲va欧美ⅴa在| 2021天堂中文幕一二区在线观 | 两个人视频免费观看高清| 亚洲精品久久国产高清桃花| 亚洲aⅴ乱码一区二区在线播放 | 日韩高清综合在线| 亚洲天堂国产精品一区在线| 欧美在线黄色| 中出人妻视频一区二区| 在线视频色国产色| e午夜精品久久久久久久| 欧美日韩黄片免| 亚洲精华国产精华精| 成人av一区二区三区在线看| 免费在线观看影片大全网站| 久久这里只有精品19| 成人三级做爰电影| 欧美亚洲日本最大视频资源| 男人的好看免费观看在线视频 | 亚洲精品一区av在线观看| 给我免费播放毛片高清在线观看| 亚洲成人免费电影在线观看| 亚洲精品久久国产高清桃花| 在线观看66精品国产| 国产高清有码在线观看视频 | 日本a在线网址| 大香蕉久久成人网| 欧洲精品卡2卡3卡4卡5卡区| 老司机深夜福利视频在线观看| 久久久国产欧美日韩av| 国产精品日韩av在线免费观看| 18禁黄网站禁片午夜丰满| 国产精品99久久99久久久不卡| 国产伦人伦偷精品视频| 欧美日本视频| 久久99热这里只有精品18| 亚洲七黄色美女视频| 欧美日韩一级在线毛片| 成人欧美大片| 国产精品99久久99久久久不卡| 亚洲国产看品久久| 精品免费久久久久久久清纯| 成年免费大片在线观看| av免费在线观看网站| 日日干狠狠操夜夜爽| 国产一区在线观看成人免费| av在线天堂中文字幕| 国产av又大| 亚洲人成网站高清观看| 亚洲熟女毛片儿| 亚洲精品粉嫩美女一区| 亚洲一卡2卡3卡4卡5卡精品中文| 日本一本二区三区精品| 久久人人精品亚洲av| 操出白浆在线播放| 欧美+亚洲+日韩+国产| 国产精华一区二区三区| 波多野结衣巨乳人妻| 999久久久国产精品视频| 在线免费观看的www视频| 欧美成人性av电影在线观看| 国产区一区二久久| 老司机深夜福利视频在线观看| av天堂在线播放| 亚洲国产精品成人综合色| 人人妻人人看人人澡| 国产一区二区激情短视频| 脱女人内裤的视频| 国产一区二区在线av高清观看| 久久久久久久久免费视频了| 十八禁网站免费在线| 亚洲在线自拍视频| АⅤ资源中文在线天堂| 久久国产亚洲av麻豆专区| 国产一区二区在线av高清观看| 精品久久久久久久久久久久久 | 国产av在哪里看| 久久久久久久午夜电影| 免费在线观看黄色视频的| 亚洲 欧美一区二区三区| 色在线成人网| 99国产精品一区二区蜜桃av| www.精华液| 亚洲人成网站在线播放欧美日韩| 精品久久久久久久毛片微露脸| 一区二区三区国产精品乱码| 黄色视频,在线免费观看| 黑人操中国人逼视频| a级毛片a级免费在线| 色播在线永久视频| 欧美激情高清一区二区三区| 亚洲最大成人中文| 99国产综合亚洲精品| 国产在线精品亚洲第一网站| 一进一出抽搐gif免费好疼| 国产欧美日韩精品亚洲av| 青草久久国产| 黄色a级毛片大全视频| 亚洲全国av大片| 天堂动漫精品| 别揉我奶头~嗯~啊~动态视频| 搞女人的毛片| 中文字幕人妻丝袜一区二区| 91大片在线观看| 99热只有精品国产| 日日夜夜操网爽| 亚洲,欧美精品.| 在线av久久热| 欧美不卡视频在线免费观看 | 老司机靠b影院| 丰满的人妻完整版| 国产亚洲av嫩草精品影院| 9191精品国产免费久久| 精华霜和精华液先用哪个| 高清毛片免费观看视频网站| 搞女人的毛片| 国产精品久久久久久人妻精品电影| 亚洲色图av天堂| 最近最新免费中文字幕在线| 亚洲精品在线美女| 国产精品美女特级片免费视频播放器 | 精品国产一区二区三区四区第35| 1024手机看黄色片| 亚洲av五月六月丁香网| 欧美黄色片欧美黄色片| a在线观看视频网站| 高清在线国产一区| 老熟妇仑乱视频hdxx| 黄色视频,在线免费观看| 亚洲第一电影网av| 日本免费一区二区三区高清不卡| 免费女性裸体啪啪无遮挡网站| 久久热在线av| 日本五十路高清| 成人手机av| 妹子高潮喷水视频| 免费在线观看黄色视频的| 欧美又色又爽又黄视频| 久久久久国产一级毛片高清牌| avwww免费| 亚洲一区高清亚洲精品| 自线自在国产av| 亚洲国产精品成人综合色| av福利片在线| 黑人操中国人逼视频| 国产又爽黄色视频| 亚洲国产欧美一区二区综合| 国产97色在线日韩免费| 又黄又粗又硬又大视频| 亚洲第一av免费看| а√天堂www在线а√下载| 夜夜躁狠狠躁天天躁| 在线永久观看黄色视频| 欧美一级毛片孕妇| 天天躁夜夜躁狠狠躁躁| 女生性感内裤真人,穿戴方法视频| 国产国语露脸激情在线看| 欧美国产精品va在线观看不卡| 日韩欧美一区视频在线观看| 丝袜人妻中文字幕| netflix在线观看网站| 国产一卡二卡三卡精品| 成人亚洲精品av一区二区| 国产av一区二区精品久久| 91大片在线观看| 久久久水蜜桃国产精品网| 男女那种视频在线观看| 婷婷六月久久综合丁香| 可以免费在线观看a视频的电影网站| 久热爱精品视频在线9| 一区福利在线观看| 欧美色视频一区免费| 无限看片的www在线观看| 国产精品一区二区三区四区久久 | 一级毛片精品| 每晚都被弄得嗷嗷叫到高潮| 在线观看免费日韩欧美大片| 窝窝影院91人妻| 亚洲精品久久成人aⅴ小说| 别揉我奶头~嗯~啊~动态视频| av在线天堂中文字幕| 久久热在线av| 男人舔女人下体高潮全视频| 18禁黄网站禁片午夜丰满| 中文字幕精品免费在线观看视频| 国产成年人精品一区二区| 亚洲avbb在线观看| 丝袜在线中文字幕| 久久亚洲真实| 无限看片的www在线观看| a级毛片a级免费在线| 不卡av一区二区三区| 视频在线观看一区二区三区| 999久久久国产精品视频| 国产成人欧美在线观看| 欧美在线黄色| 淫妇啪啪啪对白视频| 亚洲av日韩精品久久久久久密| 亚洲va日本ⅴa欧美va伊人久久| 亚洲精华国产精华精| 免费在线观看影片大全网站| 欧美中文日本在线观看视频| 午夜免费观看网址| 久久国产亚洲av麻豆专区| 18禁美女被吸乳视频| 午夜两性在线视频| 三级毛片av免费| 国产精品久久久av美女十八| 最近最新中文字幕大全电影3 | 在线av久久热| 亚洲成人国产一区在线观看| 亚洲av成人一区二区三| 免费人成视频x8x8入口观看| 在线观看www视频免费| 很黄的视频免费| 亚洲片人在线观看| 欧美久久黑人一区二区| 欧美日韩中文字幕国产精品一区二区三区| 女性被躁到高潮视频| 两性夫妻黄色片| 人人妻人人澡欧美一区二区| 黄色丝袜av网址大全| av有码第一页| 曰老女人黄片| 夜夜爽天天搞| 亚洲av五月六月丁香网| 男女视频在线观看网站免费 | 欧美国产精品va在线观看不卡| 久久久久久久久久黄片| 成年免费大片在线观看| 久久久久久免费高清国产稀缺| 日日干狠狠操夜夜爽| 国产亚洲精品综合一区在线观看 | 美女免费视频网站| 最新在线观看一区二区三区| 亚洲五月色婷婷综合| 国产极品粉嫩免费观看在线| 午夜a级毛片| 黑人欧美特级aaaaaa片| 国产一卡二卡三卡精品| 色尼玛亚洲综合影院| 97人妻精品一区二区三区麻豆 | 精品久久久久久成人av| 亚洲专区中文字幕在线| 久久久久国内视频| 欧美国产精品va在线观看不卡| 久久久久久久午夜电影| 国产精品一区二区免费欧美| 1024香蕉在线观看| 中文在线观看免费www的网站 | 十八禁人妻一区二区| 女同久久另类99精品国产91| 亚洲精华国产精华精| 国产精品国产高清国产av| 国产一区二区激情短视频| 中出人妻视频一区二区| 久久精品人妻少妇| 久久亚洲真实| 757午夜福利合集在线观看| 久久久精品欧美日韩精品| 亚洲精品av麻豆狂野| АⅤ资源中文在线天堂| 国产激情欧美一区二区| 老汉色av国产亚洲站长工具| 亚洲在线自拍视频| 婷婷六月久久综合丁香| 91麻豆av在线| 97人妻精品一区二区三区麻豆 | 熟女少妇亚洲综合色aaa.| 巨乳人妻的诱惑在线观看| 国产日本99.免费观看| 亚洲自拍偷在线| 首页视频小说图片口味搜索| 国产高清视频在线播放一区| bbb黄色大片| 成人国产一区最新在线观看| 女警被强在线播放| 亚洲专区中文字幕在线| 好男人在线观看高清免费视频 | 久久久久国内视频| 91字幕亚洲| 精品久久久久久久久久久久久 | 亚洲精品av麻豆狂野| 69av精品久久久久久| 亚洲专区中文字幕在线| 丰满人妻熟妇乱又伦精品不卡| 亚洲狠狠婷婷综合久久图片| 色婷婷久久久亚洲欧美| 午夜福利在线观看吧| 黄网站色视频无遮挡免费观看| 18禁裸乳无遮挡免费网站照片 | 搡老岳熟女国产| 99久久综合精品五月天人人| 亚洲国产精品999在线| 在线av久久热| 天天躁狠狠躁夜夜躁狠狠躁| 国产亚洲欧美98| 亚洲专区中文字幕在线| 制服诱惑二区| 白带黄色成豆腐渣| 成人午夜高清在线视频 | 非洲黑人性xxxx精品又粗又长| 国产av一区二区精品久久| 搡老熟女国产l中国老女人| 亚洲国产精品成人综合色| 亚洲中文字幕日韩| 男人操女人黄网站| 免费在线观看影片大全网站| 欧美成狂野欧美在线观看| 亚洲五月色婷婷综合| 日韩大码丰满熟妇| 亚洲五月色婷婷综合| 视频在线观看一区二区三区| 亚洲五月色婷婷综合| 一本久久中文字幕| 国产乱人伦免费视频| 在线观看午夜福利视频| 老汉色∧v一级毛片| 一级作爱视频免费观看| 国产三级在线视频| 亚洲精品国产一区二区精华液| 亚洲成人国产一区在线观看| 国产久久久一区二区三区| 啦啦啦免费观看视频1| 精品欧美一区二区三区在线| 2021天堂中文幕一二区在线观 | 精品福利观看| 18禁裸乳无遮挡免费网站照片 | www日本黄色视频网| 黄色丝袜av网址大全| 午夜亚洲福利在线播放| 一边摸一边做爽爽视频免费| 精品无人区乱码1区二区| 99re在线观看精品视频| 观看免费一级毛片| 琪琪午夜伦伦电影理论片6080| 韩国av一区二区三区四区| 日本a在线网址| 在线观看66精品国产|