summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkcwu <kcwu@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2006-04-01 22:28:03 +0800
committerkcwu <kcwu@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2006-04-01 22:28:03 +0800
commit68fb6de868a5e0daf128998cd60fe582f02dc287 (patch)
tree596b1a65c0ecf13b99408189fed9ccd2e4b45c64
parentfad5640e3ae7686f60becbb1130b9fd1f59c37d6 (diff)
downloadpttbbs-68fb6de868a5e0daf128998cd60fe582f02dc287.tar
pttbbs-68fb6de868a5e0daf128998cd60fe582f02dc287.tar.gz
pttbbs-68fb6de868a5e0daf128998cd60fe582f02dc287.tar.bz2
pttbbs-68fb6de868a5e0daf128998cd60fe582f02dc287.tar.lz
pttbbs-68fb6de868a5e0daf128998cd60fe582f02dc287.tar.xz
pttbbs-68fb6de868a5e0daf128998cd60fe582f02dc287.tar.zst
pttbbs-68fb6de868a5e0daf128998cd60fe582f02dc287.zip
make it harder to multi-login by race condition.
prevent logout function reenter. git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3319 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--mbbsd/mbbsd.c74
-rw-r--r--mbbsd/talk.c15
2 files changed, 56 insertions, 33 deletions
diff --git a/mbbsd/mbbsd.c b/mbbsd/mbbsd.c
index 31369b04..13b764d2 100644
--- a/mbbsd/mbbsd.c
+++ b/mbbsd/mbbsd.c
@@ -196,6 +196,13 @@ u_exit(const char *mode)
void
abort_bbs(int sig)
{
+ /* ignore normal signals */
+ Signal(SIGALRM, SIG_IGN);
+ Signal(SIGUSR1, SIG_IGN);
+ Signal(SIGUSR2, SIG_IGN);
+ Signal(SIGHUP, SIG_IGN);
+ Signal(SIGTERM, SIG_IGN);
+ Signal(SIGPIPE, SIG_IGN);
if (currmode)
u_exit("ABORTED");
exit(0);
@@ -257,7 +264,7 @@ abort_bbs_debug(int sig)
/* log */
/* assume vsnprintf() in log_file() is signal-safe, is it? */
log_file("log/crash.log", LOG_VF|LOG_CREAT,
- "%ld %d\n", time4(NULL), getpid());
+ "%ld %d %d %.12s\n", time4(NULL), getpid(), sig, cuser.userid);
/* try logout... not a good idea, maybe crash again. now disabled */
/*
@@ -532,7 +539,13 @@ getotherlogin(int num)
/* skip sleeping process, this is slow if lots */
if(ui->mode == DEBUGSLEEPING)
num++;
- } while (ui->mode == DEBUGSLEEPING);
+ else if(ui->pid <= 0)
+ num++;
+ else if(kill(ui->pid, 0) < 0)
+ num++;
+ else
+ break;
+ } while (1);
return ui;
}
@@ -546,28 +559,29 @@ multi_user_check(void)
if (HasUserPerm(PERM_SYSOP))
return; /* don't check sysops */
+ srandom(getpid());
+ // race condition here, sleep may help..?
if (cuser.userlevel) {
+ usleep(random()%1000000); // 0~1s
ui = getotherlogin(1);
if(ui == NULL)
return;
- if (!ui->pid /* || (kill(pid, 0) == -1) */ )
- return; /* stale entry in utmp file */
getdata(b_lines - 1, 0, "您想刪除其他重複的 login (Y/N)嗎?[Y] ",
genbuf, 3, LCECHO);
+ usleep(random()%1000000);
if (genbuf[0] != 'n') {
- // race condition here, sleep may help..?
- srandom(getpid());
- usleep(random()%1000000+100000); // 0.1~1.1s
do {
// scan again, old ui may be invalid
ui = getotherlogin(1);
if(ui==NULL)
return;
if (ui->pid > 0) {
- if(kill(ui->pid, SIGHUP)<0)
+ if(kill(ui->pid, SIGHUP)<0) {
+ perror("kill SIGHUP fail");
break;
+ }
log_usies("KICK ", cuser.nickname);
} else {
fprintf(stderr, "id=%s ui->pid=0\n", cuser.userid);
@@ -878,12 +892,12 @@ check_BM(void)
static void
setup_utmp(int mode)
{
+ /* NOTE, 在 getnewutmpent 之前不應該有任何 slow/blocking function */
userinfo_t uinfo;
memset(&uinfo, 0, sizeof(uinfo));
uinfo.pid = currpid = getpid();
uinfo.uid = usernum;
uinfo.mode = currstat = mode;
- uinfo.alerts |= load_mailalert(cuser.userid);
uinfo.userlevel = cuser.userlevel;
uinfo.sex = cuser.sex % 8;
@@ -1049,6 +1063,9 @@ user_login(void)
struct tm ptime, lasttime;
int nowusers, ifbirth = 0, i;
+ /* NOTE! 在 setup_utmp 之前, 不應該有任何 blocking/slow function,
+ * 否則可藉機 race condition 達到 multi-login */
+
/* get local time */
ptime = *localtime4(&now);
@@ -1062,25 +1079,6 @@ user_login(void)
((ptime.tm_mon+1) == cuser.month && ptime.tm_mday > cuser.day))) )
over18 = 1;
- /* show welcome_login */
- if( (ifbirth = (ptime.tm_mday == cuser.day &&
- ptime.tm_mon + 1 == cuser.month)) ){
- more("etc/Welcome_birth", NA);
- }
- else {
-#ifndef MULTI_WELCOME_LOGIN
- more("etc/Welcome_login", NA);
-#else
- if( SHM->GV2.e.nWelcomes ){
- char buf[80];
- snprintf(buf, sizeof(buf), "etc/Welcome_login.%d",
- (int)login_start_time % SHM->GV2.e.nWelcomes);
- more(buf, NA);
- }
-#endif
- }
- refresh();
-
log_usies("ENTER", fromhost);
#ifndef VALGRIND
setproctitle("%s: %s", margs, cuser.userid);
@@ -1110,6 +1108,26 @@ user_login(void)
enter_uflag = cuser.uflag;
lasttime = *localtime4(&cuser.lastlogin);
+ /* show welcome_login */
+ if( (ifbirth = (ptime.tm_mday == cuser.day &&
+ ptime.tm_mon + 1 == cuser.month)) ){
+ more("etc/Welcome_birth", NA);
+ }
+ else {
+#ifndef MULTI_WELCOME_LOGIN
+ more("etc/Welcome_login", NA);
+#else
+ if( SHM->GV2.e.nWelcomes ){
+ char buf[80];
+ snprintf(buf, sizeof(buf), "etc/Welcome_login.%d",
+ (int)login_start_time % SHM->GV2.e.nWelcomes);
+ more(buf, NA);
+ }
+#endif
+ }
+ refresh();
+ currutmp->alerts |= load_mailalert(cuser.userid);
+
if ((nowusers = SHM->UTMPnumber) > SHM->max_user) {
SHM->max_user = nowusers;
SHM->max_time = now;
diff --git a/mbbsd/talk.c b/mbbsd/talk.c
index abfd0e52..cde23af9 100644
--- a/mbbsd/talk.c
+++ b/mbbsd/talk.c
@@ -265,16 +265,19 @@ int sync_outta_server(int sfd)
if(res<0)
return -1;
if(res==2) {
+ close(sfd);
outs("登入太頻繁, 為避免系統負荷過重, 請稍後再試\n");
refresh();
- sleep(10);
- abort_bbs(0);
+ sleep(30);
+ log_usies("REJECTLOGIN", NULL);
+ memset(currutmp, 0, sizeof(userinfo_t));
+ exit(0);
}
verbose_progress(0, &iBar, &dir, barMax);
if(toread(sfd, &nfs, sizeof(nfs))<0)
return -1;
- if(nfs<0 || nfs>=MAX_FRIEND) {
+ if(nfs<0 || nfs>MAX_FRIEND*2) {
fprintf(stderr, "invalid nfs=%d\n",nfs);
return -1;
}
@@ -282,6 +285,8 @@ int sync_outta_server(int sfd)
if(toread(sfd, fs, sizeof(fs[0])*nfs)<0)
return -1;
+ close(sfd);
+
verbose_progress(0, &iBar, &dir, barMax);
for(i=0; i<nfs; i++) {
if( SHM->uinfo[fs[i].index].uid != fs[i].uid )
@@ -317,9 +322,9 @@ void login_friend_online(void)
sfd = toconnect(OUTTACACHEHOST, OUTTACACHEPORT);
if(sfd>=0) {
int res=sync_outta_server(sfd);
- close(sfd);
- if(res==0)
+ if(res==0) // sfd will be closed if return 0
return;
+ close(sfd);
}
#endif