Linux.ChinaUnix.net
ChinaUnix | Linux首页 | 新闻 | 博客 | 文章 | 专栏 | 新手 | 方案 | 图书 | 下载 | 人才 | 手册 | wiki | 搜索     
Linux论坛
  会员: 密码: 免费注册 | 忘记密码 | 会员登录 | 搜索 | 帮助 


奥运快报: 
奥运热点:
 

Kernel Bug-Vulnerability-Comment library
首页 » CU论坛 » Linux » 汇总贴列表 » 内核源码 »  
[打印] [订阅] [收藏] [推荐给朋友] [本帖文本页]
sisi8408 (linux八哥)
风云使者




UID:509266
注册:2006-12-22
最后登录: 2008-07-28
帖子:617
精华:0

可用积分:567 (稍有积蓄)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

状态:...离线...

[资料] [站内短信] [Blog]


顶部
21楼 发表于 2007-8-19 19:03 


/* linux-2.6.20.7/kernel/hrtimer.c
*
* Switch the timer base to the current CPU when possible
*/
static inline struct hrtimer_base *
switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_base *base)
{
        struct hrtimer_base *new_base;

        new_base = &__get_cpu_var(hrtimer_bases)[base->index];

        if (base != new_base) {
                /*
                 * We are trying to schedule the timer on the local CPU.
                 *
                 * However we can't change timer's base while it is running,
                 * so we keep it on the same CPU.
                 *
                 * No hassle vs. reprogramming
                 * the event source in the high resolution case.
                 *
                 * The softirq code will take care of this,
                 * when the timer function has completed.
                 *
                 * There is no conflict, as we hold the lock until
                 * the timer is enqueued.
                 */
                if (unlikely(base->curr_timer == timer))
                        return base;

                /* See the comment in lock_timer_base() */
                timer->base = NULL;
                spin_unlock(&base->lock);
                /*
                 * When the timer's base is locked,
                 * and the timer removed from list,
                 * it is possible to set timer->base = NULL and
                 * drop the lock: the timer remains locked.
                 * =================================
                 * ¥3
                 * but during get new_base->lock,
                 * how about base->curr_timer == timer ???
                 * any warrant ??? what consequence ???
                 */
                spin_lock(&new_base->lock);
                timer->base = new_base;
        }
        return new_base;
}

[ 本帖最后由 sisi8408 于 2007-8-20 20:38 编辑 ]



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

东直门外大街
张字85号
丁字96号

空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
sisi8408 (linux八哥)
风云使者




UID:509266
注册:2006-12-22
最后登录: 2008-07-28
帖子:617
精华:0

可用积分:567 (稍有积蓄)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

状态:...离线...

[资料] [站内短信] [Blog]


顶部
22楼 发表于 2007-8-19 20:31 


/*
* linux-2.6.20.7/kernel/hrtimer.c
*
* Expire the per base hrtimer-queue:
*/
static inline void run_hrtimer_queue(struct hrtimer_base *base)
{
        struct rb_node *node;

        if (!base->first)
                return;

        if (base->get_softirq_time)
                base->softirq_time = base->get_softirq_time();

        spin_lock_irq(&base->lock);

        while ((node = base->first)) {
                struct hrtimer *timer;
                int (*fn)(struct hrtimer *);
                int restart;

                timer = rb_entry(node, struct hrtimer, node);
                if (base->softirq_time.tv64 <= timer->expires.tv64)
                        break;

                fn = timer->function;
                set_curr_timer(base, timer);
                __remove_hrtimer(timer, base);
                spin_unlock_irq(&base->lock);

                restart = fn(timer);

                spin_lock_irq(&base->lock);

                if (restart != HRTIMER_NORESTART) {
                        BUG_ON(hrtimer_active(timer));
                        /*
                         * ¥2
                         * no check to assure
                         * 1, fair play among timers
                         * 2, cpu potentially suck by one timer
                         */
                        enqueue_hrtimer(timer, base);
                }
        }
        set_curr_timer(base, NULL);
        spin_unlock_irq(&base->lock);
}




您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

东直门外大街
张字85号
丁字96号

空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
sisi8408 (linux八哥)
风云使者




UID:509266
注册:2006-12-22
最后登录: 2008-07-28
帖子:617
精华:0

可用积分:567 (稍有积蓄)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

状态:...离线...

[资料] [站内短信] [Blog]


顶部
23楼 发表于 2007-8-20 20:22 


/*
* linux-2.6.20.7/net/ipv4/netfilter/ip_conntrack_core.c
* ¥8
* this is not bug/vulnerability in any definition
* but the so-called SBL, single/super big lock,
* as the result of # grep ip_conntrack_lock linux-2.6.20.7/net/ipv4/netfilter/*.c
* show its heavy impact upon performance of netfilter,
* if ip conntrack in running system.
*
* though rcu plays not nice game without lock,
* netfilter shouldnt be only protected by SBL.
*/
DEFINE_RWLOCK(ip_conntrack_lock);

[ 本帖最后由 sisi8408 于 2007-8-20 23:21 编辑 ]



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

东直门外大街
张字85号
丁字96号

空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
sisi8408 (linux八哥)
风云使者




UID:509266
注册:2006-12-22
最后登录: 2008-07-28
帖子:617
精华:0

可用积分:567 (稍有积蓄)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

状态:...离线...

[资料] [站内短信] [Blog]


顶部
24楼 发表于 2007-8-20 20:29 
回复 #20 mingyanguo 的帖子

大哥,您一路辛苦,八哥有茶水相待。
您心情好,就贴个方案。



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

东直门外大街
张字85号
丁字96号

空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
sisi8408 (linux八哥)
风云使者




UID:509266
注册:2006-12-22
最后登录: 2008-07-28
帖子:617
精华:0

可用积分:567 (稍有积蓄)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

状态:...离线...

[资料] [站内短信] [Blog]


顶部
25楼 发表于 2007-8-20 21:16 


static int e1000_clean(struct net_device *poll_dev, int *budget)
{
        struct e1000_adapter *adapter;
        int work_to_do = min(*budget, poll_dev->quota);
        int tx_cleaned = 0, work_done = 0;

        /* Must NOT use netdev_priv macro here. */
        adapter = poll_dev->priv;

        /* Keep link state information with original netdev */
        if (!netif_carrier_ok(poll_dev))
                goto quit_polling;

        /* e1000_clean is called per-cpu.  This lock protects
         * tx_ring[0] from being cleaned by multiple cpus
         * simultaneously.  A failure obtaining the lock means
         * tx_ring[0] is currently being cleaned anyway.
         *
         * ¥8 logic bug
         *
         * linux-2.6.20.7/drivers/net/e1000/e1000_main.c
         *
         * not-well-known pseudo TX-hang occurs
         * in some cases when RX is busy enough.
         *
         */
        if (spin_trylock(&adapter->tx_queue_lock)) {
                tx_cleaned = e1000_clean_tx_irq(adapter,
                                                &adapter->tx_ring[0]);
                spin_unlock(&adapter->tx_queue_lock);
        }

        adapter->clean_rx(adapter, &adapter->rx_ring[0],
                          &work_done, work_to_do);

        *budget -= work_done;
        poll_dev->quota -= work_done;

        /* If no Tx and not enough Rx work done, exit the polling mode */
        if ((!tx_cleaned && (work_done == 0)) ||
           !netif_running(poll_dev)) {
quit_polling:
                if (likely(adapter->itr_setting & 3))
                        e1000_set_itr(adapter);
                netif_rx_complete(poll_dev);
                e1000_irq_enable(adapter);
                return 0;
        }

        return 1;
}

[ 本帖最后由 sisi8408 于 2007-8-20 23:24 编辑 ]



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

东直门外大街
张字85号
丁字96号

空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
sisi8408 (linux八哥)
风云使者




UID:509266
注册:2006-12-22
最后登录: 2008-07-28
帖子:617
精华:0

可用积分:567 (稍有积蓄)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

状态:...离线...

[资料] [站内短信] [Blog]


顶部
26楼 发表于 2007-8-21 11:29 
it is hot&hard to deal with SBL,
but another version of, maybe slower, fragment treatment can be made with rcu,
of cough, possibly followed with bug&vulnerability,
to rx frag either legal or illegal.

