日韩欧美自拍在线观看-欧美精品在线看片一区二区-高清性视频一区二区播放-欧美日韩女优制服另类-国产精品久久久久久av蜜臀-成人在线黄色av网站-肥臀熟妇一区二区三区-亚洲视频在线播放老色-在线成人激情自拍视频

探討指針、結(jié)構(gòu)體、聯(lián)合體的安全規(guī)范

出處:清華大學(xué) 張樂平 邵貝貝 發(fā)布于:2011-09-02 15:10:17

  在信息工程中指針是一個用來指示一個內(nèi)存地址的計算機(jī)語言的變量或中央處理器(CPU)中寄存器(Register)。指針一般出現(xiàn)在比較近機(jī)器語言的語言,如匯編語言或C語言。面向?qū)ο蟮恼Z言如Java一般避免用指針。指針一般指向一個函數(shù)或一個變量。在使用一個指針時,一個程序既可以直接使用這個指針?biāo)鶅Υ娴膬?nèi)存地址,又可以使用這個地址里儲存的變量或函數(shù)的值。指針賦予了C編程的靈活性;結(jié)構(gòu)體使得C程序整齊而緊湊;聯(lián)合體在某些要求注重效率的場合有精彩的表現(xiàn),這三個要素是C語言的精華。

  然而,精華并不意味著完美,C語言在賦予程序員足夠靈活性的同時,也給了程序員很多犯錯誤的機(jī)會。C語言是一種計算機(jī)程序設(shè)計語言。它既具有語言的特點(diǎn),又具有匯編語言的特點(diǎn)。它可以作為工作系統(tǒng)設(shè)計語言,編寫系統(tǒng)應(yīng)用程序,也可以作為應(yīng)用程序設(shè)計語言,編寫不依賴計算機(jī)硬件的應(yīng)用程序。因此,它的應(yīng)用范圍廣泛,不僅僅是在軟件開發(fā)上,而且各類科研都需要用到C語言,具體應(yīng)用比如單片機(jī)以及嵌入式系統(tǒng)開發(fā)。C語言發(fā)展如此迅速,而且成為的語言之一,主要因為它具有強(qiáng)大的功能。許多著名的系統(tǒng)軟件,如DBASE Ⅳ都是由C 語言編寫的。用C 語言加上一些匯編語言子程序,就更能顯示C 語言的優(yōu)勢了,像PC- DOS 、WORDSTAR等就是用這種方法編寫的。

  在此。部分介紹《MISRA—C:2004》中與指針相關(guān)的部分規(guī)則,第二部分講解結(jié)構(gòu)體和聯(lián)合體的操作規(guī)范。

  1  指針的安全規(guī)范

  《MISRA—C:2004》關(guān)于指針的規(guī)范主要分為三個部分:指針的類型轉(zhuǎn)換規(guī)則、指針運(yùn)算的規(guī)則和指針的有效性規(guī)則。

  1.1  指針的類型轉(zhuǎn)換

  指針類型轉(zhuǎn)換是個高風(fēng)險的操作,所以應(yīng)該盡量避免進(jìn)行這個操作。MISRA—C對其中可能造成嚴(yán)重錯誤的情況作了嚴(yán)格的限定,選擇其中兩條作簡要分析。

  規(guī)則11.4(推薦):指向不同數(shù)據(jù)類型的指針之間不能相互轉(zhuǎn)換。

  思考如下程序:

  uint8_t*pl;

  uint32)_t*p2;

  p2=(uint32_t*)pl;

  /*注:uint8_t表示8位無符號整型,uint3_t表示32位無符號整型。*/

  程序員希望將從p1單元開始的4個字節(jié)組成一個32付的整型來參與運(yùn)算。

  中央處理器(英文Central Processing Unit,CPU)是一臺計算機(jī)的運(yùn)算和控制。CPU、內(nèi)部存儲器和輸入/輸出設(shè)備是電子計算機(jī)三大部件。電腦中所有操作都由CPU負(fù)責(zé)讀取指令,對指令譯碼并執(zhí)行指令的部件。其功能主要是解釋計算機(jī)指令以及處理計算機(jī)軟件中的數(shù)據(jù)。所謂的計算機(jī)的可編程性主要是指對CPU的編程。 CPU由運(yùn)算器、控制器和寄存器及實現(xiàn)它們之間聯(lián)系的數(shù)據(jù)、控制及狀態(tài)的總線構(gòu)成。差不多所有的CPU的運(yùn)作原理可分為四個階段:提取(Fetch)、解碼(Decode)、執(zhí)行(Execute)和寫回(Writeback)。如果CPU允許各種數(shù)據(jù)對象存放在任意的存儲單元,則以上轉(zhuǎn)換沒有問題。

  規(guī)則1 1.5:指針轉(zhuǎn)換過程中不允許丟失指針的const、volatile屬性。按如下定義指針:

  uIntl6一t    x;

  uint16_t*const  cpi=&x;  /*const指針*/

  uintl6_t*const  *pcpi;    /*指向const指針的指針*/

  const uintl6_t*  *ppci;    /*指向const整型指針的指針*/

  uIntl6_t*    *ppi ;

  const  uint16_t   *pci;    /*指向const整型的指針*/

  volatik uint16_t    *pvi;    /*指向volatile整型的指針*/

  uintl6_t    *pi;

  則以下指針轉(zhuǎn)換是允許的:

  pl=cpi;

  以下指針轉(zhuǎn)換是不允許的:

  pi=(umtl6_t*)pci;

  pi=(uintl6_t*)pvil

  ppi=(uintl6_t* *)pcpi;

  ppi=(uintl6_I**)ppci+

  以上非法指針類型轉(zhuǎn)換將會丟失const或者volatile類型。丟失const屬性,將有可能導(dǎo)致在對只讀內(nèi)容進(jìn)行寫操作時,編譯器不會發(fā)出警告,編譯器將不對具有volatile屬性的變量作優(yōu)化;丟失volatile屬性,編譯器的優(yōu)化可能導(dǎo)致程序員預(yù)先設(shè)計的硬件時序操作失。

  1.2  指針的運(yùn)算

  由于互聯(lián)網(wǎng)用戶的急劇增加及應(yīng)用范圍的不斷擴(kuò)大,一個以制定互聯(lián)網(wǎng)相關(guān)標(biāo)準(zhǔn)及推廣應(yīng)用為目的的互聯(lián)網(wǎng)用戶協(xié)會ISCO應(yīng)用而生,它標(biāo)志著互聯(lián)網(wǎng)開始真正向商用過渡。ISOC(國際互聯(lián)網(wǎng)協(xié)會)是一個非政府、非營利性的行業(yè)性國際組織,總部及秘書處設(shè)在美國弗吉尼亞州萊斯頓地區(qū)(Reston)并在美國華盛頓和瑞士日內(nèi)瓦設(shè)有辦事處。協(xié)會的目標(biāo)是保證互聯(lián)網(wǎng)的開放發(fā)展并為全人類服務(wù)。ISOC標(biāo)準(zhǔn)中,對指向數(shù)組成員的指針運(yùn)算(包括算術(shù)運(yùn)算、比較等)做了規(guī)范定義,除此以外的指針運(yùn)算屬于未定義(undefined)范圍,具體實現(xiàn)有賴于具體編譯器,其安全性無法得到保障,MISRA—C中對指針運(yùn)算的合法范圍做了如下限定。

  規(guī)則17.1:只有指向數(shù)組的指針才允許進(jìn)行算術(shù)運(yùn)算①。

  規(guī)則17 2:只有指向同一個數(shù)組的兩個指針才允許相減 ②。

  規(guī)則17 3:只有指向同一個數(shù)組的兩個指針才允許用>,>=,<,<=等關(guān)系運(yùn)算符進(jìn)行比較。

  為了盡可能減少直接進(jìn)行指針運(yùn)算帶來的隱患,尤其是程序動態(tài)運(yùn)行時可能發(fā)生的數(shù)組越界等問題,MISRA—C對指針運(yùn)算作了更為嚴(yán)格的規(guī)定。規(guī)則17 4:只允許用數(shù)組索引做指針運(yùn)算。按如下方式定義數(shù)組和指針:

  uint8_t    a[10];

  uint8_t    *p;

  則*(p+5)=O是不允許的。而p[5]=O則是允許的,盡管就這段程序而言,二者等價。

  以下給出一段程序,讀者可參照相應(yīng)程序行的注釋,細(xì)細(xì)品味上述規(guī)則的含義。

  void my_fn(uInt*_t*p1.uint8_t p2[]);

  ①其實此處的算術(shù)運(yùn)算僅限定于指針加減某個整數(shù)。比如ppoint=point一5.ppoint++等。0兩個指針可指向不同的散組成員。

  uint8_t index=0;

  uint8_t    *p3

  uint8_t    *p4;

  *pl=O;

  p1++;    /*不允許,pl不是指向數(shù)組的指針*/

  p1=p1+5;/*不允許,pl不是指向數(shù)組的指針*/

  pl[5]=O;  /*不允許,p1不是指向數(shù)組的指針*/

  p3=&p1[5];/*不允許,pl不是指向數(shù)組的指針*/

  p2[0]=O;

  index++;

  index=index+5:

  p2[index]=0;    /*允許*/

  *(p2+index)=O;  /*不允許*/

  p4=&p2[5];    /*允許*/

  }

  1.3  指針的有效性

  下面介紹《MISRA—C:2004》中關(guān)于指針有效性的規(guī)則。

  規(guī)則17 6:動態(tài)分配對象的地址不允許在本對象消亡后傳給另外一個對象。

  這條規(guī)則的實際意義是不允許將棧對象的地址傳給外部作用域的對象。

  請看以下這段程序:

  #include″stdi0.h″

  char*getm(void){

  char p[]=″hello world″;

  return p;

  intmain(){

  char* str=NULL;

  str=getm();

  printf(str);

  程序員希望的輸出結(jié)果是″hello world″這個字符串,然而實際運(yùn)行時,卻出現(xiàn)亂碼(具體內(nèi)容依賴于編譯環(huán)境)。

  簡單分析一下,由于chat p[]=″hell0 world″這條語句是在棧中分配空間存儲″hell0 world″這個字符串,當(dāng)函數(shù)getm()返回的時候,已分配的空間將會被釋放(但內(nèi)容并不會被銷毀),而priM(str)涉及系統(tǒng)調(diào)用,有數(shù)據(jù)壓棧,會修改從前分配給數(shù)組p[]存儲空間的內(nèi)容,導(dǎo)致程序無法得到預(yù)期的效果。

  倘若將getm()函數(shù)體中的char p[]=″hell0 world″程序行改成char*q=″hello world″,則執(zhí)行main( )的時候可以正確輸出″hello world″,這是由于q指向的是靜態(tài)數(shù)據(jù)區(qū),而非棧中的某個單元。

  所以,數(shù)組名是指針不假,但在實現(xiàn)細(xì)節(jié)上還是有很大的差異,程序員在使用指針的時候必須慎之又慎。

  2  結(jié)構(gòu)體、聯(lián)合體的安全規(guī)范

  規(guī)則18 4:不允許使用聯(lián)合體。這是一個不太近情理的規(guī)定,在具體闡述為何《MIS—RA—C:2004》如此“痛恨”聯(lián)合體之前,首先需要明確與聯(lián)合體相關(guān)的細(xì)節(jié):

  ①聯(lián)合體的末尾有多少個填充單元?

  ②聯(lián)合體中的各個成員如何對齊?

  ③多字節(jié)的數(shù)據(jù)類型高低字節(jié)如何排放順序?

  ④如果包含位字段(bit—field),各位如何排放順序?

  針對細(xì)節(jié)3舉個例子。

  程序段2.1

  typedef union{

  uilat32_t word;

  uint8_t bytes[4];

  }word_msg_t;

  unit32_t read_nasg(void){

  word_rnsg_t tmp;

  /*注:tmn bvte[O]對府干tmp.word的高8位,tmp  byter[l]對應(yīng)于

  tmp.WOfO的次高8位,依次類推。*/

  tmp.bytes[O]=read_byte();

  tmp.bytes[1]=read_byte();

  tmp.bytes[2]=read_byte();

  tmp.bytes[3]=read_byte();

  retlarn(trap.word);

  }

  以上代碼格式在各種通信協(xié)議中使用的頻率很高,接收端接收到的數(shù)據(jù)一般都以字節(jié)為單位存放,主控程序需要根據(jù)相應(yīng)的協(xié)議將接收到的多個字節(jié)進(jìn)行組合。為了實現(xiàn)相同的功能,《MISRA-C:2004》推薦了read_msg()函數(shù)的另外一種寫法。

  程序段2.2

  uint32_trcad_msg(void){

  uint32_t word;

  Word=((unit32_t)read_byte())《24;

  word=word│(((unit32_t)read_byte())《16);

  word=word│(((unit32_t)read_byted_byte《8);

  word=word│(((unit32_t)read_byte());

  return(word):

  }

  無論從程序的清晰程度還是執(zhí)行效率來講,程序段2.1都優(yōu)于程序段2.2。然而,程序段2.1在Intel 80x86/Pentlurn體系(1ittle—endian,存儲多字節(jié)整數(shù)的時候低字節(jié)存放在低地址,高字節(jié)存放在高地址)CPU中和在Mo—torola 68K體系(big—endian,存儲多字節(jié)整數(shù)的時候高字節(jié)存放在低地址,低字節(jié)存放在高地址)cPu中的執(zhí)行結(jié)果完全不一樣。假設(shè)read_byte()函數(shù)返回的數(shù)據(jù)依次是0x01、0x02、0x03和0x04,則在Intel體系中,程序段2.1中read_msg()函數(shù)的返回值是0x432l;在Motorola體系中,read_msg()的返回值是0x1234。

  無論在Intel體系還是Motorola體系中,程序段2.2中read_msg()的返回值都是0x1 234。

  以上是聯(lián)合體中多字節(jié)整型字節(jié)排放順序不定導(dǎo)致漏洞的一個例子。倘若不明確聯(lián)合體末尾填充的細(xì)節(jié),或者不清楚聯(lián)合體成員的對齊方式,或者不注意聯(lián)合體中位字段成員的位排列次序,都有可能導(dǎo)致錯誤。

  然而,聯(lián)合體畢竟是C語言的一個重要元素,所以MISRA—C主張禁止使用聯(lián)合體的同時,也為效率和資源要求比較苛刻的情況開了一扇門,程序員在明確聯(lián)合體各個實現(xiàn)細(xì)節(jié)的前提下,在萬不得已的時候,仍可謹(jǐn)慎使用聯(lián)合體,在不同體系的CPU間移植程序的時候要注意做相應(yīng)的修改。

  此外,《MISRA—C:2004》中也對結(jié)構(gòu)體和聯(lián)合體的編程風(fēng)格作了限定。

  規(guī)則18 1:所有結(jié)構(gòu)體和聯(lián)合體的定義必須保證完整性。

  由于涉及ISOC中類型定義完整性等概念,礙于篇幅的原因,此處就不再贅述,讀者可以參閱《MISRA-C:2004》一書和ISOC標(biāo)準(zhǔn)以了解更多信息,完善自己的編程風(fēng)格。

  3  小  結(jié)

  總而言之,對于C程序中為靈活的指針、結(jié)構(gòu)體和聯(lián)合體,程序員不僅僅要關(guān)注其定義和操作的一般方法,更要注重實現(xiàn)的細(xì)節(jié)。由于指針、聯(lián)合體等的功能性錯誤一般都可以逃過編譯器的檢查。



  

版權(quán)與免責(zé)聲明

凡本網(wǎng)注明“出處:維庫電子市場網(wǎng)”的所有作品,版權(quán)均屬于維庫電子市場網(wǎng),轉(zhuǎn)載請必須注明維庫電子市場網(wǎng),http://hbjingang.com,違反者本網(wǎng)將追究相關(guān)法律責(zé)任。

本網(wǎng)轉(zhuǎn)載并注明自其它出處的作品,目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點(diǎn)或證實其內(nèi)容的真實性,不承擔(dān)此類作品侵權(quán)行為的直接責(zé)任及連帶責(zé)任。其他媒體、網(wǎng)站或個人從本網(wǎng)轉(zhuǎn)載時,必須保留本網(wǎng)注明的作品出處,并自負(fù)版權(quán)等法律責(zé)任。

如涉及作品內(nèi)容、版權(quán)等問題,請在作品發(fā)表之日起一周內(nèi)與本網(wǎng)聯(lián)系,否則視為放棄相關(guān)權(quán)利。

廣告
OEM清單文件: OEM清單文件
*公司名:
*聯(lián)系人:
*手機(jī)號碼:
QQ:
有效期:

掃碼下載APP,
一鍵連接廣大的電子世界。

在線人工客服

買家服務(wù):
賣家服務(wù):
技術(shù)客服:

0571-85317607

網(wǎng)站技術(shù)支持

13606545031

客服在線時間周一至周五
9:00-17:30

關(guān)注官方微信號,
第一時間獲取資訊。

建議反饋

聯(lián)系人:

聯(lián)系方式:

按住滑塊,拖拽到最右邊
>>
感謝您向阿庫提出的寶貴意見,您的參與是維庫提升服務(wù)的動力!意見一經(jīng)采納,將有感恩紅包奉上哦!