[C語言] - gets()設計缺陷

gets()設計是用來取得輸入的字串。但此function有重大的缺陷,即不會去檢查buffer是否足夠使用

Bug

先看以下這段程式碼

1
2
3
4
5
6
7
int main(void)
{
char line[512];
...
...
gets(line);
}

程式會將取得的字串放進line這個buffer,但gets()不會去確認buffer是否足夠,實際上也無法確認,因gets()無法得知buffer大小的資訊,如果輸入的字串大於buffer,那gets()會將此字串完整的貼到buffer裡,即便會超過此buffer造成其他的memory被覆蓋掉

Internet worm

這個簡單的bug卻可以造成嚴重的危害。正常來說local variable的buffer會放在stack裡面,某些重要資訊也可能放在stack,例如return address(RA),若剛好遇到此架構的RA是放在stack,那惡意的使用者就可以輸入一個非常長的字串,讓gets()蓋掉其它stack的資訊,包括了RA,當此function執行完之後準備jump回原本的caller function,但RA已經被改成惡意使用者的function address,即可破壞甚至取得此架構的控制權

Patch

還好已經有可替代的function避免這個問題,就是改使用fgets(),fgets()需帶入buffer大小的參數,因此會幫忙檢查是否造成overwrite,在Linux下輸入man gets可得到相關資訊,其中最後的部分寫到SECURITY CONSIDERATIONS即為相關說明