首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
FreeBSD 10 qlxge/qlxgbe Driver IOCTL Multiple Kernel Memory Leak
来源:http://www.x90c.org 作者:x90c 发布时间:2013-11-18  
XADV-2013006
FreeBSD <= 10 kernel qlxge/qlxgbe Driver IOCTL Multiple Kernel Memory Leak Bugs
  
  
1. Overview
  
The qlxge Driver is Qlogic 10Gb Ethernet Driver for Qlogic 8100
Series CNA Adapter [1]. The qlxgbe for the QLogic 8300 series
of the same ethernet driver.
  
The qlxge/qlxgbe Driver in freebsd <= 10 has vulnerabilities to leak
arbitrary kernel memory to the userspace. It's occured at qls_eioctl()
/ ql_eioctl() kernel function and because no sanity check.
  
* Vulnerable Source Code:
  
* Credit:
  - x90c <geinblues@gmail.com>
    (site: http://www.x90c.org)
  
* References:
  
  
2. Details
  
2.1 The vulerability for the qlxge driver
  
[/dev/qlxge/qls_ioctl.c?v=FREEBSD10#L80]
----
...
   40 #include "qls_ioctl.h"
   41 #include "qls_dump.h"
   42 extern qls_mpi_coredump_t ql_mpi_coredump; // XXX The leak kmem!
   43 
   44 static int qls_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
   45                 struct thread *td);
   46 
   47 static struct cdevsw qla_cdevsw = {
   48         .d_version = D_VERSION,
   49         .d_ioctl = qls_eioctl,  // XXX qls_eioctl.
   50         .d_name = "qlxge",
   51 };
   52 
...
  
   80 static int
   81 qls_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
   82         struct thread *td)
   83 {
   84         qla_host_t *ha;
   85         int rval = 0;
   86         device_t pci_dev;
   87 
   88         qls_mpi_dump_t *mpi_dump;
   89 
   90         if ((ha = (qla_host_t *)dev->si_drv1) == NULL)
   91                 return ENXIO;
   92 
   93         pci_dev= ha->pci_dev;
   94 
   95         switch(cmd) {
   96 
   97         case QLA_MPI_DUMP:
   98                 mpi_dump = (qls_mpi_dump_t *)data; // mpi_dump = data(arg).
   99 
  100                 if (mpi_dump->size == 0) {
  101                         mpi_dump->size = sizeof (qls_mpi_coredump_t);
  
  102                 } else { // XXX mpi_dump->size > 0?
  
  103                         if (mpi_dump->size < sizeof (qls_mpi_coredump_t))
  104                                 rval = EINVAL;
  
  105                         else { // XXX mpi_dump_size > qls_mpi_coredump_t struct size?
  
  106                                 qls_mpi_core_dump(ha);
  
              /* XXX copy ql_mpi_coredump(static kmem) to userspace with 
               *     mpi_dump->size(arg). Kernel memory leak occured!
                                       */
  107                                 rval = copyout( &ql_mpi_coredump,
  108                                                 mpi_dump->dbuf,
  109                                                 mpi_dump->size);
----
  
  
2.2 The vulerability for the qlxgbe driver
  
[/dev/qlxgbe/ql_ioctl.c?v=FREEBSD10#L79]
----
46 static struct cdevsw qla_cdevsw = {
   47         .d_version = D_VERSION,
   48         .d_ioctl = ql_eioctl, /* XXX ql_eioctl! */
   49         .d_name = "qlcnic",
   50 };
  
...
  
  79 static int
   80 ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
   81         struct thread *td)
   82 {
   83         qla_host_t *ha;
  
...
  
   90         qla_rd_fw_dump_t *fw_dump;
   91         union {
   92                 qla_reg_val_t *rv;
   93                 qla_rd_flash_t *rdf;
   94                 qla_wr_flash_t *wrf;
   95                 qla_erase_flash_t *erf;
   96                 qla_offchip_mem_val_t *mem;
   97         } u;
   98 
   99 
  100         if ((ha = (qla_host_t *)dev->si_drv1) == NULL) /* XXX ha = dev->si_drv1. */
  101                 return ENXIO;
  102 
...
  105         switch(cmd) {
  106 
...
  218         case QLA_RD_FW_DUMP: /* XXX QLA_RD_FW_DUMP ioctl cmd */
  219 
  220                 if (ha->hw.mdump_init == 0) {
  221                         rval = EINVAL;
  222                         break;
  223                 }
  224                 
  225                 fw_dump = (qla_rd_fw_dump_t *)data; // XXX fw_dump = data(arg)
  
          /* XXX no sanity check and copy arbitrary ha... (the kmem)
                       *     kmem to userspace (kmem leak occured!)
                       */
  226                 if ((rval = copyout(ha->hw.dma_buf.minidump.dma_b,
  227                         fw_dump->md_template, fw_dump->template_size)))
  228                         rval = ENXIO;
  229                 break;
----
  
  
3. Patch code
  
[freebsd_qlxge_kmem_leak.patch]
----
+   if(mpi_dump->size > sizeof(qls_mpi_coredump_t))
+           return EINVAL;
  
    rval = copyout( &ql_mpi_coredump,
                    mpi_dump->dbuf,
                    mpi_dump->size);
----
  
[freebsd_qlxgbe_kmem_leak.patch]
----
+   if(fw_dump->template_size > sizeof(qla_host_t))
+       return EINVAL;
    if ((rval = copyout(ha->hw.dma_buf.minidump.dma_b,
        fw_dump->md_template, fw_dump->template_size)))
----
  
  
There's the vendor patch code.
  
[qlxg.diff]
----
Index: sys/dev/qlxgbe/ql_ioctl.c
===================================================================
--- sys/dev/qlxgbe/ql_ioctl.c  (revision 258154)
+++ sys/dev/qlxgbe/ql_ioctl.c  (working copy)
@@ -223,6 +223,10 @@ ql_eioctl(struct cdev *dev, u_long cmd, caddr_t da
     }
       
     fw_dump = (qla_rd_fw_dump_t *)data;
+    if (fw_dump->template_size < ha->hw.dma_buf.minidump.size)
+      return (EINVAL);
+    else
+      fw_dump->template_size = ha->hw.dma_buf.minidump.size;
     if ((rval = copyout(ha->hw.dma_buf.minidump.dma_b,
       fw_dump->md_template, fw_dump->template_size)))
       rval = ENXIO;
Index: sys/dev/qlxge/qls_ioctl.c
===================================================================
--- sys/dev/qlxge/qls_ioctl.c  (revision 258154)
+++ sys/dev/qlxge/qls_ioctl.c  (working copy)
@@ -103,10 +103,13 @@ qls_eioctl(struct cdev *dev, u_long cmd, caddr_t d
       if (mpi_dump->size < sizeof (qls_mpi_coredump_t))
         rval = EINVAL;
       else {
-        qls_mpi_core_dump(ha);
-        rval = copyout( &ql_mpi_coredump,
-            mpi_dump->dbuf,
-            mpi_dump->size);
+        mpi_dump->size = sizeof(qls_mpi_coredump_t);
+        if (qls_mpi_core_dump(ha) == 0) {
+          rval = copyout( &ql_mpi_coredump,
+              mpi_dump->dbuf,
+              mpi_dump->size);
+        } else
+          rval = ENXIO;
   
         if (rval) {
           device_printf(ha->pci_dev,
----
  
  
4. Vendor Status
  
- 2013/11/12 I discovered two kernel memory leaks.
- 2013/11/14 Report to the vendor of secteam@freebsd.org.
- 2013/11/15 The vendor response with the coordination 
             with the vendor patch code. (will be freebsd's advisory)
- 2013/11/16 Cve-id for each bug request to the cve-assign@mitre.org.
- 2013/11/16 The original advisory released on full-disclosure, bugtraq.
  
  
EOF

 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·Supermicro Onboard IPMI close_
·FreeBSD 10 nand Driver IOCTL K
·Windows SYSTEM Escalation Via
·Avira Secure Backup 1.0.0.1 Bu
·Dahua DVR Authentication Bypas
·Linux Kernel bt8xx Video Drive
·Watermark Master v2.2.23 .wsty
·DeepOfix 3.3 SMTP Authenticati
·Plogue Sforzando 1.665 Buffer
·DesktopCentral AgentLogUpload
·ALLPlayer 5.6.2 (.m3u) - Local
·Light Alloy 4.7.3 (.m3u) - SEH
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved