• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            使您的軟件運行起來: 防止緩沖區(qū)溢出

            http://www.ibm.com/developerworks/cn/security/buffer-defend/index.html#resources

            上一篇專欄文章中,描述了高水平的緩沖區(qū)溢出攻擊,以及討論了為什么緩沖區(qū)溢出是如此嚴(yán)重的安全性問題。本專欄文章的主題是,通過防御性編程保護代碼不受緩沖區(qū)溢出攻擊。我們將論及 C 編程語言中的主要安全性陷阱,顯示應(yīng)該避免特殊構(gòu)造的原因,以及演示推薦的編程實踐。最后,將討論有助于有效防止緩沖區(qū)溢出的其它技術(shù)。

            C 中大多數(shù)緩沖區(qū)溢出問題可以直接追溯到標(biāo)準(zhǔn) C 庫。最有害的罪魁禍?zhǔn)资遣贿M行自變量檢查的、有問題的字符串操作(strcpy、strcat、sprintf 和 gets)。一般來講,象“避免使用 strcpy()”和“永遠不使用 gets()”這樣嚴(yán)格的規(guī)則接近于這個要求。

            今天,編寫的程序仍然利用這些調(diào)用,因為從來沒有人教開發(fā)人員避免使用它們。某些人從各處獲得某個提示,但即使是優(yōu)秀的開發(fā)人員也會被這弄糟。他們也許在危險函數(shù)的自變量上使用自己總結(jié)編寫的檢查,或者錯誤地推論出使用潛在危險的函數(shù)在某些特殊情況下是“安全”的。

            第一位公共敵人是 gets()。永遠不要使用 gets()。該函數(shù)從標(biāo)準(zhǔn)輸入讀入用戶輸入的一行文本,它在遇到 EOF 字符或換行字符之前,不會停止讀入文本。也就是:gets() 根本不執(zhí)行邊界檢查。因此,使用 gets() 總是有可能使任何緩沖區(qū)溢出。作為一個替代方法,可以使用方法 fgets()。它可以做與 gets() 所做的同樣的事情,但它接受用來限制讀入字符數(shù)目的大小參數(shù),因此,提供了一種防止緩沖區(qū)溢出的方法。例如,不要使用以下代碼:

            void main()
              {
              char buf[1024];
              gets(buf);
              }
            

            而使用以下代碼:

            #define BUFSIZE 1024
            
            void main()
              {
              char buf[BUFSIZE];
              fgets(buf, BUFSIZE, stdin);
              }
            

            C 編程中的主要陷阱

            C 語言中一些標(biāo)準(zhǔn)函數(shù)很有可能使您陷入困境。但不是所有函數(shù)使用都不好。通常,利用這些函數(shù)之一需要任意輸入傳遞給該函數(shù)。這個列表包括:

            • strcpy()
            • strcat()
            • sprintf()
            • scanf()
            • sscanf()
            • fscanf()
            • vfscanf()
            • vsprintf
            • vscanf()
            • vsscanf()
            • streadd()
            • strecpy()
            • strtrns()

            壞消息是我們推薦,如果有任何可能,避免使用這些函數(shù)。好消息是,在大多數(shù)情況下,都有合理的替代方法。我們將仔細檢查它們中的每一個,所以可以看到什么構(gòu)成了它們的誤用,以及如何避免它。

            strcpy()函數(shù)將源字符串復(fù)制到緩沖區(qū)。沒有指定要復(fù)制字符的具體數(shù)目。復(fù)制字符的數(shù)目直接取決于源字符串中的數(shù)目。如果源字符串碰巧來自用戶輸入,且沒有專門限制其大小,則有可能會陷入大的麻煩中!

            如果知道目的地緩沖區(qū)的大小,則可以添加明確的檢查:

            if(strlen(src) >= dst_size) {
              /* Do something appropriate, such as throw an error. */
              }
                   else {
              strcpy(dst, src);
            

            完成同樣目的的更容易方式是使用 strncpy() 庫例程:

            strncpy(dst, src, dst_size-1);
              dst[dst_size-1] = '\0'; /* Always do this to be safe! */
            

            如果 src 比 dst 大,則該函數(shù)不會拋出一個錯誤;當(dāng)達到最大尺寸時,它只是停止復(fù)制字符。注意上面調(diào)用 strncpy() 中的 -1。如果 src 比 dst 長,則那給我們留有空間,將一個空字符放在 dst 數(shù)組的末尾。

            當(dāng)然,可能使用 strcpy() 不會帶來任何潛在的安全性問題,正如在以下示例中所見:

            strcpy(buf, "Hello!");
            

            即使這個操作造成 buf 的溢出,但它只是對幾個字符這樣而已。由于我們靜態(tài)地知道那些字符是什么,并且很明顯,由于沒有危害,所以這里無須擔(dān)心 ― 當(dāng)然,除非可以用其它方式覆蓋字符串“Hello”所在的靜態(tài)存儲器。

            確保 strcpy() 不會溢出的另一種方式是,在需要它時就分配空間,確保通過在源字符串上調(diào)用 strlen() 來分配足夠的空間。例如:

            dst = (char *)malloc(strlen(src));
              strcpy(dst, src);
            

            strcat()函數(shù)非常類似于 strcpy(),除了它可以將一個字符串合并到緩沖區(qū)末尾。它也有一個類似的、更安全的替代方法 strncat()。如果可能,使用 strncat() 而不要使用 strcat()。

            函數(shù) sprintf()vsprintf()是用來格式化文本和將其存入緩沖區(qū)的通用函數(shù)。它們可以用直接的方式模仿 strcpy() 行為。換句話說,使用 sprintf() 和 vsprintf() 與使用 strcpy() 一樣,都很容易對程序造成緩沖區(qū)溢出。例如,考慮以下代碼:

            void main(int argc, char **argv)
              {
              char usage[1024];
              sprintf(usage, "USAGE: %s -f flag [arg1]\n", argv[0]);
              }
            

            我們經(jīng)常會看到類似上面的代碼。它看起來沒有什么危害。它創(chuàng)建一個知道如何調(diào)用該程序字符串。那樣,可以更改二進制的名稱,該程序的輸出將自動反映這個更改。 雖然如此, 該代碼有嚴(yán)重的問題。文件系統(tǒng)傾向于將任何文件的名稱限制于特定數(shù)目的字符。那么,您應(yīng)該認(rèn)為如果您的緩沖區(qū)足夠大,可以處理可能的最長名稱,您的程序會安全,對嗎?只要將 1024 改為對我們的操作系統(tǒng)適合的任何數(shù)目,就好了嗎?但是,不是這樣的。通過編寫我們自己的小程序來推翻上面所說的,可能容易地推翻這個限制:

            void main()
              {
              execl("/path/to/above/program", 
              <<insert really long string here>>, 
              NULL);
              }
            

            函數(shù) execl() 啟動第一個參數(shù)中命名的程序。第二個參數(shù)作為 argv[0] 傳遞給被調(diào)用的程序。我們可以使那個字符串要多長有多長!

            那么如何解決 {v}sprintf() 帶來得問題呢?遺憾的是,沒有完全可移植的方法。某些體系結(jié)構(gòu)提供了 snprintf() 方法,即允許程序員指定將多少字符從每個源復(fù)制到緩沖區(qū)中。例如,如果我們的系統(tǒng)上有 snprintf,則可以修正一個示例成為:

            void main(int argc, char **argv)
              {
              char usage[1024];
              char format_string = "USAGE: %s -f flag [arg1]\n";
              snprintf(usage, format_string, argv[0], 
              1024-strlen(format_string) + 1); 
              }
            

            注意,在第四個變量之前,snprintf() 與 sprintf() 是一樣的。第四個變量指定了從第三個變量中應(yīng)被復(fù)制到緩沖區(qū)的字符最大數(shù)目。注意,1024 是錯誤的數(shù)目!我們必須確保要復(fù)制到緩沖區(qū)使用的字符串總長不超過緩沖區(qū)的大小。所以,必須考慮一個空字符,加上所有格式字符串中的這些字符,再減去格式說明符 %s。該數(shù)字結(jié)果為 1000, 但上面的代碼是更具有可維護性,因為如果格式字符串偶然發(fā)生變化,它不會出錯。

            {v}sprintf() 的許多(但不是全部)版本帶有使用這兩個函數(shù)的更安全的方法??梢灾付ǜ袷阶址旧砻總€自變量的精度。例如,另一種修正上面有問題的 sprintf() 的方法是:

            void main(int argc, char **argv)
              {
              char usage[1024];
              sprintf(usage, "USAGE: %.1000s -f flag [arg1]\n", argv[0]); 
              }
            

            注意,百分號后與 s 前的 .1000。該語法表明,從相關(guān)變量(本例中是 argv[0])復(fù)制的字符不超過 1000 個。

            如果任一解決方案在您的程序必須運行的系統(tǒng)上行不通,則最佳的解決方案是將 snprintf() 的工作版本與您的代碼放置在一個包中??梢哉业揭?sh 歸檔格式的、自由使用的版本;請參閱 參考資料。

            繼續(xù), scanf系列的函數(shù)也設(shè)計得很差。在這種情況下,目的地緩沖區(qū)會發(fā)生溢出??紤]以下代碼:

            void main(int argc, char **argv)
              {
              char buf[256];
              sscanf(argv[0], "%s", &buf);
              }
            

            如果輸入的字大于 buf 的大小,則有溢出的情況。幸運的是,有一種簡便的方法可以解決這個問題。考慮以下代碼,它沒有安全性方面的薄弱環(huán)節(jié):

            void main(int argc, char **argv)
              {
              char buf[256];
              sscanf(argv[0], "%255s", &buf);
              }
            

            百分號和 s 之間的 255 指定了實際存儲在變量 buf 中來自 argv[0] 的字符不會超過 255 個。其余匹配的字符將不會被復(fù)制。

            接下來,我們討論 streadd()strecpy()。由于,不是每臺機器開始就有這些調(diào)用,那些有這些函數(shù)的程序員,在使用它們時,應(yīng)該小心。這些函數(shù)可以將那些含有不可讀字符的字符串轉(zhuǎn)換成可打印的表示。例如,考慮以下程序:

            #include <libgen.h>
            
            void main(int argc, char **argv)
              {
              char buf[20];
              streadd(buf, "\t\n", "");
              printf(%s\n", buf);
              }
            

            該程序打?。?/p>
            \t\n
            

            而不是打印所有空白。如果程序員沒有預(yù)料到需要多大的輸出緩沖區(qū)來處理輸入緩沖區(qū)(不發(fā)生緩沖區(qū)溢出),則 streadd() 和 strecpy() 函數(shù)可能有問題。如果輸入緩沖區(qū)包含單一字符 ― 假設(shè)是 ASCII 001(control-A)― 則它將打印成四個字符“\001”。這是字符串增長的最壞情況。如果沒有分配足夠的空間,以至于輸出緩沖區(qū)的大小總是輸入緩沖區(qū)大小的四倍,則可能發(fā)生緩沖區(qū)溢出。

            另一個較少使用的函數(shù)是 strtrns(),因為許多機器上沒有該函數(shù)。函數(shù) strtrns() 取三個字符串和結(jié)果字符串應(yīng)該放在其內(nèi)的一個緩沖區(qū),作為其自變量。第一個字符串必須復(fù)制到該緩沖區(qū)。一個字符被從第一個字符串中復(fù)制到緩沖區(qū),除非那個字符出現(xiàn)在第二個字符串中。如果出現(xiàn)的話,那么會替換掉第三個字符串中同一索引中的字符。這聽上去有點令人迷惑。讓我們看一下,將所有小寫字符轉(zhuǎn)換成大寫字符的示例:

            #include <libgen.h>
            
            void main(int argc, char **argv)
              {
              char lower[] = "abcdefghijklmnopqrstuvwxyz";
              char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
              char *buf;
              if(argc < 2) {
              printf("USAGE: %s arg\n", argv[0]);
              exit(0);
              } buf = (char *)malloc(strlen(argv[1]));
              strtrns(argv[1], lower, upper, buf);
              printf("%s\n", buf);
              }
            

            以上代碼實際上不包含緩沖區(qū)溢出。但如果我們使用了固定大小的靜態(tài)緩沖區(qū),而不是用 malloc() 分配足夠空間來復(fù)制 argv[1],則可能會引起緩沖區(qū)溢出情況。





            回頁首


            避免內(nèi)部緩沖區(qū)溢出

            realpath() 函數(shù)接受可能包含相對路徑的字符串,并將它轉(zhuǎn)換成指同一文件的字符串,但是通過絕對路徑。在做這件事時,它展開了所有符號鏈接。

            該函數(shù)取兩個自變量,第一個作為要規(guī)范化的字符串,第二個作為將存儲結(jié)果的緩沖區(qū)。當(dāng)然,需要確保結(jié)果緩沖區(qū)足夠大,以處理任何大小的路徑。分配的 MAXPATHLEN 緩沖區(qū)應(yīng)該足夠大。然而,使用 realpath() 有另一個問題。如果傳遞給它的、要規(guī)范化的路徑大小大于 MAXPATHLEN,則 realpath() 實現(xiàn)內(nèi)部的靜態(tài)緩沖區(qū)會溢出!雖然實際上沒有訪問溢出的緩沖區(qū),但無論如何它會傷害您的。結(jié)果是,應(yīng)該明確不使用 realpath(),除非確保檢查您試圖規(guī)范化的路徑長度不超過 MAXPATHLEN。

            其它廣泛可用的調(diào)用也有類似的問題。經(jīng)常使用的 syslog() 調(diào)用也有類似的問題,直到不久前,才注意到這個問題并修正了它。大多數(shù)機器上已經(jīng)糾正了這個問題,但您不應(yīng)該依賴正確的行為。最好總是假定代碼正運行在可能最不友好的環(huán)境中,只是萬一在哪天它真的這樣。getopt() 系列調(diào)用的各種實現(xiàn),以及 getpass() 函數(shù),都可能產(chǎn)生內(nèi)部靜態(tài)緩沖區(qū)溢出問題。如果您不得不使用這些函數(shù),最佳解決方案是設(shè)置傳遞給這些函數(shù)的輸入長度的閾值。

            自己模擬 gets() 的安全性問題以及所有問題是非常容易的。 例如,下面這段代碼:

            char buf[1024];
              int i = 0;
              char ch;
              while((ch = getchar()) != '\n')
              {
              if(ch == -1) break;
              buf[i++] = ch;
              }
            

            哎呀!可以用來讀入字符的任何函數(shù)都存在這個問題,包括 getchar()、fgetc()、getc() 和 read()。

            緩沖區(qū)溢出問題的準(zhǔn)則是:總是確保做邊界檢查。

            C 和 C++ 不能夠自動地做邊界檢查,這實在不好,但確實有很好的原因,來解釋不這樣做的理由。邊界檢查的代價是效率。一般來講,C 在大多數(shù)情況下注重效率。然而,獲得效率的代價是,C 程序員必須十分警覺,并且有極強的安全意識,才能防止他們的程序出現(xiàn)問題,而且即使這些,使代碼不出問題也不容易。

            在現(xiàn)在,變量檢查不會嚴(yán)重影響程序的效率。大多數(shù)應(yīng)用程序不會注意到這點差異。所以,應(yīng)該總是進行邊界檢查。在將數(shù)據(jù)復(fù)制到您自己的緩沖區(qū)之前,檢查數(shù)據(jù)長度。同樣,檢查以確保不要將過大的數(shù)據(jù)傳遞給另一個庫,因為您也不能相信其他人的代碼?。ɑ貞浺幌虑懊嫠懻摰膬?nèi)部緩沖區(qū)溢出。)





            回頁首


            其它危險是什么?

            遺憾的是,即使是系統(tǒng)調(diào)用的“安全”版本 ― 譬如,相對于 strcpy() 的 strncpy() ― 也不完全安全。也有可能把事情搞糟。即使“安全”的調(diào)用有時會留下未終止的字符串,或者會發(fā)生微妙的相差一位錯誤。當(dāng)然,如果您偶然使用比源緩沖區(qū)小的結(jié)果緩沖區(qū),則您可能發(fā)現(xiàn)自己處于非常困難的境地。

            與我們目前所討論的相比,往往很難犯這些錯誤,但您應(yīng)該仍然意識到它們。當(dāng)使用這類調(diào)用時,要仔細考慮。如果不仔細留意緩沖區(qū)大小,包括 bcopy()、fgets()、memcpy()、snprintf()、strccpy()、strcadd()、strncpy() 和 vsnprintf(),許多函數(shù)會行為失常。

            另一個要避免的系統(tǒng)調(diào)用是 getenv()。使用 getenv() 的最大問題是您從來不能假定特殊環(huán)境變量是任何特定長度的。我們將在后續(xù)的專欄文章中討論環(huán)境變量帶來的種種問題。

            到目前為止,我們已經(jīng)給出了一大堆常見 C 函數(shù),這些函數(shù)容易引起緩沖區(qū)溢出問題。當(dāng)然,還有許多函數(shù)有相同的問題。特別是,注意第三方 COTS 軟件。不要設(shè)想關(guān)于其他人軟件行為的任何事情。還要意識到我們沒有仔細檢查每個平臺上的每個常見庫(我們不想做那一工作),并且還可能存在其它有問題的調(diào)用。

            即使我們檢查了每個常見庫的各個地方,如果我們試圖聲稱已經(jīng)列出了將在任何時候遇到的所有問題,則您應(yīng)該持非常非常懷疑的態(tài)度。我們只是想給您起一個頭。其余全靠您了。





            回頁首


            靜態(tài)和動態(tài)測試工具

            我們將在以后的專欄文章中更加詳細地介紹一些脆弱性檢測的工具,但現(xiàn)在值得一提的是兩種已被證明能有效幫助找到和去除緩沖區(qū)溢出問題的掃描工具。 這兩個主要類別的分析工具是靜態(tài)工具(考慮代碼但永不運行)和動態(tài)工具(執(zhí)行代碼以確定行為)。

            可以使用一些靜態(tài)工具來查找潛在的緩沖區(qū)溢出問題。很糟糕的是,沒有一個工具對一般公眾是可用的!許多工具做得一點也不比自動化 grep 命令多,可以運行它以找到源代碼中每個有問題函數(shù)的實例。由于存在更好的技術(shù),這仍然是高效的方式將幾萬行或幾十萬行的大程序縮減到只有數(shù)百個“潛在的問題”。(在以后的專欄文章中,將演示一個基于這種方法的、草草了事的掃描工具,并告訴您有關(guān)如何構(gòu)建它的想法。)

            較好的靜態(tài)工具利用以某些方式表示的數(shù)據(jù)流信息來斷定哪個變量會影響到其它哪個變量。用這種方法,可以丟棄來自基于 grep 的分析的某些“假肯定”。David Wagner 在他的工作中已經(jīng)實現(xiàn)了這樣的方法(在“Learning the basics of buffer overflows”中描述;請參閱 參考資料),在 Reliable Software Technologies 的研究人員也已實現(xiàn)。當(dāng)前,數(shù)據(jù)流相關(guān)方法的問題是它當(dāng)前引入了假否定(即,它沒有標(biāo)志可能是真正問題的某些調(diào)用)。

            第二類方法涉及動態(tài)分析的使用。動態(tài)工具通常把注意力放在代碼運行時的情況,查找潛在的問題。一種已在實驗室使用的方法是故障注入。這個想法是以這樣一種方式來檢測程序:對它進行實驗,運行“假設(shè)”游戲,看它會發(fā)生什么。有一種故障注入工具 ― FIST(請參閱 參考資料)已被用來查找可能的緩沖區(qū)溢出脆弱性。

            最終,動態(tài)和靜態(tài)方法的某些組合將會給您的投資帶來回報。但在確定最佳組合方面,仍然有許多工作要做。





            回頁首


            Java 和堆棧保護可以提供幫助

            如上一篇專欄文章中所提到的(請參閱 參考資料),堆棧搗毀是最惡劣的一種緩沖區(qū)溢出攻擊,特別是,當(dāng)在特權(quán)模式下?lián)v毀了堆棧。這種問題的優(yōu)秀解決方案是非可執(zhí)行堆棧。 通常,利用代碼是在程序堆棧上編寫,并在那里執(zhí)行的。(我們將在下一篇專欄文章中解釋這是如何做到的。)獲取許多操作系統(tǒng)(包括 Linux 和 Solaris)的非可執(zhí)行堆棧補丁是可能的。(某些操作系統(tǒng)甚至不需要這樣的補??;它們本身就帶有。)

            非可執(zhí)行堆棧涉及到一些性能問題。(沒有免費的午餐。)此外,在既有堆棧溢出又有堆溢出的程序中,它們易出問題??梢岳枚褩R绯鍪钩绦蛱D(zhuǎn)至利用代碼,該代碼被放置在堆上。 沒有實際執(zhí)行堆棧中的代碼,只有堆中的代碼。這些基本問題非常重要,我們將在下一篇專欄文章中專門刊載。

            當(dāng)然,另一種選項是使用類型安全的語言,譬如 Java。較溫和的措施是獲取對 C 程序中進行數(shù)組邊界檢查的編譯器。對于 gcc 存在這樣的工具。這種技術(shù)可以防止所有緩沖區(qū)溢出,堆和堆棧。不利的一面是,對于那些大量使用指針、速度是至關(guān)重要的程序,這種技術(shù)可能會影響性能。但是在大多數(shù)情況下,該技術(shù)運行得非常好。

            Stackguard 工具實現(xiàn)了比一般性邊界檢查更為有效的技術(shù)。它將一些數(shù)據(jù)放在已分配數(shù)據(jù)堆棧的末尾,并且以后會在緩沖區(qū)溢出可能發(fā)生前,查看這些數(shù)據(jù)是否仍然在那里。這種模式被稱之為“金絲雀”。(威爾士的礦工將 金絲雀放在礦井內(nèi)來顯示危險的狀況。當(dāng)空氣開始變得有毒時,金絲雀會昏倒,使礦工有足夠時間注意到并逃離。)

            Stackguard 方法不如一般性邊界檢查安全,但仍然相當(dāng)有用。Stackguard 的主要缺點是,與一般性邊界檢查相比,它不能防止堆溢出攻擊。一般來講,最好用這樣一個工具來保護整個操作系統(tǒng),否則,由程序調(diào)用的不受保護庫(譬如,標(biāo)準(zhǔn)庫)可以仍然為基于堆棧的利用代碼攻擊打開了大門。

            類似于 Stackguard 的工具是內(nèi)存完整性檢查軟件包,譬如,Rational 的 Purify。這類工具甚至可以保護程序防止堆溢出,但由于性能開銷,這些工具一般不在產(chǎn)品代碼中使用。





            回頁首


            結(jié)束語

            在本專欄的上兩篇文章中,我們已經(jīng)介紹了緩沖區(qū)溢出,并指導(dǎo)您如何編寫代碼來避免這些問題。我們還討論了可幫助使您的程序安全遠離可怕的緩沖區(qū)溢出的幾個工具。表 1 總結(jié)了一些編程構(gòu)造,我們建議您小心使用或避免一起使用它們。如果有任何認(rèn)為我們應(yīng)該將其它函數(shù)加入該列表,請則通知我們,我們將更新該列表。

            函數(shù) 嚴(yán)重性 解決方案
            gets 最危險 使用 fgets(buf, size, stdin)。這幾乎總是一個大問題!
            strcpy 很危險 改為使用 strncpy。
            strcat 很危險 改為使用 strncat。
            sprintf 很危險 改為使用 snprintf,或者使用精度說明符。
            scanf 很危險 使用精度說明符,或自己進行解析。
            sscanf 很危險 使用精度說明符,或自己進行解析。
            fscanf 很危險 使用精度說明符,或自己進行解析。
            vfscanf 很危險 使用精度說明符,或自己進行解析。
            vsprintf 很危險 改為使用 vsnprintf,或者使用精度說明符。
            vscanf 很危險 使用精度說明符,或自己進行解析。
            vsscanf 很危險 使用精度說明符,或自己進行解析。
            streadd 很危險 確保分配的目的地參數(shù)大小是源參數(shù)大小的四倍。
            strecpy 很危險 確保分配的目的地參數(shù)大小是源參數(shù)大小的四倍。
            strtrns 危險 手工檢查來查看目的地大小是否至少與源字符串相等。
            realpath 很危險(或稍小,取決于實現(xiàn)) 分配緩沖區(qū)大小為 MAXPATHLEN。同樣,手工檢查參數(shù)以確保輸入?yún)?shù)不超過 MAXPATHLEN。
            syslog 很危險(或稍小,取決于實現(xiàn)) 在將字符串輸入傳遞給該函數(shù)之前,將所有字符串輸入截成合理的大小。
            getopt 很危險(或稍小,取決于實現(xiàn)) 在將字符串輸入傳遞給該函數(shù)之前,將所有字符串輸入截成合理的大小。
            getopt_long 很危險(或稍小,取決于實現(xiàn)) 在將字符串輸入傳遞給該函數(shù)之前,將所有字符串輸入截成合理的大小。
            getpass 很危險(或稍小,取決于實現(xiàn)) 在將字符串輸入傳遞給該函數(shù)之前,將所有字符串輸入截成合理的大小。
            getchar 中等危險 如果在循環(huán)中使用該函數(shù),確保檢查緩沖區(qū)邊界。
            fgetc 中等危險 如果在循環(huán)中使用該函數(shù),確保檢查緩沖區(qū)邊界。
            getc 中等危險 如果在循環(huán)中使用該函數(shù),確保檢查緩沖區(qū)邊界。
            read 中等危險 如果在循環(huán)中使用該函數(shù),確保檢查緩沖區(qū)邊界。
            bcopy 低危險 確保緩沖區(qū)大小與它所說的一樣大。
            fgets 低危險 確保緩沖區(qū)大小與它所說的一樣大。
            memcpy 低危險 確保緩沖區(qū)大小與它所說的一樣大。
            snprintf 低危險 確保緩沖區(qū)大小與它所說的一樣大。
            strccpy 低危險 確保緩沖區(qū)大小與它所說的一樣大。
            strcadd 低危險 確保緩沖區(qū)大小與它所說的一樣大。
            strncpy 低危險 確保緩沖區(qū)大小與它所說的一樣大。
            vsnprintf 低危險 確保緩沖區(qū)大小與它所說的一樣大。

            在我們急匆匆講述這些基礎(chǔ)知識時,到現(xiàn)在為止,已經(jīng)遺漏了一些緩沖區(qū)溢出很酷的細節(jié)。在下幾篇專欄文章中,我們將深入這臺“引擎”的工作,并給它加點黃油。我們將詳細地了解緩沖區(qū)溢出的工作原理,甚至還會演示一些利用代碼。



            參考資料



            作者簡介

            Gary McGraw是 Reliable Software Technologies 負責(zé)企業(yè)技術(shù)的副總裁,該公司位于美國弗吉尼亞州杜勒斯(Dulles)。他從事咨詢服務(wù)和研究工作,幫助決定技術(shù)研究和開發(fā)方向。McGraw 在 Reliable Software Technologies 從一個研究科學(xué)家做起,從事軟件工程和計算機安全性方面的研究。他擁有印第安那大學(xué)認(rèn)知科學(xué)和計算機科學(xué)雙博士學(xué)位,弗吉尼亞大學(xué)的哲學(xué)學(xué)士學(xué)位。他為技術(shù)刊物撰寫了 40 余篇經(jīng)同行審查的文章,擔(dān)任過主要的電子貿(mào)易供應(yīng)商(包括 Visa 和 Federal Reserve)的顧問職務(wù),并在空軍研究實驗室、DARPA、國家科學(xué)基金會以及 NIST 的高級技術(shù)項目贊助下?lián)纹涫紫{(diào)研員。

            McGraw 是移動代碼安全性方面著名的權(quán)威人士,并且與普林斯頓的教授 Ed Felten 合作撰寫了“Java Security: Hostile Applets, Holes, & Antidotes”(Wiley, 1996)以及“Securing Java: Getting down to business with mobile code”(Wiley, 1999)。McGraw 和 RST 創(chuàng)始人之一、首席科學(xué)家 Dr. Jeffrey Voas 一起編寫了“Software Fault Injection: Inoculating Programs Against Errors”(Wiley, 1998)。McGraw 定期為一些受歡迎的商業(yè)出版物撰稿,而且其文章經(jīng)常在全國出版的文章中所引用。


            John Viega是一名高級副研究員,Software Security Group 的共同創(chuàng)始人,并擔(dān)任 Reliable Software Technologies 的高級顧問。他是 DARPA 贊助的開發(fā)標(biāo)準(zhǔn)編程語言安全性擴展的首席調(diào)研員。John 已撰寫了 30 余篇涉及軟件安全性和測試領(lǐng)域的技術(shù)性文章。他負責(zé)在主要網(wǎng)絡(luò)和電子商業(yè)產(chǎn)品中查找一些眾所周知的安全性弱點,包括最近在 Netscape 安全性中的缺陷。他還是開放源碼軟件社區(qū)的重要成員,編寫過 Mailman、GNU Mailing List Manager 以及最近發(fā)布的 ITS4(一種在 C 和 C++ 代碼中查找安全性弱點的工具)。Viega 擁有弗吉尼亞大學(xué)計算機科學(xué)碩士學(xué)位。

            posted on 2008-05-10 20:56 肥仔 閱讀(918) 評論(0)  編輯 收藏 引用 所屬分類: C++ 基礎(chǔ)

            久久久久久九九99精品| 久久精品国产精品亚洲精品 | 中文字幕人妻色偷偷久久| 一本综合久久国产二区| 国产精品99久久久精品无码| 国产亚洲欧美精品久久久| 国产午夜精品久久久久九九电影| 亚洲AV伊人久久青青草原| 久久精品国产亚洲av影院| 久久国产三级无码一区二区| 久久精品国产亚洲av麻豆图片| 97久久精品人妻人人搡人人玩 | 亚洲伊人久久综合中文成人网| 久久精品亚洲AV久久久无码| 久久久久四虎国产精品| 国产毛片欧美毛片久久久| 狠狠色综合久久久久尤物| 久久亚洲春色中文字幕久久久| 成人国内精品久久久久影院VR| 久久亚洲私人国产精品vA| 性做久久久久久免费观看| 99久久精品免费国产大片| jizzjizz国产精品久久| 亚洲综合日韩久久成人AV| 性做久久久久久久久久久| 很黄很污的网站久久mimi色| 国产精品久久久久久吹潮| 97久久国产露脸精品国产| 欧美一级久久久久久久大片| 99久久无码一区人妻| 国产91久久精品一区二区| 亚洲精品无码久久久久去q| 国产香蕉久久精品综合网| 香港aa三级久久三级老师2021国产三级精品三级在 | 无码精品久久久天天影视| 国产精品亚洲综合久久| 亚洲国产天堂久久久久久| 久久久久综合中文字幕 | 午夜精品久久久久9999高清| 久久精品亚洲精品国产欧美| 久久久久久av无码免费看大片|