none
Bug Check 0x19: BAD_POOL_HEADER RRS feed

  • 问题

  • 系统蓝屏了,操作系统版本:windows server 2003 SP2 x64

    以下是minidump的概要信息,主机由于磁盘性能很挫,而物理内存又十分充裕,所以设置了虚拟内存限制:1024M-2048M,物理内存为16G

    DUMP文件:http://pan.baidu.com/s/1eQ5Xmlc

    13: kd> dt nt!_pool_header fffffade6cf5d750
       +0x000 PreviousSize     : 0y01110010 (0x72)
       +0x000 PoolIndex        : 0y00000000 (0)
       +0x000 BlockSize        : 0y01111001 (0x79)
       +0x000 PoolType         : 0y00000000 (0)
       +0x000 Ulong1           : 0x790072
       +0x004 PoolTag          : 0x4f0020
       +0x008 ProcessBilled    : 0x00200072`00650076 _EPROCESS
       +0x008 AllocatorBackTraceIndex : 0x76
       +0x00a PoolTagHash      : 0x65
    13: kd> !pool fffffade6cf5d6e0
    Pool page fffffade6cf5d6e0 region is Unknown
     fffffade6cf5d000 size:  640 previous size:    0  (Allocated)  TCPB
     fffffade6cf5d640 size:   30 previous size:  640  (Allocated)  ReEv
     fffffade6cf5d670 size:   70 previous size:   30  (Allocated)  CMpa Process: fffffade6d9a88b0
    *fffffade6cf5d6e0 size:   70 previous size:   70  (Allocated) *IoEr
      Pooltag IoEr : Io error log packets, Binary : nt!io

    fffffade6cf5d750 doesn't look like a valid small pool allocation, checking to see
    if the entire page is actually part of a large page allocation...

    GetUlongFromAddress: unable to read from fffff800011cf218
    Unable to get pool big page table. Check for valid symbols.
    fffffade6cf5d750 is not valid pool. Checking for freed (or corrupt) pool
    Bad previous allocation size @fffffade6cf5d750, last size was 7

    很明显,a pool block header size is corrupt.

    13: kd> dt nt!_pool_header fffffade6cf5d6e0
       +0x000 PreviousSize     : 0y00000111 (0x7)
       +0x000 PoolIndex        : 0y00000000 (0)
       +0x000 BlockSize        : 0y00000111 (0x7)
       +0x000 PoolType         : 0y00000101 (0x5)
       +0x000 Ulong1           : 0x5070007
       +0x004 PoolTag          : 0x72456f49
       +0x008 ProcessBilled    : 0xfffffade`6ec79b00 _EPROCESS
       +0x008 AllocatorBackTraceIndex : 0x9b00
       +0x00a PoolTagHash      : 0x6ec7
    13: kd> !pool fffffade6cf5d6e0
    Pool page fffffade6cf5d6e0 region is Unknown
     fffffade6cf5d000 size:  640 previous size:    0  (Allocated)  TCPB
     fffffade6cf5d640 size:   30 previous size:  640  (Allocated)  ReEv
     fffffade6cf5d670 size:   70 previous size:   30  (Allocated)  CMpa Process: fffffade6d9a88b0
    *fffffade6cf5d6e0 size:   70 previous size:   70  (Allocated) *IoEr
    Pooltag IoEr : Io error log packets, Binary : nt!io
    fffffade6cf5d750 doesn't look like a valid small pool allocation, checking to see
    if the entire page is actually part of a large page allocation...
    GetUlongFromAddress: unable to read from fffff800011cf218
    Unable to get pool big page table. Check for valid symbols.
    fffffade6cf5d750 is not valid pool. Checking for freed (or corrupt) pool
    Bad previous allocation size @fffffade6cf5d750, last size was 7
    在地址 0xfffffade6cf5d750 的地方_pool_header 被破坏,看看上一 pool_entry 0xfffffade6cf5d6e0 的内容:

    13: kd> db fffffade6cf5d6e0 L80
    fffffade`6cf5d6e0  07 00 07 05 49 6f 45 72-00 9b c7 6e de fa ff ff  ....IoEr...n....
    fffffade`6cf5d6f0  0b 00 60 00 00 00 00 00-f0 d6 1d 01 00 f8 ff ff  ..`.............
    fffffade`6cf5d700  f0 d6 1d 01 00 f8 ff ff-40 50 15 6f de fa ff ff  ........@P.o....
    fffffade`6cf5d710  80 52 2e 70 de fa ff ff-a2 0c e8 ec a3 e6 cf 01  .R.p............
    fffffade`6cf5d720  00 00 00 00 01 00 28 00-00 00 00 00 07 00 05 80  ......(.........
    fffffade`6cf5d730  e2 03 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
    fffffade`6cf5d740  00 00 00 00 00 00 00 00-4d 00 65 00 6d 00 6f 00  ........M.e.m.o.
    fffffade`6cf5d750  72 00 79 00 20 00 4f 00-76 00 65 00 72 00 20 00  r.y. .O.v.e.r. .
    本应该是下一块 _pool_header 的内存区域 0xfffffade`6cf5d750 被覆写了,内容还是有意义的,
    看的不明显,在多一点:
    13: kd> db fffffade6cf5d6e0 L112
    fffffade`6cf5d6e0  07 00 07 05 49 6f 45 72-00 9b c7 6e de fa ff ff  ....IoEr...n....
    fffffade`6cf5d6f0  0b 00 60 00 00 00 00 00-f0 d6 1d 01 00 f8 ff ff  ..`.............
    fffffade`6cf5d700  f0 d6 1d 01 00 f8 ff ff-40 50 15 6f de fa ff ff  ........@P.o....
    fffffade`6cf5d710  80 52 2e 70 de fa ff ff-a2 0c e8 ec a3 e6 cf 01  .R.p............
    fffffade`6cf5d720  00 00 00 00 01 00 28 00-00 00 00 00 07 00 05 80  ......(.........
    fffffade`6cf5d730  e2 03 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
    fffffade`6cf5d740  00 00 00 00 00 00 00 00-4d 00 65 00 6d 00 6f 00  ........M.e.m.o.
    fffffade`6cf5d750  72 00 79 00 20 00 4f 00-76 00 65 00 72 00 20 00  r.y. .O.v.e.r. .
    fffffade`6cf5d760  4c 00 69 00 6d 00 69 00-74 00 2c 00 20 00 4c 00  L.i.m.i.t.,. .L.
    fffffade`6cf5d770  69 00 6d 00 69 00 74 00-20 00 69 00 73 00 20 00  i.m.i.t. .i.s. .
    fffffade`6cf5d780  3a 00 20 00 28 00 31 00-30 00 37 00 33 00 37 00  :. .(.1.0.7.3.7.
    fffffade`6cf5d790  34 00 31 00 38 00 32 00-34 00 29 00 2c 00 20 00  4.1.8.2.4.).,. .
    fffffade`6cf5d7a0  43 00 75 00 72 00 72 00-65 00 6e 00 74 00 20 00  C.u.r.r.e.n.t. .
    fffffade`6cf5d7b0  55 00 73 00 61 00 67 00-65 00 3a 00 20 00 28 00  U.s.a.g.e.:. .(.
    fffffade`6cf5d7c0  38 00 35 00 38 00 39 00-39 00 36 00 32 00 32 00  8.5.8.9.9.6.2.2.
    fffffade`6cf5d7d0  34 00 29 00 00 00 00 00-00 00 00 00 00 00 00 00  4.).............
    fffffade`6cf5d7e0  40 2d 4a 70 de fa ff ff-00 10 00 40 63 96 2a df  @-Jp.......@c.*.
    fffffade`6cf5d7f0  60 0f
    额,貌似是写日志的时内存越界,出现覆写。
    查找驱动源码:
        len1 = ErrorString ? (wcslen(ErrorString) + 1)*sizeof(WCHAR) : 0;
        len = len1 + FIELD_OFFSET(IO_ERROR_LOG_PACKETDumpData);
        len = max(lensizeof(IO_ERROR_LOG_PACKET));
        
        if ( len < ERROR_LOG_MAXIMUM_SIZE ) {
            pIoErrorLogPacket = (PIO_ERROR_LOG_PACKETIoAllocateErrorLogEntry((PVOID)pDeviceObjectlen);
            if ( NULL != pIoErrorLogPacket ) {
                RtlZeroMemory(pIoErrorLogPacketsizeof(IO_ERROR_LOG_PACKET));
                pIoErrorLogPacket->RetryCount = 0;    //tried once
                pIoErrorLogPacket->ErrorCode = ErrorCode;
                pIoErrorLogPacket->UniqueErrorValue = UniqueErrorValue;
                pIoErrorLogPacket->FinalStatus = FinalStatus;
                pIoErrorLogPacket->DumpDataSize = 0;
                if ( len1 > 0 ) {
                    pIoErrorLogPacket->NumberOfStrings = 1;
                    pIoErrorLogPacket->StringOffset = FIELD_OFFSET(IO_ERROR_LOG_PACKETDumpData);
                    RtlCopyMemory((PWSTR)((PCHAR)pIoErrorLogPacket + pIoErrorLogPacket->StringOffset), ErrorStringlen1);
                }
                //queues a given error log packet to the system error logging thread
                IoWriteErrorLogEntry(pIoErrorLogPacket);
            }
        } 
    貌似没什么问题。Waitting...
     PVOID IoAllocateErrorLogEntry(
      _In_  PVOID IoObject,
    
      _In_  UCHAR EntrySize
    
    );
    EntrySize [in]

    Specifies the size, in bytes, of the error log entry to be allocated. This value cannot exceed ERROR_LOG_MAXIMUM_SIZE.

    Warning   EntrySize is a UCHAR value. If you specify a larger value, the compiler will silently truncate that value to a (wrong) UCHAR.

    应该就是这里的问题了,增加判断条件:

        // thoroughly check the value of len to prevent buffer underflows/overflows
        if ((len < ERROR_LOG_MAXIMUM_SIZE) && (len >= len1) && (len > 0) && (len <= 255)) {
            问题解决。


    • 已编辑 bendsha 2014年10月17日 8:33
    2014年10月13日 14:14

答案

全部回复