看板Maple
标 题[Maple Bug 修正] - str_decode 造成 SIGSEGV
发信站清华资讯(枫桥驿站) (Sun Apr 28 00:39:40 2002)
转信站Ptt!news.cs.nthu!maple
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.
[email protected]
Dept. of Computer & Information Science
--
※ Origin: 枫桥驿站<bbs.cs.nthu.edu.tw> ◆ From: u5-214.u203-203.giga.net.tw
1F:→ Kukuxumusu: 只是偶尔闷闷的了 医师当时是觉得不用处理 我也不能 05/06 01:27
2F:→ Kukuxumusu: 免强他 05/06 01:27