⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fortify.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                     FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);
    st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + size,
                     FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);

#ifdef FORTIFY_FILL_ON_ALLOCATE
    /*
     * Fill the actual user memory
     */
    st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
                        FORTIFY_FILL_ON_ALLOCATE_VALUE, size);
#endif

    /*
     * End Critical Region
     */
    FORTIFY_UNLOCK();


    /*
     * update the statistics
     */
    st_TotalAllocation += size;
    st_Allocations++;
    st_CurBlocks++;
    st_CurAllocation += size;
    if (st_CurBlocks > st_MaxBlocks)
        st_MaxBlocks = st_CurBlocks;
    if (st_CurAllocation > st_MaxAllocation)
        st_MaxAllocation = st_CurAllocation;

    /*
     * We return the address of the user's memory, not the start of the block,
     * which points to our magic cookies
     */
    return (ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE);
}



/*
 * Fortify_Deallocate() - Free a block of memory allocated with Fortify_Allocate()
 */
void FORTIFY_STORAGE
Fortify_Deallocate(void *uptr, BYTE deallocator, const char *file, DWORD line)
{
    BYTE *ptr = (BYTE *)uptr
                        - FORTIFY_HEADER_SIZE
                        - FORTIFY_ALIGNED_BEFORE_SIZE;
    struct Header *h   = (struct Header *)ptr;

#ifdef FORTIFY_CHECK_ALL_MEMORY_ON_DEALLOCATE
    Fortify_CheckAllMemory(file, line);
#endif

    /*
     * If Fortify has been disabled, then it's easy
     * (well, almost)
     */
    if (st_Disabled)
    {
        /* there is a possibility that this memory
         * block was allocated when Fortify was
         * enabled, so we must check the Allocated
         * list before we free it.
         */
        if (!st_IsOnAllocatedList(h))
        {
            free(uptr);    
            return;
        }    
        else
        {
            /* the block was allocated by Fortify, so we 
             * gotta free it differently.
             */
            /*
             * Begin critical region
             */
            FORTIFY_LOCK();
        
            /*
             * Remove the block from the list
             */
            if (h->Prev)
                h->Prev->Next = h->Next;
            else
                st_AllocatedHead = h->Next;
        
            if (h->Next)
                h->Next->Prev = h->Prev;
        
            /*
             * End Critical Region
             */
            FORTIFY_UNLOCK();

            /*
             * actually free the memory
             */
            free(ptr);
            return;
        }
    }


#ifdef FORTIFY_PARANOID_DEALLOCATE
    if (!st_IsOnAllocatedList(h))
    {
#ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
        if (st_IsOnDeallocatedList(h))
        {
            sprintf(st_Buffer, "\nFortify: \"%s\" twice of %s detected at %s.%lu\n",
                                st_DeallocatorName[deallocator],
                                st_MemoryBlockString(h), file, line);
            st_Output(st_Buffer);

            sprintf(st_Buffer, "         Memory block was deallocated by \"%s\" at %s.%lu\n",
                                st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
            st_Output(st_Buffer);
            st_OutputDeleteTrace();
            return;
        }
#endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */

        sprintf (st_Buffer, "\nFortify: Possible \"%s\" twice of (%08lX) was detected at %s.%lu\n",
                 st_DeallocatorName[deallocator], (DWORD)uptr, file, line);

        st_Output(st_Buffer);
        st_OutputDeleteTrace();
        return;
    }
#endif /* FORTIFY_PARANOID_DELETE */

    /*
     * Make sure the block is okay before we free it.
     * If it's not okay, don't free it - it might not
     * be a real memory block. Or worse still, someone
     * might still be writing to it
     */
    if (!st_CheckBlock(h, file, line))
    {
        st_OutputDeleteTrace();
        return;
    }

#ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
    /*
     * Make sure the block hasn't been freed already
     * (we can get to here if FORTIFY_PARANOID_DELETE
     * is off, but FORTIFY_TRACK_DEALLOCATED_MEMORY
     * is on).
     */
    if (h->Deallocator != Fortify_Deallocator_nobody)
    {
        sprintf(st_Buffer, "\nFortify: \"%s\" twice of %s detected at %s.%lu\n",
                              st_DeallocatorName[deallocator],
                            st_MemoryBlockString(h), file, line);
        st_Output(st_Buffer);

        sprintf(st_Buffer, "         Memory block was deallocated by \"%s\" at %s.%lu\n",
                            st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
        st_Output(st_Buffer);
        st_OutputDeleteTrace();
        return;
    }
#endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */

    /*
     * Make sure the block is being freed with a valid
     * deallocator. If not, complain. (but free it anyway)
     */
    if ((st_ValidDeallocator[h->Allocator] & (1 << deallocator)) == 0)
    {
        sprintf(st_Buffer, "\nFortify: Incorrect deallocator \"%s\" detected at %s.%lu\n",
                              st_DeallocatorName[deallocator], file, line);
        st_Output(st_Buffer);
        sprintf(st_Buffer,   "         %s was allocated with \"%s\"\n",
                              st_MemoryBlockString(h), st_AllocatorName[h->Allocator]);
        st_Output(st_Buffer);
        st_OutputDeleteTrace();
    }

    /*
     * Begin critical region
     */
    FORTIFY_LOCK();

    /*
     * Remove the block from the list
     */
    if (h->Prev)
    {
        if (!st_CheckBlock(h->Prev, file, line))
        {
            FORTIFY_UNLOCK();
            st_OutputDeleteTrace();
            return;
        }

        h->Prev->Next = h->Next;
        st_MakeHeaderValid(h->Prev);
    }
    else
        st_AllocatedHead = h->Next;

    if (h->Next)
    {
        if (!st_CheckBlock(h->Next, file, line))
        {
            FORTIFY_UNLOCK();
            st_OutputDeleteTrace();
            return;
        }

        h->Next->Prev = h->Prev;
        st_MakeHeaderValid(h->Next);
    }

    /*
     * End Critical Region
     */
    FORTIFY_UNLOCK();

    /*
     * update the statistics
     */
    st_Frees++;
    st_CurBlocks--;
    st_CurAllocation -= h->Size;


#ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
    if (st_Scope > 0)
    {
        /*
         * Don't _actually_ free the memory block, just yet.
         * Place it onto the deallocated list, instead, so
         * we can check later to see if it's been written to.
         */
    #ifdef FORTIFY_FILL_ON_DEALLOCATE
        /*
         * Nuke out all user memory that is about to be freed
         */
        st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,
                                    FORTIFY_FILL_ON_DEALLOCATE_VALUE,
                                  h->Size);
    #endif /* FORTIFY_FILL_ON_DEALLOCATE */

        /*
         * Begin critical region
         */
        FORTIFY_LOCK();

        /*
         * Place the block on the deallocated list
         */
        if (st_DeallocatedHead)
        {
            st_DeallocatedHead->Prev = (struct Header *)ptr;
            st_MakeHeaderValid(st_DeallocatedHead);
        }

        h = (struct Header *)ptr;
        h->FreedFile   = file;
        h->FreedLine   = line;
        h->Deallocator = deallocator;
        h->Next        = st_DeallocatedHead;
        h->Prev        = 0;
        st_MakeHeaderValid(h);
        st_DeallocatedHead = h;

        if (!st_DeallocatedTail)
        {
            st_DeallocatedTail = h;
        }

        st_TotalDeallocated += h->Size;

    #ifdef FORTIFY_DEALLOCATED_MEMORY_LIMIT
        /*
         * If we've got too much on the deallocated list; free some
         */
        if (st_TotalDeallocated > FORTIFY_DEALLOCATED_MEMORY_LIMIT)
        {
             st_PurgeDeallocatedBlocks(st_TotalDeallocated - FORTIFY_DEALLOCATED_MEMORY_LIMIT, file, line);
        }
    #endif

        /*
         * End critical region
         */
        FORTIFY_UNLOCK();
    }
    else
#endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */
    {
           /*
         * Free the User Label
         */
        if (h->Label)
        {
            free(h->Label);
        }             

#ifdef FORTIFY_FILL_ON_DEALLOCATE
        /*
         * Nuke out all memory that is about to be freed, including the header
         */
        st_SetFortification(ptr, FORTIFY_FILL_ON_DEALLOCATE_VALUE,
                              FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size + FORTIFY_AFTER_SIZE);
#endif /* FORTIFY_FILL_ON_DEALLOCATE */

        /*
         * And do the actual free
         */
        free(ptr);
    }
}


/*
 * Fortify_LabelPointer() - Labels the memory block
 * with a string provided by the user. This function
 * takes a copy of the passed in string.
 * The pointer MUST be one returned by a Fortify
 * allocation function.
 */
/*@-redef@*/
void
Fortify_LabelPointer(void *uptr, const char *label, const char *file, DWORD line)
{
    if (!st_Disabled)
    {
        BYTE *ptr = (BYTE *)uptr
                              - FORTIFY_HEADER_SIZE - FORTIFY_ALIGNED_BEFORE_SIZE;
        struct Header *h = (struct Header *)ptr;

        /* make sure the pointer is okay */
        Fortify_CheckPointer(uptr, file, line);
    
        /* free the previous label */
        if (h->Label)
        {
            free(h->Label);
        }    
    
        /* make sure the label is sensible */
        assert(label);

        /* copy it in */
        h->Label = (char*)malloc(strlen(label)+1);
        strcpy(h->Label, label);
        
        /* update the checksum */
        st_MakeHeaderValid(h);
    }
}

/*
 * Fortify_CheckPointer() - Returns true if the uptr
 * points to a valid piece of Fortify_Allocated()'d
 * memory. The memory must be on the allocated list,
 * and it's fortifications must be intact.
 * Always returns TRUE if Fortify is disabled.
 */
int FORTIFY_STORAGE
Fortify_CheckPointer(void *uptr, const char *file, DWORD line)
{
    BYTE *ptr = (BYTE *)uptr
                              - FORTIFY_HEADER_SIZE - FORTIFY_ALIGNED_BEFORE_SIZE;
    struct Header *h = (struct Header *)ptr;
    int r;

    if (st_Disabled)
        return 1;

    FORTIFY_LOCK();

    if (!st_IsOnAllocatedList(h))
    {
        sprintf (st_Buffer, "\nFortify: Invalid pointer (%08lX) detected at %s.%lu\n",
                 (DWORD) uptr, file, line);

        st_Output(st_Buffer);
        FORTIFY_UNLOCK();
        return (0);
    }

#ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY
    if (st_IsOnDeallocatedList(h))
    {
        sprintf (st_Buffer, "\nFortify: Deallocated pointer (%08lX) detected at %s.%lu\n",
                 (DWORD) uptr, file, line);

        st_Output(st_Buffer);
        sprintf(st_Buffer, "         Memory block was deallocated by \"%s\" at %s.%lu\n",
                           st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);
        st_Output(st_Buffer);
        FORTIFY_UNLOCK();
        return (0);
    }
#endif

    r = st_CheckBlock(h, file, line);
    FORTIFY_UNLOCK();
    return r;
}

/*
 * Fortify_SetOutputFunc(Fortify_OutputFuncPtr Output) -
 * Sets the function used to output all error and
 * diagnostic messages. The output function  takes 
 * a single const BYTE * argument, and must be
 * able to handle newlines. This function returns the 
 * old output function.
 */
Fortify_OutputFuncPtr FORTIFY_STORAGE
Fortify_SetOutputFunc(Fortify_OutputFuncPtr Output)
{
    Fortify_OutputFuncPtr Old = st_Output;

    st_Output = Output;
  
    return (Old);
}

/*
 * Fortify_SetAllocateFailRate(int Percent) - 
 * Fortify_Allocate() will "fail" this Percent of 
 * the time, even if the memory is available. 
 * Useful to "stress-test" an application. 
 * Returns the old value.
 * The fail rate defaults to 0 (a good default I think).
 */
int FORTIFY_STORAGE
Fortify_SetAllocateFailRate(int Percent)
{
    int Old = st_AllocateFailRate;
  
    st_AllocateFailRate = Percent;
  
    return (Old);
}

 
/*
 * Fortify_CheckAllMemory() - Checks the fortifications
 * of all memory on the allocated list. And, if 
 * FORTIFY_DEALLOCATED_MEMORY is enabled, all the
 * known deallocated memory as well.
 * Returns the number of blocks that failed. 
 * Always returns 0 if Fortify is disabled.
 */
DWORD FORTIFY_STORAGE
Fortify_CheckAllMemory(const char *file, DWORD line)
{
    struct Header *curr = st_AllocatedHead;
    DWORD count = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -