當(dāng)前位置:首頁 > 公眾號精選 > 嵌入式云IOT技術(shù)圈
[導(dǎo)讀]C中大多數(shù)緩沖區(qū)溢出問題可以直接追溯到標(biāo)準(zhǔn) C 庫。最有害的罪魁禍?zhǔn)资遣贿M行自變量檢查的、有問題的字符串操作strcpy、strcat、sprintf?和?gets。一般來講,象“避免使用?strcpy()和永遠(yuǎn)不使用gets()這樣嚴(yán)格的規(guī)則接近于這個要求。 今天,編寫的程序仍然利









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

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

第一位公共敵人是 gets()。永遠(yuǎn)不要使用 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ù)情況下,都有合理的替代方法。我們將仔細(xì)檢查它們中的每一個,所以可以看到什么構(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)用的程序。我們可以使那個字符串要多長有多長!

那么如何解決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ā)生變化,它不會出錯。

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)用時,要仔細(xì)考慮。如果不仔細(xì)留意緩沖區(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)于其他人軟件行為的任何事情。還要意識到我們沒有仔細(xì)檢查每個平臺上的每個常見庫(我們不想做那一工作),并且還可能存在其它有問題的調(diào)用。

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

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

我們將在以后的專欄文章中更加詳細(xì)地介紹一些脆弱性檢測的工具,但現(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)您如何編寫代碼來避免這些問題。我們還討論了可幫助使您的程序安全遠(yuǎn)離可怕的緩沖區(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ū)邊界。
read 中等危險 如果在循環(huán)中使用該函數(shù),確保檢查緩沖區(qū)邊界。
bcopy 中等危險 如果在循環(huán)中使用該函數(shù),確保檢查緩沖區(qū)邊界。
fgets 低危險 確保緩沖區(qū)大小與它所說的一樣大。
memcpy 低危險 確保緩沖區(qū)大小與它所說的一樣大。
snprintf 低危險 確保緩沖區(qū)大小與它所說的一樣大。
strccpy 低危險 確保緩沖區(qū)大小與它所說的一樣大。
strcadd 低危險 確保緩沖區(qū)大小與它所說的一樣大。
strncpy 低危險 確保緩沖區(qū)大小與它所說的一樣大。
getchar 低危險 確保緩沖區(qū)大小與它所說的一樣大。
vsnprintf 低危險 確保緩沖區(qū)大小與它所說的一樣大。

往期精彩


讓C語言的調(diào)試更加高大上

用變量a給出下面的定義

分享一個自己量產(chǎn)項目上的集成測試軟件MTTEST

分享一個非常有用且簡單C語言測試框架

嵌入式系統(tǒng)軟件架構(gòu)設(shè)計(長篇深度好文)

若覺得本次分享的文章對您有幫助,隨手點[在看]并轉(zhuǎn)發(fā)分享,也是對我的支持。





免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