Linux kernel是美国Linux基金会发布的操作系统Linux所使用的内核。NFSv4 implementation是其中的一个分布式文件系统协议。 Linux Kernel实现上存在漏洞,本地攻击者可能利用此漏洞提升权限。 Linux Kernel的drivers/isdn/i4l/isdn_net.c文件中的isdn_net_setcfg()函数在处理发送给ISDN伪设备(/dev/isdnctrl)的IOCTL配置请求时存在缓冲区溢出漏洞: 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 /* Set configurable parameters of a network-interface */ 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 /* If binding is exclusive, try to grab the channel */ 2781...
Linux kernel是美国Linux基金会发布的操作系统Linux所使用的内核。NFSv4 implementation是其中的一个分布式文件系统协议。 Linux Kernel实现上存在漏洞,本地攻击者可能利用此漏洞提升权限。 Linux Kernel的drivers/isdn/i4l/isdn_net.c文件中的isdn_net_setcfg()函数在处理发送给ISDN伪设备(/dev/isdnctrl)的IOCTL配置请求时存在缓冲区溢出漏洞: 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 /* Set configurable parameters of a network-interface */ 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 /* If binding is exclusive, try to grab the channel */ 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 /* Grab failed, because desired channel is in use */ 2786 lp->exclusive = -1; 2787 spin_unlock_irqrestore(&dev->lock, flags); 2788 return -EBUSY; 2789 } 2790 /* All went ok, so update isdninfo */ 2791 dev->usage[i] = ISDN_USAGE_EXCLUSIVE; 2792 isdn_info_update(); 2793 spin_unlock_irqrestore(&dev->lock, flags); 2794 lp->exclusive = i; 2795 } else { 2796 /* Non-exclusive binding or unbind. */ 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 } 在2805行调用了strcpy(),lp->msn参数大小为32,cfg->eaz大小为256。由于*cfg的数据是用户可控的,因此cfg->eaz也是用户可控的,这样就可以通过cfg->eaz字符串覆盖目标字符串lp->msn。如果cfg->eaz字符串的长度大于32的话,就可以触发缓冲区溢出。