免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: sisi8408

Kernel Bug-Vulnerability-Comment library [复制链接]

论坛徽章:
0
发表于 2007-08-19 19:03 |显示全部楼层

  1. /* linux-2.6.20.7/kernel/hrtimer.c
  2. *
  3. * Switch the timer base to the current CPU when possible
  4. */
  5. static inline struct hrtimer_base *
  6. switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_base *base)
  7. {
  8.         struct hrtimer_base *new_base;

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

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

  28.                 /* See the comment in lock_timer_base() */
  29.                 timer->base = NULL;
  30.                 spin_unlock(&base->lock);
  31.                 /*
  32.                  * When the timer's base is locked,
  33.                  * and the timer removed from list,
  34.                  * it is possible to set timer->base = NULL and
  35.                  * drop the lock: the timer remains locked.
  36.                  * =================================
  37.                  * ¥3
  38.                  * but during get new_base->lock,
  39.                  * how about base->curr_timer == timer ???
  40.                  * any warrant ??? what consequence ???
  41.                  */
  42.                 spin_lock(&new_base->lock);
  43.                 timer->base = new_base;
  44.         }
  45.         return new_base;
  46. }
复制代码

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

论坛徽章:
0
发表于 2007-08-19 20:31 |显示全部楼层

  1. /*
  2. * linux-2.6.20.7/kernel/hrtimer.c
  3. *
  4. * Expire the per base hrtimer-queue:
  5. */
  6. static inline void run_hrtimer_queue(struct hrtimer_base *base)
  7. {
  8.         struct rb_node *node;

  9.         if (!base->first)
  10.                 return;

  11.         if (base->get_softirq_time)
  12.                 base->softirq_time = base->get_softirq_time();

  13.         spin_lock_irq(&base->lock);

  14.         while ((node = base->first)) {
  15.                 struct hrtimer *timer;
  16.                 int (*fn)(struct hrtimer *);
  17.                 int restart;

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

  21.                 fn = timer->function;
  22.                 set_curr_timer(base, timer);
  23.                 __remove_hrtimer(timer, base);
  24.                 spin_unlock_irq(&base->lock);

  25.                 restart = fn(timer);

  26.                 spin_lock_irq(&base->lock);

  27.                 if (restart != HRTIMER_NORESTART) {
  28.                         BUG_ON(hrtimer_active(timer));
  29.                         /*
  30.                          * ¥2
  31.                          * no check to assure
  32.                          * 1, fair play among timers
  33.                          * 2, cpu potentially suck by one timer
  34.                          */
  35.                         enqueue_hrtimer(timer, base);
  36.                 }
  37.         }
  38.         set_curr_timer(base, NULL);
  39.         spin_unlock_irq(&base->lock);
  40. }
复制代码

论坛徽章:
0
发表于 2007-08-20 20:22 |显示全部楼层

  1. /*
  2. * linux-2.6.20.7/net/ipv4/netfilter/ip_conntrack_core.c
  3. * ¥8
  4. * this is not bug/vulnerability in any definition
  5. * but the so-called SBL, single/super big lock,
  6. * as the result of # grep ip_conntrack_lock linux-2.6.20.7/net/ipv4/netfilter/*.c
  7. * show its heavy impact upon performance of netfilter,
  8. * if ip conntrack in running system.
  9. *
  10. * though rcu plays not nice game without lock,
  11. * netfilter shouldnt be only protected by SBL.
  12. */
  13. DEFINE_RWLOCK(ip_conntrack_lock);
复制代码

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

论坛徽章:
0
发表于 2007-08-20 20:29 |显示全部楼层

回复 #20 mingyanguo 的帖子

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

