isdn_ioctl (drivers/isdn/i4l/isdn_common.c):
1270 isdn_ioctl(strUCt inode *inode, struct file *file, uint cmd, ulong arg)
...
...
1410 case IIOCNETSCF:
1411
1412 if (arg) {
1413 if (copy_from_user(&cfg, argp, sizeof(cfg))) *** <- cfg is user-controlled
1414 return -EFAULT;
1415 return isdn_net_setcfg(&cfg); *** <-call isdn_net_setcfg()
1416 } else
1417 return -EINVAL;
...
在1413行,cfg是从用户空间读取的,因此受用户控制。
在1415行调用了isdn_net_setcfg()函数,&cfg作为参数传送给了isdn_net_setcfg()。
isdn_net_setcfg (drivers/isdn/i41/isdn_net.c):
2664 isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
2665 {
...
2777 if (cfg->exclusive > 0) {
2778 unsigned long flags;
2779
2780
2781 spin_lock_irqsave(&dev->lock, flags);
2782 if ((i = isdn_get_free_channel(ISDN_USAGE_NET,
2783 lp->l2_proto, lp->l3_proto, drvidx,
2784 chidx, lp->MSN)) < 0) {
2785
2786 lp->exclusive = -1;
2787 spin_unlock_irqrestore(&dev->lock, flags);
2788 return -EBUSY;
2789 }
2790
2791 dev->usage = ISDN_USAGE_EXCLUSIVE;
2792 isdn_info_update();
2793 spin_unlock_irqrestore(&dev->lock, flags);
2794 lp->exclusive = i;
2795 } else {
2796
2797 lp->exclusive = -1;
2798 if ((lp->pre_device != -1) && (cfg->exclusive == -1)) {
2799 isdn_unexclusive_channel(lp->pre_device, lp->pre_channel);
2800 isdn_free_channel(lp->pre_device, lp->pre_channel, ISDN_USAGE_NET);
2801 drvidx = -1;
2802 chidx = -1;
2803 }
2804 }
2805 strcpy(lp->msn, cfg->eaz); *** <- Possible overrun of lp->msn by cfg-eaz
2806 lp->pre_device = drvidx;
2807 lp->pre_channel = chidx;
2808 lp->onhtime = cfg->onhtime;
2809 lp->charge = cfg->charge;
...
2884 return -ENODEV;
2885 } |