免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 36650 | 回复: 149
打印 上一主题 下一主题

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

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-08-18 13:49 |只看该作者 |倒序浏览
这里搜集/整理/讨论 linux 八哥/漏洞,和解决方案

[ 本帖最后由 sisi8408 于 2008-7-27 14:20 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-08-18 13:52 |只看该作者

  1. linux-2.6.17.x/drivers/net/ppp_generic.c

  2. static void cardmap_set(struct cardmap **pmap, unsigned int nr, void *ptr)
  3. {
  4.         struct cardmap *p;
  5.         int i;

  6.         p = *pmap;
  7.         if (p == NULL || (nr >> p->shift) >= CARDMAP_WIDTH) {
  8.                 do {
  9.                         /* need a new top level */
  10.                         struct cardmap *np = kmalloc(sizeof(*np), GFP_KERNEL);
  11.                         /*
  12.                          * ¥6
  13.                          * if (np == NULL)
  14.                          *        what_to_do???
  15.                          */
  16.                         memset(np, 0, sizeof(*np));
  17.                         np->ptr[0] = p;
  18.                         if (p != NULL) {
  19.                                 np->shift = p->shift + CARDMAP_ORDER;
  20.                                 p->parent = np;
  21.                         } else
  22.                                 np->shift = 0;
  23.                         p = np;
  24.                         /*
  25.                          * ¥3
  26.                          * if (p->shift == 0)
  27.                          *      ask_linuz_stop_while_loop???
  28.                          */
  29.                 } while ((nr >> p->shift) >= CARDMAP_WIDTH);
  30.                 *pmap = p;
  31.         }
  32.         while (p->shift > 0) {
  33.                 i = (nr >> p->shift) & CARDMAP_MASK;
  34.                 if (p->ptr[i] == NULL) {
  35.                         struct cardmap *np = kmalloc(sizeof(*np), GFP_KERNEL);
  36.                         memset(np, 0, sizeof(*np));
  37.                         np->shift = p->shift - CARDMAP_ORDER;
  38.                         np->parent = p;
  39.                         p->ptr[i] = np;
  40.                 }
  41.                 if (ptr == NULL)
  42.                         clear_bit(i, &p->inuse);
  43.                 p = p->ptr[i];
  44.         }
  45.         i = nr & CARDMAP_MASK;
  46.         p->ptr[i] = ptr;
  47.         if (ptr != NULL)
  48.                 set_bit(i, &p->inuse);
  49.         else
  50.                 clear_bit(i, &p->inuse);
  51. }
复制代码

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

论坛徽章:
0
3 [报告]
发表于 2007-08-18 13:56 |只看该作者

  1. linux-2.6.22.1/kernel/time/timer_list.c

  2. static void print_active_timers(struct seq_file *m,
  3.         struct hrtimer_clock_base *base, u64 now)
  4. {
  5.         struct hrtimer *timer, tmp;
  6.         unsigned long next = 0, i;
  7.         struct rb_node *curr;
  8.         unsigned long flags;

  9. next_one:
  10.         i = 0;
  11.         spin_lock_irqsave(&base->cpu_base->lock, flags);

  12.         curr = base->first;
  13.         /*
  14.          * Crude but we have to do this O(N*N) thing, because
  15.          * we have to unlock the base when printing:
  16.          */
  17.         while (curr && i < next) {
  18.                 curr = rb_next(curr);
  19.                 i++;
  20.         }

  21.         if (curr) {
  22.                 timer = rb_entry(curr, struct hrtimer, node);
  23.                 tmp = *timer;
  24.                 spin_unlock_irqrestore(&base->cpu_base->lock, flags);
  25.                 /*
  26.                  * yeah Ingo Molnar, ifuleu,
  27.                  * but print shows not timer but tmp,
  28.                  * how can i see %p timer??
  29.                  */
  30.                 print_timer(m, &tmp, i, now);
  31.                 next++;
  32.                 goto next_one;
  33.         }
  34.         spin_unlock_irqrestore(&base->cpu_base->lock, flags);
  35. }
复制代码

[ 本帖最后由 sisi8408 于 2007-8-18 13:58 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2007-08-18 14:04 |只看该作者

  1. /*
  2. * linux-2.6.22.1/net/ipv4/ip_fragment.c
  3. *
  4. * Oops, a fragment queue timed out.
  5. * Kill it and send an ICMP reply.
  6. *
  7. * sisi 2007-8-13 02:27pm
  8. */
  9. static void ip_expire(unsigned long arg)
  10. {
  11.         struct ipq *qp = (struct ipq *) arg;

  12.         spin_lock(&qp->lock);

  13.         if (qp->last_in & COMPLETE)
  14.                 goto out;

  15.         ipq_kill(qp);

  16.         IP_INC_STATS_BH(IPSTATS_MIB_REASMTIMEOUT);
  17.         IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);

  18.         if ((qp->last_in&FIRST_IN) && qp->fragments != NULL) {
  19.                 struct sk_buff *head = qp->fragments;
  20.                 /*
  21.                  * Send an ICMP "Fragment Reassembly Timeout" message.
  22.                  *
  23.                  * 由这里引发
  24.                  */
  25.                 if ((head->dev = dev_get_by_index(qp->iif)) != NULL) {
  26.                         icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
  27.                         dev_put(head->dev);
  28.                 }
  29.         }
  30. out:
  31.         spin_unlock(&qp->lock);
  32.         ipq_put(qp, NULL);
  33. }

  34. void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
  35. {
  36.         struct iphdr *iph;
  37.         int room;
  38.         struct icmp_bxm icmp_param;
  39.         struct rtable *rt = (struct rtable *)skb_in->dst;
  40.         struct ipcm_cookie ipc;
  41.         __be32 saddr;
  42.         u8  tos;

  43.         if (!rt) {
  44.                 /* 在这里兑现,
  45.                  *
  46.                  * defarg, if issued by netfilter,
  47.                  * at PRE_ROUTING in normal cases,
  48.                  * 谁给skb_in->dst赋值?
  49.                  *
  50.                  * 本应发送Fragment Reassembly Timeout message,
  51.                  * 确没有发。
  52.                  */
  53.                 goto out;
  54.         }
  55. }
复制代码


  1. shot bug by daemeon

  2. --- linux-2.6.22/net/ipv4/icmp.c        2007-07-09 07:32:17.000000000 +0800
  3. +++ new/net/ipv4/icmp.c        2007-08-13 17:36:21.000000000 +0800
  4. @@ -440,9 +440,6 @@ void icmp_send(struct sk_buff *skb_in, i
  5.         __be32 saddr;
  6.         u8  tos;

  7. -        if (!rt)
  8. -                goto out;
  9. -
  10.         /*
  11.          *        Find the original header. It is expected to be valid, of course.
  12.          *        Check this, icmp_send is called from the most obscure devices
  13. @@ -461,16 +458,24 @@ void icmp_send(struct sk_buff *skb_in, i
  14.                 goto out;

  15.         /*
  16. -         *        Now check at the protocol level
  17. +         *        Only reply to fragment 0. We byte re-order the constant
  18. +         *        mask for efficiency.
  19.          */
  20. -        if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
  21. +        if (iph->frag_off & htons(IP_OFFSET))
  22.                 goto out;

  23. +        if (!rt) {
  24. +                if (ip_route_input(skb_in, iph->daddr, iph->saddr,
  25. +                                        iph->tos, skb_in->dev) != 0)
  26. +                        goto out;
  27. +
  28. +                rt = (struct rtable *)skb_in->dst;
  29. +        }
  30. +
  31.         /*
  32. -         *        Only reply to fragment 0. We byte re-order the constant
  33. -         *        mask for efficiency.
  34. +         *        Now check at the protocol level
  35.          */
  36. -        if (iph->frag_off & htons(IP_OFFSET))
  37. +        if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
  38.                 goto out;

  39.         /*
复制代码


daemeon won ¥4。
版权问题,请daemeon大哥确认。


  1. refined by rtable

  2. +        if (!rt) {
  3. +                struct net_device __ndev;
  4. +
  5. +                if (skb_in->input_dev)
  6. +                    __ndev = skb_in->input_dev;
  7. +                else
  8. +                   __ndev = get_dev_by_index(skb_in->iif);
  9. +                if (!__ndev)
  10. +                   goto out;
  11. +
  12. +                if (ip_route_input(skb_in, iph->daddr, iph->saddr,
  13. +                                             iph->tos, __ndev) != 0)
  14. +                        goto out;
  15. +
  16. +                rt = (struct rtable *)skb_in->dst;
  17. +        }
复制代码

[ 本帖最后由 sisi8408 于 2007-8-18 14:37 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2007-08-18 14:06 |只看该作者

  1. /*
  2. * linux-2.6.22.1/net/xfrm/xfrm_state.c
  3. * sisi 2007-8-14 10:44am
  4. */
  5. int km_report (u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr)
  6. {
  7.         int err = -EINVAL;
  8.         int ret;
  9.         struct xfrm_mgr *km;

  10.         read_lock(&xfrm_km_lock);
  11.         list_for_each_entry(km, &xfrm_km_list, list) {
  12.                 if (km->report) {
  13.                         ret = km->report(proto, sel, addr);
  14.                         if (!ret)
  15.                                 err = ret;
  16.                 }
  17.         }
  18.         read_unlock(&xfrm_km_lock);
  19.         /*
  20.          * err report bug
  21.          */
  22.         return err;
  23. }
复制代码

论坛徽章:
0
6 [报告]
发表于 2007-08-18 14:10 |只看该作者

  1. linux-2.6.20.7 漏洞

  2. static int wanpipe_rcv(struct sk_buff *skb, struct net_device *dev,
  3.                        struct sock *sk)
  4. {
  5.         struct wan_sockaddr_ll * sll = (struct wan_sockaddr_ll *)skb->cb;
  6.         wanpipe_common_t * chan = dev->priv;
  7.         /*
  8.          * When we registered the protocol,
  9.          * we saved the socket in the data field for just this event.
  10.          */
  11.         skb->dev = dev;

  12.         sll->sll_family = AF_WANPIPE;
  13.         sll->sll_hatype = dev->type;
  14.         sll->sll_protocol = skb->protocol;
  15.         sll->sll_pkttype = skb->pkt_type;
  16.         sll->sll_ifindex = dev->ifindex;
  17.       
  18.         sll->sll_halen = 0;
  19.         if (dev->hard_header_parse)
  20.                 sll->sll_halen = dev->hard_header_parse(skb, sll->sll_addr);

  21.         /*
  22.          * WAN_PACKET_DATA : Data which should be passed up the receive queue.
  23.          * WAN_PACKET_ASYC : Asynchronous data like place call, which should
  24.          *                   be passed up the listening sock.
  25.          * WAN_PACKET_ERR  : Asynchronous data like clear call or restart
  26.          *                   which should go into an error queue.
  27.          */
  28.         switch (skb->pkt_type) {
  29.                 case WAN_PACKET_DATA:
  30.                         if (sock_queue_rcv_skb(sk, skb) < 0) {
  31.                                 return -ENOMEM;
  32.                         }
  33.                         break;
  34.                
  35.                 case WAN_PACKET_CMD:
  36.                         sk->sk_state = chan->state;
  37.                         /* Bug fix: update Mar6.
  38.                          * Do not set the sock lcn number here, since
  39.                           * cmd is not guaranteed to be executed on the
  40.                          * board, thus Lcn could be wrong
  41.                          */
  42.                         sk->sk_data_ready(sk, skb->len);
  43.                         kfree_skb(skb);
  44.                         break;
  45.                
  46.                 case WAN_PACKET_ERR:
  47.                         sk->sk_state = chan->state;
  48.                         if (sock_queue_err_skb(sk,skb)<0){
  49.                                 return -ENOMEM;
  50.                         }
  51.                         break;
  52.                
  53.                 default:
  54.                         //at this case 就在这儿,呵呵
  55.                         printk(KERN_INFO "wansock: BH Illegal Packet Type Dropping\n");
  56.                         kfree_skb(skb);
  57.                         break;
  58.         }
  59.         return 0;
  60. }
复制代码

论坛徽章:
0
7 [报告]
发表于 2007-08-18 14:53 |只看该作者

回复 #1 sisi8408 的帖子

>>请daemeon大哥确认
狂汗

print_active_timers不会是指Andrew的注释里的说问题吧?

论坛徽章:
0
8 [报告]
发表于 2007-08-18 14:58 |只看该作者

回复 #7 daemeon 的帖子

请细说Andrew的注释里的问题,

这里请注意spin lock 的用法,¥1 就为这个。

化¥1 理解I Molnar的苦心,if(timer_pending(t))让俺受苦。
¥5 for WAN 还等你出手,呵呵。

[ 本帖最后由 sisi8408 于 2007-8-18 15:13 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2007-08-18 16:06 |只看该作者

回复 #8 sisi8408 的帖子

spin_lock用法没有问题.

论坛徽章:
0
10 [报告]
发表于 2007-08-18 16:22 |只看该作者

回复 #9 daemeon 的帖子

的确没问题,他干吗用个tmp,还要memcpy?
俺查看timer的地址,对吗?

[ 本帖最后由 sisi8408 于 2007-8-18 16:33 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP