- 論壇徽章:
- 0
|
1) net_ratelimit()用于保護內(nèi)核網(wǎng)絡(luò)調(diào)試信息的打印, 當它返回(TRUE)時則可以打印調(diào)試信息,
返回零則禁止信息打印. 它的特性為當"極快地"調(diào)用net_ratelimit()時,它最多只允許連續(xù)打印
前10條信息, 后繼信息每隔5秒允許打印一次.這樣可防止攻擊者使內(nèi)核不斷產(chǎn)生調(diào)試信息來使系
統(tǒng)過載的拒絕服務(wù)攻擊.
2) net_ratelimit()定義了一個時間計數(shù)器變量(toks), 它隨著系統(tǒng)時鐘計數(shù)線性增長,
但不超時50秒時鐘計數(shù)(net_msg_burst). 當計時器的值大于或等于5秒時鐘計數(shù)(net_msg_cost)時,
則允許打印信息. 每允許打印一條信息, 計時器就減去5秒計數(shù), 當計時器的值小于5秒時, 就
不允許打印信息了.
; net/core/utils.c:
int net_msg_cost = 5*HZ; /*在擁塞時, 每條網(wǎng)絡(luò)消息記錄所間隔的時間*/
int net_msg_burst = 10*5*HZ; /*連續(xù)記錄網(wǎng)絡(luò)突發(fā)消息的間隔(最多連續(xù)記錄10條消息)*/
/*
* This enforces a rate limit: not more than one kernel message
* every 5secs to make a denial-of-service attack impossible.
*
* All warning printk()s should be guarded by this function.
*/
int net_ratelimit(void)
{
static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
static unsigned long toks = 10*5*HZ; /*50秒量程的計時器,每打印一條消息,計時器減5秒時間*/
static unsigned long last_msg; /*上一次調(diào)用net_ratelimit()的時戳*/
static int missed; /*兩次net_ratelimit()調(diào)用之間所丟棄的信息數(shù)量*/
unsigned long flags;
unsigned long now = jiffies; /*取當前時戳*/
spin_lock_irqsave(&ratelimit_lock, flags);
toks += now - last_msg;
/*計時器加上兩次net_ratelimit()調(diào)用的時間差,表現(xiàn)為計時時間的線性增長*/
last_msg = now;
if (toks > net_msg_burst) /*計時器累積時間超時50秒時*/
toks = net_msg_burst;/* 設(shè)置計時上限*/
if (toks >= net_msg_cost) { /*當計時大于或等于5秒時可以打印信息*/
int lost = missed;
missed = 0;
toks -= net_msg_cost; /*減去5秒時間*/
spin_unlock_irqrestore(&ratelimit_lock, flags);
if (lost)
printk(KERN_WARNING "NET: %d messages suppressed.\n", lost);
return 1;
}
missed++;
spin_unlock_irqrestore(&ratelimit_lock, flags);
return 0;
}
/*linux 2.6內(nèi)核直接調(diào)用__printk_ratelimit()*/
int net_ratelimit(void)
{
return __printk_ratelimit(net_msg_cost, net_msg_burst);
}
kernel/printk.c
/*
* printk rate limiting, lifted from the networking subsystem.
*
* This enforces a rate limit: not more than one kernel message
* every printk_ratelimit_jiffies to make a denial-of-service
* attack impossible.
*/
int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
{
static DEFINE_SPINLOCK(ratelimit_lock);
static unsigned long toks = 10 * 5 * HZ;
static unsigned long last_msg;
static int missed;
unsigned long flags;
unsigned long now = jiffies;
spin_lock_irqsave(&ratelimit_lock, flags);
toks += now - last_msg;
last_msg = now;
if (toks > (ratelimit_burst * ratelimit_jiffies))
toks = ratelimit_burst * ratelimit_jiffies;
if (toks >= ratelimit_jiffies) {
int lost = missed;
missed = 0;
toks -= ratelimit_jiffies;
spin_unlock_irqrestore(&ratelimit_lock, flags);
if (lost)
printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
return 1;
}
missed++;
spin_unlock_irqrestore(&ratelimit_lock, flags);
return 0;
}
本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u1/33173/showart_1161828.html |
|