--- linux-2.6.22.1/net/ipv4/ip_fragment.c        2007-07-11 02:56:30.000000000 +0800
+++ /usr/src/chg/ip_fragment3.c        2007-08-21 11:27:03.000000000 +0800
@@ -25,6 +25,7 @@
#include <linux/compiler.h>
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/rcupdate.h>
#include <linux/mm.h>
#include <linux/jiffies.h>
#include <linux/skbuff.h>
@@ -111,8 +112,8 @@ int ip_frag_nqueues = 0;

static __inline__ void __ipq_unlink(struct ipq *qp)
{
-        hlist_del(&qp->list);
-        list_del(&qp->lru_list);
+        hlist_del_rcu(&qp->list);
+        list_del_rcu(&qp->lru_list);
        ip_frag_nqueues--;
}

@@ -149,10 +150,10 @@ static void ipfrag_secret_rebuild(unsign
                                                      q->daddr, q->protocol);

                        if (hval != i) {
-                                hlist_del(&q->list);
+                                hlist_del_rcu(&q->list);

                                /* Relink to new hash chain. */
-                                hlist_add_head(&q->list, &ipq_hash[hval]);
+                                hlist_add_head_rcu(&q->list, &ipq_hash[hval]);
                        }
                }
        }
@@ -252,16 +253,16 @@ static void ip_evictor(void)
                return;

        while (work > 0) {
-                read_lock(&ipfrag_lock);
+                rcu_read_lock();
                if (list_empty(&ipq_lru_list)) {
-                        read_unlock(&ipfrag_lock);
+                        rcu_read_unlock();
                        return;
                }
-                tmp = ipq_lru_list.next;
-                qp = list_entry(tmp, struct ipq, lru_list);
+                tmp = rcu_dereference(ipq_lru_list.next);
+                qp  = list_entry(tmp, struct ipq, lru_list);
                atomic_inc(&qp->refcnt);
-                read_unlock(&ipfrag_lock);
-
+                rcu_read_unlock();
+               
                spin_lock(&qp->lock);
                if (!(qp->last_in&COMPLETE))
                        ipq_kill(qp);
@@ -320,7 +321,7 @@ static struct ipq *ip_frag_intern(struct
         * such entry could be created on other cpu, while we
         * promoted read lock to write lock.
         */
-        hlist_for_each_entry(qp, n, &ipq_hash[hash], list) {
+        hlist_for_each_entry_rcu(qp, n, &ipq_hash[hash], list) {
                if (qp->id == qp_in->id                &&
                    qp->saddr == qp_in->saddr        &&
                    qp->daddr == qp_in->daddr        &&
@@ -340,9 +341,9 @@ static struct ipq *ip_frag_intern(struct
                atomic_inc(&qp->refcnt);

        atomic_inc(&qp->refcnt);
-        hlist_add_head(&qp->list, &ipq_hash[hash]);
+        hlist_add_head_rcu(&qp->list, &ipq_hash[hash]);
        INIT_LIST_HEAD(&qp->lru_list);
-        list_add_tail(&qp->lru_list, &ipq_lru_list);
+        list_add_tail_rcu(&qp->lru_list, &ipq_lru_list);
        ip_frag_nqueues++;
        write_unlock(&ipfrag_lock);
        return qp;
@@ -395,20 +396,20 @@ static inline struct ipq *ip_find(struct
        struct ipq *qp;
        struct hlist_node *n;

-        read_lock(&ipfrag_lock);
+        rcu_read_lock();
        hash = ipqhashfn(id, saddr, daddr, protocol);
-        hlist_for_each_entry(qp, n, &ipq_hash[hash], list) {
+        hlist_for_each_entry_rcu(qp, n, &ipq_hash[hash], list) {
                if (qp->id == id                &&
                    qp->saddr == saddr        &&
                    qp->daddr == daddr        &&
                    qp->protocol == protocol &&
                    qp->user == user) {
                        atomic_inc(&qp->refcnt);
-                        read_unlock(&ipfrag_lock);
+                        rcu_read_unlock();
                        return qp;
                }
        }
-        read_unlock(&ipfrag_lock);
+        rcu_read_lock();

        return ip_frag_create(iph, user);
}
@@ -599,7 +600,8 @@ static void ip_frag_queue(struct ipq *qp
                qp->last_in |= FIRST_IN;

        write_lock(&ipfrag_lock);
-        list_move_tail(&qp->lru_list, &ipq_lru_list);
+        list_del_rcu(&qp->lru_list);
+        list_add_tail_rcu(&qp->lru_list, &ipq_lru_list);
        write_unlock(&ipfrag_lock);

        return;

[ 本帖最后由 sisi8408 于 2007-8-22 10:48 编辑 ]



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

东直门外大街
张字85号
丁字96号

空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
sisi8408 (linux八哥)
风云使者




UID:509266
注册:2006-12-22
最后登录: 2008-07-28
帖子:617
精华:0

可用积分:567 (稍有积蓄)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

状态:...离线...

[资料] [站内短信] [Blog]


顶部
27楼 发表于 2007-8-23 10:39 


struct ip_conntrack
{
        /* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
           plus 1 for any connection(s) we are `master' for */
        struct nf_conntrack ct_general;

        /* Have we seen traffic both ways yet? (bitset) */
        unsigned long status;

        /* Timer function; drops refcnt when it goes off. */
        /*
         * linux-2.6.20.7/include/linux/netfilter_ipv4/ip_conntrack.h
         * ¥8
         * potential vulnerability in design
         *
         * if as boasted, FW warrant 1M connections,
         * how many cpus required to response timer?
         */
        struct timer_list timeout;

#ifdef CONFIG_IP_NF_CT_ACCT
        /* Accounting Information (same cache line as other written members) */
        struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
#endif
        /* If we were expected by an expectation, this will be it */
        struct ip_conntrack *master;

        /* Current number of expected connections */
        unsigned int expecting;

        /* Unique ID that identifies this conntrack*/
        unsigned int id;

        /* Helper, if any. */
        struct ip_conntrack_helper *helper;

        /* Storage reserved for other modules: */
        union ip_conntrack_proto proto;

        union ip_conntrack_help help;

#ifdef CONFIG_IP_NF_NAT_NEEDED
        struct {
                struct ip_nat_info info;
                union ip_conntrack_nat_help help;
#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
        defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
                int masq_index;
#endif
        } nat;
#endif /* CONFIG_IP_NF_NAT_NEEDED */

#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
        u_int32_t mark;
#endif

#ifdef CONFIG_IP_NF_CONNTRACK_SECMARK
        u_int32_t secmark;
#endif

        /* Traversed often, so hopefully in different cacheline to top */
        /* These are my tuples; original and reply */
        struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
};




您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

东直门外大街
张字85号
丁字96号

空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
sisi8408 (linux八哥)
风云使者




UID:509266
注册:2006-12-22
最后登录: 2008-07-28
帖子:617
精华:0

可用积分:567 (稍有积蓄)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

状态:...离线...

[资料] [站内短信] [Blog]


顶部
28楼 发表于 2007-8-23 11:37 


void shrink_dcache_sb(struct super_block * sb)
{
        struct list_head *tmp, *next;
        struct dentry *dentry;

        /*
         * Pass one ... move the dentries for the specified
         * superblock to the most recent end of the unused list.
         */
        spin_lock(&dcache_lock);
        list_for_each_safe(tmp, next, &dentry_unused) {
                dentry = list_entry(tmp, struct dentry, d_lru);
                if (dentry->d_sb != sb)
                        continue;
                list_move(tmp, &dentry_unused);
        }

        /*
         * Pass two ... free the dentries for this superblock.
         */
repeat:
        list_for_each_safe(tmp, next, &dentry_unused) {
                dentry = list_entry(tmp, struct dentry, d_lru);
                if (dentry->d_sb != sb)
                        continue;
                dentry_stat.nr_unused--;
                list_del_init(tmp);
                spin_lock(&dentry->d_lock);
                if (atomic_read(&dentry->d_count)) {
                        /*
                         * linux-2.6.20.7/fs/dcache.c
                         *
                         * ¥3
                         * how can i get dentry on lru later?
                         * where u go on earth?
                         */
                        spin_unlock(&dentry->d_lock);
                        continue;
                }
                prune_one_dentry(dentry);
                cond_resched_lock(&dcache_lock);
                goto repeat;
        }
        spin_unlock(&dcache_lock);
}

[ 本帖最后由 sisi8408 于 2007-8-23 11:40 编辑 ]



您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

东直门外大街
张字85号
丁字96号

空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
版主 思一克   帅哥
版主-法师




UID:88701
注册:2003-8-25
最后登录: 2008-08-28
帖子:5739
精华:14

可用积分:6794 (富足长乐)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

来自:东城
状态:...保密...

[资料] [站内短信] [Blog]


顶部
29楼 发表于 2007-8-23 20:45 
你说的这里有什么问题? 能否详细说一下?

QUOTE:
原帖由 sisi8408 于 2007-8-23 11:37 发表 [url=http://linux.chinaunix.net/bbs/redirect.php?goto=findpost&&

void shrink_dcache_sb(struct super_block * sb)
{
        struct list_head *tmp, *next;
        struct dentry *dentry;

        /*
         * Pass one ... move the dentries for the specified
         * superblock to the most recent end of the unused list.
         */
        spin_lock(&dcache_lock);
        list_for_each_safe(tmp, next, &dentry_unused) {
                dentry = list_entry(tmp, struct dentry, d_lru);
                if (dentry->d_sb != sb)
                        continue;
                list_move(tmp, &dentry_unused);
        }

        /*
         * Pass two ... free the dentries for this superblock.
         */
repeat:
        list_for_each_safe(tmp, next, &dentry_unused) {
                dentry = list_entry(tmp, struct dentry, d_lru);
                if (dentry->d_sb != sb)
                        continue;
                dentry_stat.nr_unused--;
                list_del_init(tmp);
                spin_lock(&dentry->d_lock);
                if (atomic_read(&dentry->d_count)) {
                        /*
                         * linux-2.6.20.7/fs/dcache.c
                         *
                         * ¥3
                         * how can i get dentry on lru later?
                         * where u go on earth?
                         */
                        spin_unlock(&dentry->d_lock);
                        continue;
                }
                prune_one_dentry(dentry);
                cond_resched_lock(&dcache_lock);
                goto repeat;
        }
        spin_unlock(&dcache_lock);
}




您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

Email: johnye@webizmail.com
空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘
sisi8408 (linux八哥)
风云使者




UID:509266
注册:2006-12-22
最后登录: 2008-07-28
帖子:617
精华:0

可用积分:567 (稍有积蓄)
信誉积分:100
空间积分:0 (白手起家)
专家积分:0 (本版)

状态:...离线...

[资料] [站内短信] [Blog]


顶部
30楼 发表于 2007-8-24 09:39 


int ocfs2_node_map_is_only(struct ocfs2_super *osb,
                           struct ocfs2_node_map *target,
                           int bit)
{
        struct ocfs2_node_map temp;
        int ret;

        spin_lock(&osb->node_map_lock);
        __ocfs2_node_map_dup(&temp, target);
        /*
         * linux-2.6.20.7/fs/ocfs2/heartbeat.c
         *
         * ¥1
         *
         * abuse of spin_lock
         */
        __ocfs2_node_map_clear_bit(&temp, bit);
        ret = __ocfs2_node_map_is_empty(&temp);
        spin_unlock(&osb->node_map_lock);

        return ret;
}




您对本贴的看法:鲜花[0] 臭蛋[0]

__________________________________

东直门外大街
张字85号
丁字96号

空间积分可以换礼品了! | 有奖跟帖:服务器节能,奖50-100元图书 | 致电800-858-2903,了解DELL如何为你量身订制笔记本 | 送2G U盘

首页 » CU论坛 » Linux » 汇总贴列表 » 内核源码 »

 


Copyright © 2001-2008 ChinaUnix.net All Rights Reserved     联系我们:

感谢所有关心和支持过ChinaUnix的朋友们    转载本站内容请注明原作者名及出处

京ICP证041476号


清除 Cookies - Linux时代 - Archiver - WAP - TOP

Processed in 0.292968 second(s), 5 queries , Gzip enabled