论坛徽章:
0
发表于 2007-08-20 21:16 |显示全部楼层

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

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

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

  11.         /* e1000_clean is called per-cpu.  This lock protects
  12.          * tx_ring[0] from being cleaned by multiple cpus
  13.          * simultaneously.  A failure obtaining the lock means
  14.          * tx_ring[0] is currently being cleaned anyway.
  15.          *
  16.          * ¥8 logic bug
  17.          *
  18.          * linux-2.6.20.7/drivers/net/e1000/e1000_main.c
  19.          *
  20.          * not-well-known pseudo TX-hang occurs
  21.          * in some cases when RX is busy enough.
  22.          *
  23.          */
  24.         if (spin_trylock(&adapter->tx_queue_lock)) {
  25.                 tx_cleaned = e1000_clean_tx_irq(adapter,
  26.                                                 &adapter->tx_ring[0]);
  27.                 spin_unlock(&adapter->tx_queue_lock);
  28.         }

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

  31.         *budget -= work_done;
  32.         poll_dev->quota -= work_done;

  33.         /* If no Tx and not enough Rx work done, exit the polling mode */
  34.         if ((!tx_cleaned && (work_done == 0)) ||
  35.            !netif_running(poll_dev)) {
  36. quit_polling:
  37.                 if (likely(adapter->itr_setting & 3))
  38.                         e1000_set_itr(adapter);
  39.                 netif_rx_complete(poll_dev);
  40.                 e1000_irq_enable(adapter);
  41.                 return 0;
  42.         }

  43.         return 1;
  44. }
复制代码

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

