荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: jjk (pq), 信区: InstallBBS
标  题: [范文5][BBSDev]关于FB的所谓超级隐身bug
发信站: 荔园晨风BBS站 (Thu Nov 29 11:21:15 2001), 转信

【 以下文字转载自 jjk 的信箱 】
【 原文由 jjk.bbs@bbs.pku.edu.cn 所发表 】
发信人: vida (下一个自杀的id...), 信区: BBSDev
标  题: [范文5][BBSDev]关于FB的所谓超级隐身bug
发信站: 北大未名站 (2001年05月23日22:07:09 星期三), 站内信件


发信人: Figue (斐哥--回到原点), 信区: BBSDev
标  题: [范文5][BBSDev]关于FB的所谓超级隐身bug
发信站: 一塌糊涂 BBS (Sun Jul  9 15:26:17 2000)

发信人: ylsdd (ylsdd), 信区: InstallBBS
标  题: [范文5][BBSDev]关于FB的所谓超级隐身bug
发信站: 华南网木棉站 (Sun May 21 16:50:19 2000), 转信

【 以下文字转载自 ylsdd 的信箱 】

这个问题我在ytht bbs上基本解决了, 关键问题就是fb系统常常忘了
系统名单是个共用的东西, 致使不同进程占用同一名单项

*********bcache.c*******************
int
getnewutmpent( up )
struct user_info *up;
{
    /* static int          utmpfd;*/
    int utmpfd;
    struct user_info    *uentp;
    time_t      now;
    int         i, n, num[2];

    /*--------modified by ylsdd, utmpfd 不需要是static的---
        if( utmpfd < 0 )LIST, O_RDWR|O_CREAT, 0600 );
        if( utmpfd < 0 )
            return -1;
    }
    ---------------------------*/
    utmpfd = open( ULIST, O_RDWR|O_CREAT, 0600 );
    if( utmpfd < 0 ) return -1;

    resolve_utmp();
    flock( utmpfd, LOCK_EX );
    for( i = 0; i < USHM_SIZE; i++ ) {
        uentp = &(utmpshm->uinfo[ i ]);
        if( !uentp->active || !uentp->pid ) break ;
    }
    if( i >= USHM_SIZE ) {
        flock( utmpfd, LOCK_UN );
        return -1;
    }
    utmpshm->uinfo[i] = *up;
    /* flock( utmpfd, LOCK_UN ); */   /*向下移动到函数尾部. by ylsdd*/
    now = time( NULL );
    if( now > utmpshm->uptime + 60 ) {
        num[0]=num[1]=0;
        utmpshm->uptime = now;
        for( n = 0; n < USHM_SIZE; n++ ) {
            uentp = &(utmpshm->uinfo[ n ]);
            if( uentp->active && uentp->pid )
            {
                if(kill( uentp->pid, 0 ) == -1)
                {
                        memset( uentp, 0, sizeof( struct user_info ) );
                        continue;
                }else
                {
                        num[(uentp->invisible==YEA)?1:0]++;
                }
            }
        }
        utmpshm->usersum=allusers();
        n = USHM_SIZE - 1;
        while( n > 0 && utmpshm->uinfo[ n ].active == 0 )
            n--;
        ftruncate( utmpfd, 0 );
        write( utmpfd, utmpshm->uinfo, (n+1) * sizeof(struct user_info) );
    }
    flock( utmpfd, LOCK_UN );  /*by ylsdd*/
    close(utmpfd);
    return i+1 ;
}
****************delete.c, kick_user********************************
    sprintf(buffer, "kicked %s", kickuser);
    report(buffer);
    sprintf( genbuf, "%s (%s)", kuinfo.userid, kuinfo.username );
    log_usies( "KICK ", genbuf );
/*----main中设置了SIGHUP为abort_bbs-->u_exit, 信号获取
方做update的事, 这里不必做了, 而且做了会导致某些混乱.(ylsdd)
    uin.active = NA;
    uin.pid = 0;
    uin.invisible = YEA;
    uin.sockactive = 0;
    uin.sockaddr = 0;
    uin.destuid = 0;
    update_ulist( &uin, ind );
--------------------*/
    move(2,0) ;
   if(uinfo.mode!=LUSERS&&uinfo.mode!=OFFLINE&&uinfo.mode!=FRIEND)
****************main.c u_exit********************
void
u_exit()
{   /*这些信号的处理要关掉, 否则在离线时等候回车时出现
      信号会导致重写名单, 这个导致的名单混乱比kick user更多*/
    signal(SIGHUP, SIG_DFL);
    signal(SIGALRM, SIG_DFL);
    signal(SIGPIPE, SIG_DFL);
    signal(SIGTERM, SIG_DFL);
    signal(SIGUSR1, SIG_IGN);
    signal(SIGUSR2, SIG_IGN);
    setflags(PAGER_FLAG, (uinfo.pager&ALL_PAGER));
    if (HAS_PERM(PERM_LOGINCLOAK))
        setflags(CLOAK_FLAG, uinfo.invisible);

    if( currentuser.flags[0] != enter_uflags && !ERROR_READ_SYSTEM_FILE) {
        set_safe_record();

substitute_record(PASSFILE,&currentuser,sizeof(currentuser),usernum);
    }

    uinfo.active = NA ;
    uinfo.pid = 0 ;
    uinfo.invisible = YEA ;
    uinfo.sockactive = NA ;
    uinfo.sockaddr = 0 ;
    uinfo.destuid = 0 ;
#ifdef SHOW_IDLE_TIME
    strcpy(uinfo.tty, "NoTTY");
#endif
    update_utmp2();
}
***********************************************
另外注意各处的kill, 要防止kill(0,*), 这是对进程
组里的所有id发信号, fb的代码容易造成这点, 特别是
在用bbsd时, 会经常导致bbsd死掉, 先前我为了防止发
消息时的显示混乱采用了在两个kill之间sleep的方法,
使得这个问题很严重才发现的, 要改的地方好多.
********************************************

【 在 zhch (zhch) 的大作中提到: 】
: 发信人: zhch (sign, halt now.), 信区: BBSDev
: 标  题: 关于FB产生超级隐身bug的一种可能.
: 发信站: 南京大学小百合站 (Thu Apr  6 23:12:41 2000), 转信
: 通常都认为是同时访问shm的问题. 但我仔细看了看 u_enter(), getnewutmpent()
: 等函数, 内容都是很清楚的, 应该没有问题.
: 找来找去, 我认为最可疑的是kick_user()函数, 摘录如下:
: 1:        kill(uin.pid, SIGHUP);
: 2:        sprintf(buffer, "kicked %s", kickuser);
: 3:        report(buffer);
: 4:        sprintf(genbuf, "%s (%s)", kuinfo.userid, kuinfo.username);
: 5:        log_usies("KICK ", genbuf);
: 6:        uin.active = NA;
: 7:        uin.pid = 0;
:           uin.invisible = YEA;
:           uin.sockactive = 0;
:           uin.sockaddr = 0;
:           uin.destuid = 0;
:           update_ulist(&uin, ind);
: 本来, 有第一句一个kill()就足够把人踢下去了, 后面的那些语句颇有画蛇添足之嫌,

: 考虑下面这样一种情况:
: 进程c执行1后, 某a被kick下去了, 这时有b连进来, getnewutmpent()时发现a的pid不


: 存在了, 就占了a的这块shm区域, 然后进程c执行6, 7, 把b的.pid和.active清掉了,
: 以后再登录的d就会和b占用同一块shm内存区. 从理论上说, 以上问题可产生这个FB超

: 级隐身bug. 但是否事实就是如此还有待证实.
: 另外, 我觉得.active属性没有任何用处, 和.pid重复, 该去掉.

--
欢迎大家来Software版!
        这里提供各种最新软件信息,软件的使用以及评测。
        同时非常希望大家写出自己的心得体会!

欢迎访问北大FTP联盟主页:http://www.pkuftp.dhs.org

※ 来源:·北大未名站 bbs.pku.edu.cn·[FROM: 162.105.170.50]
--
※ 转载:·北大未名站 bbs.pku.edu.cn·[FROM: 166.111.215.160]
--
※ 转寄:·北大未名站 bbs.pku.edu.cn·[FROM: 210.39.3.50]
--
※ 转载:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.0.146]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店