gets()設計是用來取得輸入的字串。但此function有重大的缺陷,即不會去檢查buffer是否足夠使用
Bug
先看以下這段程式碼
1 | int main(void) |
程式會將取得的字串放進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
即為相關說明