论坛徽章:
0
发表于 2007-08-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.


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

  12. static __inline__ void __ipq_unlink(struct ipq *qp)
  13. {
  14. -        hlist_del(&qp->list);
  15. -        list_del(&qp->lru_list);
  16. +        hlist_del_rcu(&qp->list);
  17. +        list_del_rcu(&qp->lru_list);
  18.         ip_frag_nqueues--;
  19. }

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

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

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

  33.         while (work > 0) {
  34. -                read_lock(&ipfrag_lock);
  35. +                rcu_read_lock();
  36.                 if (list_empty(&ipq_lru_list)) {
  37. -                        read_unlock(&ipfrag_lock);
  38. +                        rcu_read_unlock();
  39.                         return;
  40.                 }
  41. -                tmp = ipq_lru_list.next;
  42. -                qp = list_entry(tmp, struct ipq, lru_list);
  43. +                tmp = rcu_dereference(ipq_lru_list.next);
  44. +                qp  = list_entry(tmp, struct ipq, lru_list);
  45.                 atomic_inc(&qp->refcnt);
  46. -                read_unlock(&ipfrag_lock);
  47. -
  48. +                rcu_read_unlock();
  49. +               
  50.                 spin_lock(&qp->lock);
  51.                 if (!(qp->last_in&COMPLETE))
  52.                         ipq_kill(qp);
  53. @@ -320,7 +321,7 @@ static struct ipq *ip_frag_intern(struct
  54.          * such entry could be created on other cpu, while we
  55.          * promoted read lock to write lock.
  56.          */
  57. -        hlist_for_each_entry(qp, n, &ipq_hash[hash], list) {
  58. +        hlist_for_each_entry_rcu(qp, n, &ipq_hash[hash], list) {
  59.                 if (qp->id == qp_in->id                &&
  60.                     qp->saddr == qp_in->saddr        &&
  61.                     qp->daddr == qp_in->daddr        &&
  62. @@ -340,9 +341,9 @@ static struct ipq *ip_frag_intern(struct
  63.                 atomic_inc(&qp->refcnt);

  64.         atomic_inc(&qp->refcnt);
  65. -        hlist_add_head(&qp->list, &ipq_hash[hash]);
  66. +        hlist_add_head_rcu(&qp->list, &ipq_hash[hash]);
  67.         INIT_LIST_HEAD(&qp->lru_list);
  68. -        list_add_tail(&qp->lru_list, &ipq_lru_list);
  69. +        list_add_tail_rcu(&qp->lru_list, &ipq_lru_list);
  70.         ip_frag_nqueues++;
  71.         write_unlock(&ipfrag_lock);
  72.         return qp;
  73. @@ -395,20 +396,20 @@ static inline struct ipq *ip_find(struct
  74.         struct ipq *qp;
  75.         struct hlist_node *n;

  76. -        read_lock(&ipfrag_lock);
  77. +        rcu_read_lock();
  78.         hash = ipqhashfn(id, saddr, daddr, protocol);
  79. -        hlist_for_each_entry(qp, n, &ipq_hash[hash], list) {
  80. +        hlist_for_each_entry_rcu(qp, n, &ipq_hash[hash], list) {
  81.                 if (qp->id == id                &&
  82.                     qp->saddr == saddr        &&
  83.                     qp->daddr == daddr        &&
  84.                     qp->protocol == protocol &&
  85.                     qp->user == user) {
  86.                         atomic_inc(&qp->refcnt);
  87. -                        read_unlock(&ipfrag_lock);
  88. +                        rcu_read_unlock();
  89.                         return qp;
  90.                 }
  91.         }
  92. -        read_unlock(&ipfrag_lock);
  93. +        rcu_read_lock();

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

  98.         write_lock(&ipfrag_lock);
  99. -        list_move_tail(&qp->lru_list, &ipq_lru_list);
  100. +        list_del_rcu(&qp->lru_list);
  101. +        list_add_tail_rcu(&qp->lru_list, &ipq_lru_list);
  102.         write_unlock(&ipfrag_lock);

  103.         return;
复制代码

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

论坛徽章:
0
发表于 2007-08-23 10:39 |显示全部楼层

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

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

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

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

  24.         /* Current number of expected connections */
  25.         unsigned int expecting;

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

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

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

  32.         union ip_conntrack_help help;

  33. #ifdef CONFIG_IP_NF_NAT_NEEDED
  34.         struct {
  35.                 struct ip_nat_info info;
  36.                 union ip_conntrack_nat_help help;
  37. #if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
  38.         defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
  39.                 int masq_index;
  40. #endif
  41.         } nat;
  42. #endif /* CONFIG_IP_NF_NAT_NEEDED */

  43. #if defined(CONFIG_IP_NF_CONNTRACK_MARK)
  44.         u_int32_t mark;
  45. #endif

  46. #ifdef CONFIG_IP_NF_CONNTRACK_SECMARK
  47.         u_int32_t secmark;
  48. #endif

  49.         /* Traversed often, so hopefully in different cacheline to top */
  50.         /* These are my tuples; original and reply */
  51.         struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
  52. };
复制代码

论坛徽章:
0
发表于 2007-08-23 11:37 |显示全部楼层

  1. void shrink_dcache_sb(struct super_block * sb)
  2. {
  3.         struct list_head *tmp, *next;
  4.         struct dentry *dentry;

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

  16.         /*
  17.          * Pass two ... free the dentries for this superblock.
  18.          */
  19. repeat:
  20.         list_for_each_safe(tmp, next, &dentry_unused) {
  21.                 dentry = list_entry(tmp, struct dentry, d_lru);
  22.                 if (dentry->d_sb != sb)
  23.                         continue;
  24.                 dentry_stat.nr_unused--;
  25.                 list_del_init(tmp);
  26.                 spin_lock(&dentry->d_lock);
  27.                 if (atomic_read(&dentry->d_count)) {
  28.                         /*
  29.                          * linux-2.6.20.7/fs/dcache.c
  30.                          *
  31.                          * ¥3
  32.                          * how can i get dentry on lru later?
  33.                          * where u go on earth?
  34.                          */
  35.                         spin_unlock(&dentry->d_lock);
  36.                         continue;
  37.                 }
  38.                 prune_one_dentry(dentry);
  39.                 cond_resched_lock(&dcache_lock);
  40.                 goto repeat;
  41.         }
  42.         spin_unlock(&dcache_lock);
  43. }
复制代码

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

论坛徽章:
0
发表于 2007-08-23 20:45 |显示全部楼层
你说的这里有什么问题? 能否详细说一下?

原帖由 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
发表于 2007-08-24 09:39 |显示全部楼层

  1. int ocfs2_node_map_is_only(struct ocfs2_super *osb,
  2.                            struct ocfs2_node_map *target,
  3.                            int bit)
  4. {
  5.         struct ocfs2_node_map temp;
  6.         int ret;

  7.         spin_lock(&osb->node_map_lock);
  8.         __ocfs2_node_map_dup(&temp, target);
  9.         /*
  10.          * linux-2.6.20.7/fs/ocfs2/heartbeat.c
  11.          *
  12.          * ¥1
  13.          *
  14.          * abuse of spin_lock
  15.          */
  16.         __ocfs2_node_map_clear_bit(&temp, bit);
  17.         ret = __ocfs2_node_map_is_empty(&temp);
  18.         spin_unlock(&osb->node_map_lock);

  19.         return ret;
  20. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP