[Maple Bug 修正] - str_decode 造成 SIGSEGV
Maple 系列 Bug - str_decode
可能影響之系統: Maple v2.36, Maple v3.02, Maple v3.10, 以及其延伸版本
像是 Sob, Ptt, 以及 WD 等.
目前已經確定影響之系統: Maple v3.10 (自己的站)
WD 全版本 (幫別人管的站)
-----------------------------------------------------------------------------
問題背景: str_decode.c (/home/bbs/src/lib)
str_decode 是將一個原本以 QP/BASE64 編碼的字串內容,將其解碼後,
存放回原字串的一個函式。如果傳入了大於緩衝區數目的字元進入,那麼函式
運作期間,將導致 SIGSEGV (segmentation violation),程式終止運行.
有問題的程式區段如下: (以 Maple 為例子)
void
str_decode(str)
unsigned char *str;
{
int adj;
unsigned char *src, *dst;
unsigned char buf[512]; ← (1)
src = str;
dst = buf;
adj = 0;
.
. 中間為程式解碼過程
.
*dst = 0; ← (2)
strcpy(str, buf);
}
問題即在上述 (1)、(2) 的地方。
假設一大串編碼資料送入 str_decode(),解碼過後的結果為 1024 bytes,
而原先 (1) 所配給 buf 緩衝區僅為 512 bytes, 程式執行到 (2) 的地方時,
指標已經超出了 buf 區段,將產生 Invalid memory reference.
接著就會產生 SIGSEGV 訊號, 程式終止運行.
-----------------------------------------------------------------------------
系統影響: 目前已知會產生大量的 0 byte 檔案在每個使用者目錄下.
(如 /home/bbs/usr/c/chunhan, 檔名為 @???????? ) - Maple 系列
(如 /home/bbs/home/chunhan, 檔名為 M.??????????.A) - WD 系列
其他的影響還不知道, 請各位立即檢查
1. /home/bbs/run/mailog - Maple 系列
(WD 系列沒有 log 可以檢查)
裡面是否有以下記錄:
(請在 /home/bbs/run 下 grep signal mailog 指令)
如果出現以下內容, 表示您的系統內有本 bug.
04/13 15:59:17 <bbsmail> signal [11]
04/16 09:42:49 <bbsmail> signal [11]
04/16 15:53:33 <bbsmail> signal [11]
04/22 05:21:15 <bbsmail> signal [11]
04/22 05:21:48 <bbsmail> signal [11]
2. 檢查每個使用者目錄下是否有許多為零的檔案:
請在 home/bbs/usr 下以下指令: (Maple 系列)
find . -size 0 -name '@*'
請在 home/bbs/home 下以下指令: (WD 系列)
find . -size 0 -name 'M*'
如果您發現每個人的目錄下都有不少這種 0 byte 的檔案,
那麼更可以確定您的系統有這個 bug 存在.
值得注意的是, 這些 0 byte 的檔案都不存在於 .DIR 當中,
可以將其刪除. 請參考後面介紹.
這些 0 byte 的檔案起因在於 bbsmail.c,由於外界以 E-mail 寄入站內信箱
時,bbsmail 無法順利處理單行超過 512 bytes 的信件,因此造成 SIGSEGV,
然而,之前開過的檔案並未因此而消失,因此在程式結束之後,會殘留 0 byte
的檔案於使用者的目錄當中. 當外界(如廣告信) 瘋狂丟這樣的信件到系統上時,
很容易照成檔案系統被垃圾塞滿.
-----------------------------------------------------------------------------
修正辦法: 以下將提出一些patch 辦法, 建議都做:
1.修正 str_decode.c (/home/bbs/src/lib)
不管是 WD 或是 Maple 都可以做以下修正:
(如果您的系統是 Maple, 您可以修改如下)
void
str_decode(str)
unsigned char *str;
{
int adj;
unsigned char *src, *dst;
/* unsigned char buf[512]; */
/* by chunhan 2002.04.28 : 將 buffer size 調高, 避免 SIGSEGV */
unsigned char buf[5120];
(如果您的系統是 WD, 您可以修改如下)
void
str_decode(str)
unsigned char *str;
{
int code, c1, c2, c3, c4;
unsigned char *src, *dst;
/* unsigned char buf[512]; */
/* by chunhan 2002.04.28 : 將 buffer size 調高, 避免 SIGSEGV */
unsigned char buf[5120];
以上是我自己的修正辦法, 如果您有其他改法請自行修改.
2.修正 bbsmail.c (/home/bbs/src/util)
bbsmail.c
(如果您的系統是 Maple, 您可以修改如下)
/* parse header */
title[0] = sender[0] = '\0';
while (fgets(buf, sizeof(buf), stdin) && buf[0])
{
/* by chunhan: 2002.04.27 強制 crop, 避免 SIGSEGV */
buf[511] = 0;
/* ---------------------------------------------- */
if (!memcmp(buf, "From", 4))
{
(如果您的系統是 WD, 您可以修改如下)
fputs(genbuf, fout);
while (fgets(genbuf, sizeof(genbuf), stdin) != NULL)
{
/* by chunhan: 2002.04.27 強制 crop, 避免 SIGSEGV */
genbuf[511] = 0;
/* ---------------------------------------------- */
str_decode(genbuf);
strcat(genbuf,"\n");
fputs(genbuf, fout);
如此修正之後,就不會有 SIGSEGV 的產生,也不會造成一堆廢檔案
存在系統當中.
以上是我自己的修正辦法, 如果您有其他改法請自行修改.
-----------------------------------------------------------------------------
補救辦法: 這邊的指令您可以當作參考, 他將幫助您刪除系統上這些為 0 byte
的廢檔案。
請在 home/bbs/usr 下以下指令: (Maple 系列)
find . -size 0 -name '@*' -exec rm {} \;
請在 home/bbs/home 下以下指令: (WD 系列)
find . -size 0 -name 'M*' -exec rm {} \;
進階補救: 所造成的垃圾檔案是否一定是 0 Byte?
絕大多數是. (在我的 Maple 系統上的確如此, 只有 0 byte 的檔案)
可是我意外的發現竟然也會有 4096, 8192, 16384 Bytes 等的檔案出現.
(在 WD 的系統下)
因此我的建議是, 寫個小程式, 將 .DIR 解析出來。
若發現該使用者目錄中的檔案,沒有出現在 .DIR 中的話,
將其刪除之. (這部份的 source 請自行 implement)
-----------------------------------------------------------------------------
以上這份報告,希望能夠帶來幫助給大家。
若有任何的問題,歡迎討論。 - 2002.04.28
Chen Chun-Han. is88050@cis.nctu.edu.tw
Dept. of Computer & Information Science
--
※ Origin: 楓橋驛站<bbs.cs.nthu.edu.tw> ◆ From: u5-214.u203-203.giga.net.tw
→
05/06 01:27, , 1F
05/06 01:27, 1F
→
05/06 01:27, , 2F
05/06 01:27, 2F
討論串 (同標題文章)
Maple 近期熱門文章
PTT數位生活區 即時熱門文章