• <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>
            Dict.CN 在線詞典, 英語學習, 在線翻譯

            學海苦作舟,書山勤為徑

            留下點回憶

            常用鏈接

            統計

            積分與排名

            Denoise

            English study

            Web技術

            數據壓縮

            一些連接

            最新評論

            Strlcpy和strlcat-一致的、安全的字符串復制和串接

            ?

            概要:

            時下緩沖區溢出攻擊已經增加,越來越多的程序員使用帶有 size 或長度邊界的字符串函數,例如: strncpy strncat 。這的確是一個趨勢,但標準的 C 字符串函數并不是真正為這些任務而設計的。本文描述一個專門設計用于安全字符串復制的可選的、直覺的和一致的 API

            strncpy strncat 作為 strcpy strcat 安全版本有幾個問題。兩個函數都是以不同的和非直覺的方法來處理 NULL 結尾的和長度參數,即使有經驗的程序員都有時迷惑;而檢查什么時候發生截斷也是不容易的。最后, strncpy 0 來填充目標字符串剩余的部分,這是以損失性能為代價的。所有這些迷惑都是由長度參數引起的,空結束的要求也非常重要。當我們評估 OpenBSD 源樹的潛在安全漏洞的時候,我們發現大量濫用 strncpy strncat 。當然,并不是所有的都導致暴露的安全漏洞,上面的這些使說明了一點:使用 strncpy strncat 作為安全字符串操作容易被誤解。推薦使用的函數是 strlcpy strlcat ,通過為安全字符串設計的 API 來程序這些問題(見圖 1 的函數原型)。兩個函數都保證 NUL 結尾,長度參數是以字節記數的,并且提供了檢查截斷的方法,兩個函數都不是在目標字符串中填充 0

            ?

            介紹

            ?

            1996 年中,作者和其他 OpenBSD 項目的成員一起承擔了對 OpenBSD 源樹的評估,為了找出安全問題;以緩沖區溢出作為開始。緩沖區溢出最近在一些論壇(例如 BugTraq )大量關注,并且正被廣泛地開拓。我們發現大量的緩沖區溢出是由于較大的使用 sprintf strcpy strcat 進行的字符串復制;在循環中操作字符串而沒有明確地檢查循環變量的長度也是一個問題。另外,我們也發現許多程序員使用 strncpy strncat 來進程安全字符串操作但失敗的場景。

            因此,在評估代碼的時候,我們發現不僅僅檢查 strcpy strcat 的不安全使用,同樣也要檢查 strncpy strncat 的不正確使用。檢查正確使用并不總是明顯地,特別在靜態變量和緩沖區或 calloc 分配的緩沖區,這些都容易被忽視。我們得到結論,一個安全的 strncpy strncat 是必要的,首先可以減輕程序員的工作;另外也可以是代碼評估更容易。

            ?

            size_t strlcpy(char *dst, const char *src, size_t size);
            size_t strlcat(char *dst, const char *src, size_t size);

            Figure 1: ANSI C prototypes for strlcpy() and strlcat()

            通常誤解

            最通常的誤解是 strncpy 空結尾的目標字符串。然而,只有源符串的長度小于 size 參數才是正確的。當用戶輸入的任意長度字符串時候,可能有問題。這種情況下最安全方法是傳遞一個小于目標字符串的 size strncpy ,并且手動添加一個結束符號。這種方法下你可以總是保證目標字符穿是 NUL 結束的。嚴格地說,如果是一個靜態的字符串或一個 calloc 分配的字符串不必要手動添加一個結束符號;主要由于這些字符串在分配的時候是填充 0 的。然而這些特性時候比較迷惑的。

            另外一個暗示的假定就是從 strcpy strcat 代碼轉換到 strncpy strncat 導致的性能下降是可以接受的。對于 strncat 來說是正確的,但同樣對于 strncpy 來說并不正確,由于 strncpy 將剩余的目標字節填充 0 ,這在字符串比較大的時候可能導致可觀的性能損失。確切的損失由 CPU 架構和實現的而決定。

            最常見的錯誤是使用 strncat 和一個不正確的 size 參數。然而 strncat 保證目標字符串是 NULL 結尾的,你不需要在 size 參數中為 NUL 計算機空間。最重要的,這不是目標字符串自身的大小,而是可用空間的數量。因此這個值總是要計算,并且作為一個可靠的常量,它常常也不能正確計算。

            為什么 strlcpy strlcat 能夠安全

            ?

            這兩個函數提供了一個一致的、沒有二義性的 API 來幫助程序員寫比較防彈代碼。首先也是最重要的,兩個函數都能夠保證所有的目標字符串是 NUL 結尾的,給定的 size 0 ;其次,兩個函數都將目標字符串的整個 size 作為一個 size 參數。在大多數情況下,這個值比較容易在編譯期間使用 sizeof 操作符號來計算;最后,不管是 strlcpy 還是 strlcat 都不 0 填充他們的目標字符串(而是強迫 NUL 到字符串的結尾)。

            Strlcpy strlcat 函數返回最終創建的字符串長度。對于 strlcpy 來說是源的長度,對于 strlcat 來說意味著目標的長度加源的長度。為了檢查截斷,程序員需要驗證返回值是否小于 size 參數。因此,如果發生截斷,可以發現已經存儲了多少個字節,并且程序員可以重新分配空間來重新復制字符串。返回值和 snprintf BSD 上的實現有相同的含義。如果沒有截斷發生,程序員現在有返回值長度的字符串;這是有用的,因為通常情況用 strncpy strncat 來構造字符串并且使用 strlen 來取得字符串的長度。使用 strlcpy strlcat strlen 就不需要了。

            例子 1a 是潛在緩沖區溢出的例子( HOME 環境變量由用戶來控制可以是任意長度)。

            strcpy(path, homedir);
            strcat(path, "/");
            strcat(path, ".foorc");
            len = strlen(path);

            Example 1a: Code fragment using strcpy() and strcat()

            例子 1b 轉換到 strncpy strncat 的同樣代碼片段(注意,我必須自己添加字符串結束符號)。

            strncpy(path, homedir,
            sizeof(path) - 1);
            path[sizeof(path) - 1] = '\?0';
            strncat(path, "/",
            sizeof(path) - strlen(path) - 1);
            strncat(path, ".foorc",
            sizeof(path) - strlen(path) - 1);
            len = strlen(path);

            Example 1b: Converted to strncpy() and strncat()

            例子 1c 是到 strlcpy/strlcat 的變化,其有例子 1a 一樣簡單的好處,但卻沒有利用 API 的返回值:

            strlcpy(path, homedir, sizeof(path));
            strlcat(path, "/", sizeof(path));
            strlcat(path, ".foorc", sizeof(path));
            len = strlen(path);

            Example 1c: Trivial conversion to strlcpy()/strlcat()

            由于例子 1c 如此容易閱讀和理解,添加其他的檢查也是非常簡單,在例子 1d 中,我們檢查返回值來確保對于源字符串來說有足夠的空間。如果沒有,我們返回一個錯誤。這里稍微復雜一點,但它仍然很好,同時也避免了調用 strlen

            len = strlcpy(path, homedir,sizeof(path);
            if (len >= sizeof(path))
            return (ENAMETOOLONG);
            len = strlcat(path, "/",sizeof(path);
            if (len >= sizeof(path))
            return (ENAMETOOLONG);
            len = strlcat(path, ".foorc",sizeof(path));
            if (len >= sizeof(path))
            return (ENAMETOOLONG);

            Example 1d: Now with a check for truncation

            ?

            設計決策

            許多思想加入判斷 strlcpy strlcat 應該是什么語義。最初的想法是使 strlcpy strlcat strncpy strncat 相同,并且始終是 NUL 結束的目標字符串。然而,當我們回過來看常用(和誤用) strncat 說服我們 strlcat size 參數應該是字符串的所有大小而不僅僅是未分配的字符的數量。返回值開始作為復制字符串的數量,由于有復制和串聯的副作用。我們很快決定返回值應該與 sprintf 一樣,這樣程序可以比較彈性的處理截斷和恢復。

            性能

            當目標字符串的長度比源字符串明顯大很多的時候,程序員正在避免使用 strncpy ,主要由于其降低性能。例如, Apache 組用內部函數來代替 strncpy 并且注意到性能提升。同樣, ncurses 包最近刪除了 strncpy ,結果比 tic 實現提高了四倍。我們的希望是,將來更多的程序員使用 strlcpy 而不是自定義的接口。

            為了對性能的降低有一個感覺,我們比較 strncpy strlcpy ,并且復制字符串 ’’ ;也就是復制 1000 次到 1024 字節的緩沖區中。這對 strncpy 有點不公平,由于使用了大的緩沖區和小的字符串,并且大緩沖區的時候, strncpy 不得不填充多余的緩沖為 NUL 字符。實際上,通常使用的緩沖區都比用戶輸入的大,例如,路徑名稱緩沖區是 MAXPATHLEN 長( 1024 ),但多數文件都比較短。表 1 中的平均運行時間在 HP9000/425t 25Mhz68040 CPU 運行 OPENBSD2.5 DEC AXPPCI166 166Mhz Alpha CPU 運行 OpenBSD 。所有的 case 都是相同 C 版本函數,時間由時間工具產生:

            ?cpu architecture?

            ?function?

            ?time (sec)?

            m68k

            strcpy

            0.137

            m68k

            strncpy

            0.464

            m68k

            strlcpy

            0.14

            alpha

            strcpy

            0.018

            alpha

            strncpy

            0.10

            alpha

            strlcpy

            0.02

            1 :性能時間表

            如我們在表 1 中看到的一樣, strncpy 的時間是最壞的。可能的原因不僅是 NUL 填充,也可能因為 CPU 數據緩沖區被長流 0flush 的原因。

            ?

            什么時候不要 strlcpy strlcat

            然而, strlcpy strlcat 處理固定大小的緩沖區很好,但他們不能在所有情況下代理 strncpy strncat 。有時候操作緩沖區并不是真正的 C 字符串(例如,結構體 utmp 中的字符串)時候就是必要的。然而,我們爭論的這樣假冒字符串不應該用在新的編碼中,由于他們可能被誤用,并且據我們的經驗,這也是 BUG 的根源。另外, strlcpy strlcat 函數并不是 C 里面修正字符串處理的嘗試,他們設計為來適應正常的 C 字符串框架。如果你需要字符串函數支持動態分配的、任意大小的緩沖區,你可能需要檢查 asstring 包,在 MIB 軟件中。

            誰使用 strlcpy strlcat

            Strlcpy strlcat 函數首先出現在 OpenBSD2.4 。這些函數最近被將來的 Solaris 版本中批準。第三方包也開始收集這些 API 。例如, rsync 包現在使用 strlcpy 并且提供它自己的版本如果 OS 不支持的話。其他的操作系統和應用程序將來使用 strlcpy strlcat 是我們的希望,并且它將某個時候接受標準。

            下一步是什么?

            Strlcpy strlcat 的源碼可以免費獲得,并且 BSD 風格的 license OpenBSD 操作系統的一部分。你可以通過匿名 ftp ftp.openbsd.org 下載代碼和相關的手冊;目錄為 /pub/OpenBSD/src/lib/libc/string strlcpy strlcat 的源碼在 strlcpy.c strlcat.c 中。也可以找到相應的文檔。

            作者: Todd C. Miller

            http://www.courtesan.com/todd/papers/strlcpy.html

            posted on 2006-10-05 18:43 笨笨 閱讀(4187) 評論(0)  編輯 收藏 引用 所屬分類: Security

            午夜精品久久久久久影视777| 欧美亚洲国产精品久久蜜芽| 品成人欧美大片久久国产欧美| 午夜精品久久久久久久| 中文国产成人精品久久亚洲精品AⅤ无码精品| 国产美女久久精品香蕉69| 国产精品久久久久国产A级| 无码精品久久久天天影视| 久久天天躁狠狠躁夜夜avapp | 人妻精品久久久久中文字幕| 国产精品亚洲综合专区片高清久久久 | 怡红院日本一道日本久久 | 久久综合狠狠综合久久97色| 久久久久久久综合综合狠狠| 亚洲精品乱码久久久久久蜜桃| 四虎久久影院| 无码国内精品久久人妻蜜桃| 99久久99这里只有免费的精品| 26uuu久久五月天| 久久亚洲精品无码aⅴ大香| 久久久精品2019免费观看| 日韩欧美亚洲综合久久影院d3| 久久93精品国产91久久综合| 久久精品国产欧美日韩99热| 欧美亚洲色综久久精品国产| AA级片免费看视频久久| 久久精品青青草原伊人| 9191精品国产免费久久| 亚洲婷婷国产精品电影人久久 | 精品伊人久久久| www性久久久com| 久久精品国产亚洲AV忘忧草18| 久久人妻少妇嫩草AV无码专区| 久久久噜噜噜久久| 国产精品久久久久影视不卡| 久久久精品久久久久影院| 国产成人精品综合久久久| 日韩久久久久久中文人妻 | 熟妇人妻久久中文字幕| 久久久精品无码专区不卡| 99久久无码一区人妻a黑|