Changeset 1009 for trunk/dll/fortify.c
- Timestamp:
 - May 10, 2008, 9:51:58 AM (17 years ago)
 - File:
 - 
      
- 1 edited
 
- 
          
  trunk/dll/fortify.c (modified) (102 diffs)
 
 
Legend:
- Unmodified
 - Added
 - Removed
 
- 
      
trunk/dll/fortify.c
r1005 r1009 27 27 */ 28 28 29 /* 29 /* 30 30 * If you use this software at all, I'd love to hear from 31 31 * you. All questions, criticisms, suggestions, praise and 32 32 * postcards are most welcome. 33 * 33 * 34 34 * email: sbullen@cybergraphic.com.au 35 * 35 * 36 36 * snail: Simon P. Bullen 37 37 * PO BOX 12138 … … 39 39 * Melbourne 3000 40 40 * Australia 41 */ 42 43 /* 06 May 08 SHL Rework scope logic to be MT capable 41 44 */ 42 45 … … 56 59 57 60 /* Prototypes and such */ 58 #define __FORTIFY_C__ 61 #define __FORTIFY_C__ // Suppress malloc replacement etc. 59 62 #include "fortify.h" 60 63 61 64 65 #if defined(__WATCOMC__) && defined(_MT) 66 #define MT_SCOPES 1 67 unsigned long Get_TID_Ordinal(void); 68 #pragma aux Get_TID_Ordinal = \ 69 "mov eax, far ptr fs:[0x14]" \ 70 modify exact [eax] \ 71 value [eax] 72 #endif 73 62 74 /* 63 75 * Round x up to the nearest multiple of n. … … 66 78 67 79 /* 68 * struct Header - this structure is used 69 * internally by Fortify to manage it's 80 * struct Header - this structure is used 81 * internally by Fortify to manage it's 70 82 * own private lists of memory. 71 83 */ … … 83 95 struct Header *Prev; /* Previous link */ 84 96 struct Header *Next; /* Next link */ 85 char *Label; /* User's Label (may be null) */97 char *Label; /* User's Label (may be null) */ 86 98 unsigned char Scope; /* Scope level of the caller */ 87 99 unsigned char Allocator; /* malloc/realloc/new/etc */ 100 # ifdef MT_SCOPES 101 unsigned short Ordinal; /* TID ordinal of caller */ 102 # endif 88 103 }; 89 104 … … 99 114 */ 100 115 #define FORTIFY_ALIGNED_BEFORE_SIZE ( \ 101 ROUND_UP(FORTIFY_HEADER_SIZE + FORTIFY_BEFORE_SIZE, FORTIFY_ALIGNMENT) \102 - FORTIFY_HEADER_SIZE)116 ROUND_UP(FORTIFY_HEADER_SIZE + FORTIFY_BEFORE_SIZE, FORTIFY_ALIGNMENT) \ 117 - FORTIFY_HEADER_SIZE) 103 118 104 119 /* … … 107 122 */ 108 123 #define FORTIFY_OVERHEAD ( FORTIFY_HEADER_SIZE \ 109 + FORTIFY_ALIGNED_BEFORE_SIZE \110 + FORTIFY_AFTER_SIZE) 124 + FORTIFY_ALIGNED_BEFORE_SIZE \ 125 + FORTIFY_AFTER_SIZE) 111 126 112 127 … … 151 166 * 152 167 */ 153 static struct Header *st_AllocatedHead = 0;154 static int st_AllocateFailRate = 0;168 static struct Header *st_AllocatedHead; 169 static int st_AllocateFailRate; 155 170 static char st_Buffer[256]; 156 171 static Fortify_OutputFuncPtr st_Output = st_DefaultOutput; 157 172 static const char *st_LastVerifiedFile = "unknown"; 158 static unsigned long st_LastVerifiedLine = 0; 173 static unsigned long st_LastVerifiedLine; 174 #ifdef MT_SCOPES 175 static unsigned volatile st_cScopes; 176 static unsigned volatile char* st_pScopes; 177 #else 159 178 static unsigned char st_Scope = 0; 179 #endif 160 180 static unsigned char st_Disabled = 0; 161 181 … … 183 203 #endif 184 204 185 205 186 206 /* allocators */ 187 207 static const char *st_AllocatorName[] = … … 231 251 int another_try; 232 252 233 /* 253 #ifdef MT_SCOPES 254 unsigned short ordinal; 255 #endif 256 257 /* 234 258 * If Fortify has been disabled, then it's easy 235 259 */ … … 237 261 { 238 262 #ifdef FORTIFY_FAIL_ON_ZERO_MALLOC 239 if(size == 0 && (allocator == Fortify_Allocator_new240 || allocator == Fortify_Allocator_array_new))263 if(size == 0 && (allocator == Fortify_Allocator_new 264 || allocator == Fortify_Allocator_array_new)) 241 265 { 242 266 /* 243 * A new of zero bytes must succeed, but a malloc of 244 * zero bytes probably won't245 */267 * A new of zero bytes must succeed, but a malloc of 268 * zero bytes probably won't 269 */ 246 270 return malloc(1); 247 271 } 248 272 #endif 249 273 250 return malloc(size);274 return malloc(size); 251 275 } 252 276 253 277 #ifdef FORTIFY_CHECK_ALL_MEMORY_ON_ALLOCATE 254 278 Fortify_CheckAllMemory(file, line); 255 #endif 279 #endif 256 280 257 281 if(st_AllocateFailRate > 0) 258 282 { 259 if(rand() % 100 < st_AllocateFailRate)260 {283 if(rand() % 100 < st_AllocateFailRate) 284 { 261 285 #ifdef FORTIFY_WARN_ON_FALSE_FAIL 262 sprintf(st_Buffer, 263 "\nFortify: A \"%s\" of %lu bytes \"false failed\" at %s.%lu\n",264 st_AllocatorName[allocator], (unsigned long)size, file, line);265 st_Output(st_Buffer);266 #endif 267 return(0);268 }269 } 270 271 /* Check to see if this allocation will 286 sprintf(st_Buffer, 287 "\nFortify: A \"%s\" of %lu bytes \"false failed\" at %s.%lu\n", 288 st_AllocatorName[allocator], (unsigned long)size, file, line); 289 st_Output(st_Buffer); 290 #endif 291 return(0); 292 } 293 } 294 295 /* Check to see if this allocation will 272 296 * push us over the artificial limit 273 297 */ … … 275 299 { 276 300 #ifdef FORTIFY_WARN_ON_FALSE_FAIL 277 sprintf(st_Buffer, 278 "\nFortify: A \"%s\" of %lu bytes \"false failed\" at %s.%lu\n",279 st_AllocatorName[allocator], (unsigned long)size, file, line);280 st_Output(st_Buffer);281 #endif 282 return(0);301 sprintf(st_Buffer, 302 "\nFortify: A \"%s\" of %lu bytes \"false failed\" at %s.%lu\n", 303 st_AllocatorName[allocator], (unsigned long)size, file, line); 304 st_Output(st_Buffer); 305 #endif 306 return(0); 283 307 } 284 308 285 309 #ifdef FORTIFY_WARN_ON_ZERO_MALLOC 286 310 if(size == 0 && (allocator == Fortify_Allocator_malloc || 287 allocator == Fortify_Allocator_calloc ||288 allocator == Fortify_Allocator_realloc ))289 { 290 sprintf(st_Buffer, 291 "\nFortify: A \"%s\" of 0 bytes attempted at %s.%lu\n",292 st_AllocatorName[allocator], file, line);293 st_Output(st_Buffer);311 allocator == Fortify_Allocator_calloc || 312 allocator == Fortify_Allocator_realloc )) 313 { 314 sprintf(st_Buffer, 315 "\nFortify: A \"%s\" of 0 bytes attempted at %s.%lu\n", 316 st_AllocatorName[allocator], file, line); 317 st_Output(st_Buffer); 294 318 } 295 319 #endif /* FORTIFY_WARN_ON_ZERO_MALLOC */ … … 297 321 #ifdef FORTIFY_FAIL_ON_ZERO_MALLOC 298 322 if(size == 0 && (allocator == Fortify_Allocator_malloc || 299 allocator == Fortify_Allocator_calloc ||300 allocator == Fortify_Allocator_realloc ))301 { 323 allocator == Fortify_Allocator_calloc || 324 allocator == Fortify_Allocator_realloc )) 325 { 302 326 #ifdef FORTIFY_WARN_ON_ALLOCATE_FAIL 303 sprintf(st_Buffer, "\nFortify: A \"%s\" of %lu bytes failed at %s.%lu\n",304 st_AllocatorName[allocator], (unsigned long)size, file, line);305 st_Output(st_Buffer);327 sprintf(st_Buffer, "\nFortify: A \"%s\" of %lu bytes failed at %s.%lu\n", 328 st_AllocatorName[allocator], (unsigned long)size, file, line); 329 st_Output(st_Buffer); 306 330 #endif /* FORTIFY_WARN_ON_ALLOCATE_FAIL */ 307 331 return 0; 308 332 } 309 #endif /* FORTIFY_FAIL_ON_ZERO_MALLOC */ 333 #endif /* FORTIFY_FAIL_ON_ZERO_MALLOC */ 310 334 311 335 #ifdef FORTIFY_WARN_ON_SIZE_T_OVERFLOW … … 316 340 */ 317 341 { 318 size_t private_size = FORTIFY_HEADER_SIZE319 + FORTIFY_ALIGNED_BEFORE_SIZE + size + FORTIFY_AFTER_SIZE;320 321 if(private_size < size)322 {323 sprintf(st_Buffer, 324 "\nFortify: A \"%s\" of %lu bytes has overflowed size_t at %s.%lu\n",325 st_AllocatorName[allocator], (unsigned long)size, file, line);326 st_Output(st_Buffer);327 return(0);328 } 329 } 330 #endif 342 size_t private_size = FORTIFY_HEADER_SIZE 343 + FORTIFY_ALIGNED_BEFORE_SIZE + size + FORTIFY_AFTER_SIZE; 344 345 if(private_size < size) 346 { 347 sprintf(st_Buffer, 348 "\nFortify: A \"%s\" of %lu bytes has overflowed size_t at %s.%lu\n", 349 st_AllocatorName[allocator], (unsigned long)size, file, line); 350 st_Output(st_Buffer); 351 return(0); 352 } 353 } 354 #endif 331 355 332 356 another_try = 1; 333 357 do 334 358 { 335 /*336 * malloc the memory, including the space 337 * for the header and fortification buffers338 */ 339 ptr = (unsigned char *)malloc( FORTIFY_HEADER_SIZE340 + FORTIFY_ALIGNED_BEFORE_SIZE 341 + size342 + FORTIFY_AFTER_SIZE );359 /* 360 * malloc the memory, including the space 361 * for the header and fortification buffers 362 */ 363 ptr = (unsigned char *)malloc( FORTIFY_HEADER_SIZE 364 + FORTIFY_ALIGNED_BEFORE_SIZE 365 + size 366 + FORTIFY_AFTER_SIZE ); 343 367 344 368 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 345 /*346 * If we're tracking deallocated memory, then347 * we can free some of it, rather than let348 * this malloc fail349 */350 if(!ptr)351 {352 another_try = st_PurgeDeallocatedBlocks(size, file, line);353 }369 /* 370 * If we're tracking deallocated memory, then 371 * we can free some of it, rather than let 372 * this malloc fail 373 */ 374 if(!ptr) 375 { 376 another_try = st_PurgeDeallocatedBlocks(size, file, line); 377 } 354 378 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 355 379 … … 360 384 { 361 385 #ifdef FORTIFY_WARN_ON_ALLOCATE_FAIL 362 sprintf(st_Buffer, "\nFortify: A \"%s\" of %lu bytes failed at %s.%lu\n",363 st_AllocatorName[allocator], (unsigned long)size, file, line);364 st_Output(st_Buffer);365 #endif 366 return(0); 386 sprintf(st_Buffer, "\nFortify: A \"%s\" of %lu bytes failed at %s.%lu\n", 387 st_AllocatorName[allocator], (unsigned long)size, file, line); 388 st_Output(st_Buffer); 389 #endif 390 return(0); 367 391 } 368 392 … … 373 397 374 398 375 /* 399 /* 376 400 * Make the head's prev pointer point to us 377 401 * ('cos we're about to become the head) … … 379 403 if(st_AllocatedHead) 380 404 { 381 st_CheckBlock(st_AllocatedHead, file, line); 382 /* what should we do if this fails? (apart from panic) */ 383 384 st_AllocatedHead->Prev = (struct Header *)ptr; 385 st_MakeHeaderValid(st_AllocatedHead); 386 } 405 st_CheckBlock(st_AllocatedHead, file, line); 406 /* what should we do if this fails? (apart from panic) */ 407 408 st_AllocatedHead->Prev = (struct Header *)ptr; 409 st_MakeHeaderValid(st_AllocatedHead); 410 } 411 412 # ifdef MT_SCOPES 413 ordinal = Get_TID_Ordinal(); 414 # endif 387 415 388 416 /* … … 392 420 h->Size = size; 393 421 h->File = file; 394 h->Line = line; 422 h->Line = line; 395 423 h->Next = st_AllocatedHead; 396 424 h->Prev = 0; 425 # ifdef MT_SCOPES 426 h->Scope = ordinal < st_cScopes ? st_pScopes[ordinal] : 0; 427 h->Ordinal = ordinal; 428 # else 397 429 h->Scope = st_Scope; 430 # endif 398 431 h->Allocator = allocator; 399 432 h->Label = 0; … … 405 438 st_MakeHeaderValid(h); 406 439 st_AllocatedHead = h; 407 440 408 441 /* 409 442 * Initialize the fortifications 410 */ 443 */ 411 444 st_SetFortification(ptr + FORTIFY_HEADER_SIZE, 412 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);445 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE); 413 446 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + size, 414 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);447 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE); 415 448 416 449 #ifdef FORTIFY_FILL_ON_ALLOCATE … … 419 452 */ 420 453 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 421 FORTIFY_FILL_ON_ALLOCATE_VALUE, size);454 FORTIFY_FILL_ON_ALLOCATE_VALUE, size); 422 455 #endif 423 456 … … 436 469 st_CurAllocation += size; 437 470 if(st_CurBlocks > st_MaxBlocks) 438 st_MaxBlocks = st_CurBlocks;471 st_MaxBlocks = st_CurBlocks; 439 472 if(st_CurAllocation > st_MaxAllocation) 440 st_MaxAllocation = st_CurAllocation;473 st_MaxAllocation = st_CurAllocation; 441 474 442 475 /* … … 456 489 { 457 490 unsigned char *ptr = (unsigned char *)uptr 458 - FORTIFY_HEADER_SIZE459 - FORTIFY_ALIGNED_BEFORE_SIZE;491 - FORTIFY_HEADER_SIZE 492 - FORTIFY_ALIGNED_BEFORE_SIZE; 460 493 struct Header *h = (struct Header *)ptr; 494 495 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 496 #ifdef MT_SCOPES 497 unsigned ordinal = Get_TID_Ordinal(); 498 #endif 499 #endif 461 500 462 501 #ifdef FORTIFY_CHECK_ALL_MEMORY_ON_DEALLOCATE … … 470 509 if(st_Disabled) 471 510 { 472 /* there is a possibility that this memory473 * block was allocated when Fortify was474 * enabled, so we must check the Allocated475 * list before we free it.476 */477 if(!st_IsOnAllocatedList(h))478 {479 free(uptr); 480 return;481 } 482 else483 {484 /* the block was allocated by Fortify, so we 485 * gotta free it differently.486 */487 /*488 * Begin critical region489 */490 FORTIFY_LOCK();491 492 /*493 * Remove the block from the list494 */495 if(h->Prev)496 h->Prev->Next = h->Next;497 else498 st_AllocatedHead = h->Next;499 500 if(h->Next)501 h->Next->Prev = h->Prev;502 503 /*504 * End Critical Region505 */506 FORTIFY_UNLOCK();507 508 /*509 * actually free the memory510 */511 free(ptr);512 return;513 }511 /* there is a possibility that this memory 512 * block was allocated when Fortify was 513 * enabled, so we must check the Allocated 514 * list before we free it. 515 */ 516 if(!st_IsOnAllocatedList(h)) 517 { 518 free(uptr); 519 return; 520 } 521 else 522 { 523 /* the block was allocated by Fortify, so we 524 * gotta free it differently. 525 */ 526 /* 527 * Begin critical region 528 */ 529 FORTIFY_LOCK(); 530 531 /* 532 * Remove the block from the list 533 */ 534 if(h->Prev) 535 h->Prev->Next = h->Next; 536 else 537 st_AllocatedHead = h->Next; 538 539 if(h->Next) 540 h->Next->Prev = h->Prev; 541 542 /* 543 * End Critical Region 544 */ 545 FORTIFY_UNLOCK(); 546 547 /* 548 * actually free the memory 549 */ 550 free(ptr); 551 return; 552 } 514 553 } 515 554 … … 519 558 { 520 559 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 521 if(st_IsOnDeallocatedList(h))522 {523 sprintf(st_Buffer, "\nFortify: \"%s\" twice of %s detected at %s.%lu\n",524 st_DeallocatorName[deallocator],525 st_MemoryBlockString(h), file, line);526 st_Output(st_Buffer);527 528 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n",529 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);530 st_Output(st_Buffer);531 st_OutputDeleteTrace();532 return;533 }560 if(st_IsOnDeallocatedList(h)) 561 { 562 sprintf(st_Buffer, "\nFortify: \"%s\" twice of %s detected at %s.%lu\n", 563 st_DeallocatorName[deallocator], 564 st_MemoryBlockString(h), file, line); 565 st_Output(st_Buffer); 566 567 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 568 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 569 st_Output(st_Buffer); 570 st_OutputDeleteTrace(); 571 return; 572 } 534 573 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 535 574 536 575 #ifdef FORTIFY_NO_PERCENT_P 537 sprintf(st_Buffer, "\nFortify: Possible \"%s\" twice of (0x%08lx) was detected at %s.%lu\n",576 sprintf(st_Buffer, "\nFortify: Possible \"%s\" twice of (0x%08lx) was detected at %s.%lu\n", 538 577 #else 539 sprintf(st_Buffer, "\nFortify: Possible \"%s\" twice of (%p) was detected at %s.%lu\n",540 #endif 541 st_DeallocatorName[deallocator],542 uptr, file, line);543 st_Output(st_Buffer);544 st_OutputDeleteTrace();545 return;546 } 547 #endif /* FORTIFY_PARANOID_DE LETE */578 sprintf(st_Buffer, "\nFortify: Possible \"%s\" twice of (%p) was detected at %s.%lu\n", 579 #endif 580 st_DeallocatorName[deallocator], 581 uptr, file, line); 582 st_Output(st_Buffer); 583 st_OutputDeleteTrace(); 584 return; 585 } 586 #endif /* FORTIFY_PARANOID_DEALLOCATE */ 548 587 549 588 /* … … 555 594 if(!st_CheckBlock(h, file, line)) 556 595 { 557 st_OutputDeleteTrace();558 return;596 st_OutputDeleteTrace(); 597 return; 559 598 } 560 599 … … 562 601 /* 563 602 * Make sure the block hasn't been freed already 564 * (we can get to here if FORTIFY_PARANOID_DE LETE603 * (we can get to here if FORTIFY_PARANOID_DEALLOCATE 565 604 * is off, but FORTIFY_TRACK_DEALLOCATED_MEMORY 566 605 * is on). … … 568 607 if(h->Deallocator != Fortify_Deallocator_nobody) 569 608 { 570 sprintf(st_Buffer, "\nFortify: \"%s\" twice of %s detected at %s.%lu\n",571 st_DeallocatorName[deallocator],572 st_MemoryBlockString(h), file, line);573 st_Output(st_Buffer);574 575 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n",576 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);577 st_Output(st_Buffer);578 st_OutputDeleteTrace();579 return;609 sprintf(st_Buffer, "\nFortify: \"%s\" twice of %s detected at %s.%lu\n", 610 st_DeallocatorName[deallocator], 611 st_MemoryBlockString(h), file, line); 612 st_Output(st_Buffer); 613 614 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 615 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 616 st_Output(st_Buffer); 617 st_OutputDeleteTrace(); 618 return; 580 619 } 581 620 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ … … 587 626 if((st_ValidDeallocator[h->Allocator] & (1<<deallocator)) == 0) 588 627 { 589 sprintf(st_Buffer, "\nFortify: Incorrect deallocator \"%s\" detected at %s.%lu\n",590 st_DeallocatorName[deallocator], file, line);591 st_Output(st_Buffer);592 sprintf(st_Buffer, " %s was allocated with \"%s\"\n",593 st_MemoryBlockString(h), st_AllocatorName[h->Allocator]);594 st_Output(st_Buffer);595 st_OutputDeleteTrace();628 sprintf(st_Buffer, "\nFortify: Incorrect deallocator \"%s\" detected at %s.%lu\n", 629 st_DeallocatorName[deallocator], file, line); 630 st_Output(st_Buffer); 631 sprintf(st_Buffer, " %s was allocated with \"%s\"\n", 632 st_MemoryBlockString(h), st_AllocatorName[h->Allocator]); 633 st_Output(st_Buffer); 634 st_OutputDeleteTrace(); 596 635 } 597 636 … … 606 645 if(h->Prev) 607 646 { 608 if(!st_CheckBlock(h->Prev, file, line))609 {610 FORTIFY_UNLOCK();611 st_OutputDeleteTrace();612 return;613 }614 615 h->Prev->Next = h->Next;616 st_MakeHeaderValid(h->Prev);647 if(!st_CheckBlock(h->Prev, file, line)) 648 { 649 FORTIFY_UNLOCK(); 650 st_OutputDeleteTrace(); 651 return; 652 } 653 654 h->Prev->Next = h->Next; 655 st_MakeHeaderValid(h->Prev); 617 656 } 618 657 else 619 st_AllocatedHead = h->Next;658 st_AllocatedHead = h->Next; 620 659 621 660 if(h->Next) 622 661 { 623 if(!st_CheckBlock(h->Next, file, line))624 {625 FORTIFY_UNLOCK();626 st_OutputDeleteTrace();627 return;628 }629 630 h->Next->Prev = h->Prev;631 st_MakeHeaderValid(h->Next);662 if(!st_CheckBlock(h->Next, file, line)) 663 { 664 FORTIFY_UNLOCK(); 665 st_OutputDeleteTrace(); 666 return; 667 } 668 669 h->Next->Prev = h->Prev; 670 st_MakeHeaderValid(h->Next); 632 671 } 633 672 … … 644 683 st_CurAllocation -= h->Size; 645 684 646 647 685 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 686 #ifdef MT_SCOPES 687 ordinal = Get_TID_Ordinal(); 688 if(ordinal < st_cScopes && st_pScopes[ordinal] > 0) 689 #else 648 690 if(st_Scope > 0) 649 { 650 /* 651 * Don't _actually_ free the memory block, just yet. 652 * Place it onto the deallocated list, instead, so 653 * we can check later to see if it's been written to. 654 */ 691 #endif 692 { 693 /* 694 * Don't _actually_ free the memory block, just yet. 695 * Place it onto the deallocated list, instead, so 696 * we can check later to see if it's been written to. 697 */ 655 698 #ifdef FORTIFY_FILL_ON_DEALLOCATE 656 /*657 * Nuke out all user memory that is about to be freed658 */659 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,660 FORTIFY_FILL_ON_DEALLOCATE_VALUE,661 h->Size);699 /* 700 * Nuke out all user memory that is about to be freed 701 */ 702 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 703 FORTIFY_FILL_ON_DEALLOCATE_VALUE, 704 h->Size); 662 705 #endif /* FORTIFY_FILL_ON_DEALLOCATE */ 663 706 664 /* 665 * Begin critical region 666 */ 667 FORTIFY_LOCK(); 668 669 /* 670 * Place the block on the deallocated list 671 */ 672 if(st_DeallocatedHead) 673 { 674 st_DeallocatedHead->Prev = (struct Header *)ptr; 675 st_MakeHeaderValid(st_DeallocatedHead); 676 } 677 678 h = (struct Header *)ptr; 679 h->FreedFile = file; 680 h->FreedLine = line; 681 h->Deallocator = deallocator; 682 h->Next = st_DeallocatedHead; 683 h->Prev = 0; 684 st_MakeHeaderValid(h); 685 st_DeallocatedHead = h; 686 687 if(!st_DeallocatedTail) 688 { 689 st_DeallocatedTail = h; 690 } 691 692 st_TotalDeallocated += h->Size; 707 /* 708 * Begin critical region 709 */ 710 FORTIFY_LOCK(); 711 712 /* 713 * Place the block on the deallocated list 714 */ 715 if(st_DeallocatedHead) 716 { 717 st_DeallocatedHead->Prev = (struct Header *)ptr; 718 st_MakeHeaderValid(st_DeallocatedHead); 719 } 720 721 h = (struct Header *)ptr; 722 h->FreedFile = file; 723 h->FreedLine = line; 724 h->Deallocator = deallocator; 725 h->Next = st_DeallocatedHead; 726 h->Prev = 0; 727 st_MakeHeaderValid(h); 728 st_DeallocatedHead = h; 729 730 if(!st_DeallocatedTail) 731 st_DeallocatedTail = h; 732 733 st_TotalDeallocated += h->Size; 693 734 694 735 #ifdef FORTIFY_DEALLOCATED_MEMORY_LIMIT 695 /*696 * If we've got too much on the deallocated list; free some697 */698 if(st_TotalDeallocated > FORTIFY_DEALLOCATED_MEMORY_LIMIT)699 {700 st_PurgeDeallocatedBlocks(st_TotalDeallocated - FORTIFY_DEALLOCATED_MEMORY_LIMIT, file, line);701 }736 /* 737 * If we've got too much on the deallocated list; free some 738 */ 739 if(st_TotalDeallocated > FORTIFY_DEALLOCATED_MEMORY_LIMIT) 740 { 741 st_PurgeDeallocatedBlocks(st_TotalDeallocated - FORTIFY_DEALLOCATED_MEMORY_LIMIT, file, line); 742 } 702 743 #endif 703 744 704 /*705 * End critical region706 */707 FORTIFY_UNLOCK();745 /* 746 * End critical region 747 */ 748 FORTIFY_UNLOCK(); 708 749 } 709 750 else 710 751 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 711 752 { 712 /*753 /* 713 754 * Free the User Label 714 755 */ … … 716 757 { 717 758 free(h->Label); 718 } 759 } 719 760 720 761 #ifdef FORTIFY_FILL_ON_DEALLOCATE 721 /*722 * Nuke out all memory that is about to be freed, including the header723 */724 st_SetFortification(ptr, FORTIFY_FILL_ON_DEALLOCATE_VALUE,725 FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size + FORTIFY_AFTER_SIZE);762 /* 763 * Nuke out all memory that is about to be freed, including the header 764 */ 765 st_SetFortification(ptr, FORTIFY_FILL_ON_DEALLOCATE_VALUE, 766 FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size + FORTIFY_AFTER_SIZE); 726 767 #endif /* FORTIFY_FILL_ON_DEALLOCATE */ 727 768 728 /*729 * And do the actual free730 */731 free(ptr);769 /* 770 * And do the actual free 771 */ 772 free(ptr); 732 773 } 733 774 } … … 747 788 { 748 789 unsigned char *ptr = (unsigned char *)uptr 749 - FORTIFY_HEADER_SIZE - FORTIFY_ALIGNED_BEFORE_SIZE;790 - FORTIFY_HEADER_SIZE - FORTIFY_ALIGNED_BEFORE_SIZE; 750 791 struct Header *h = (struct Header *)ptr; 751 792 752 793 /* make sure the pointer is okay */ 753 794 Fortify_CheckPointer(uptr, file, line); 754 795 755 796 /* free the previous label */ 756 797 if(h->Label) 757 798 { 758 799 free(h->Label); 759 } 760 800 } 801 761 802 /* make sure the label is sensible */ 762 803 assert(label); … … 765 806 h->Label = (char*)malloc(strlen(label)+1); 766 807 strcpy(h->Label, label); 767 808 768 809 /* update the checksum */ 769 810 st_MakeHeaderValid(h); … … 782 823 { 783 824 unsigned char *ptr = (unsigned char *)uptr 784 - FORTIFY_HEADER_SIZE - FORTIFY_ALIGNED_BEFORE_SIZE;825 - FORTIFY_HEADER_SIZE - FORTIFY_ALIGNED_BEFORE_SIZE; 785 826 struct Header *h = (struct Header *)ptr; 786 827 int r; 787 828 788 829 if(st_Disabled) 789 return 1;830 return 1; 790 831 791 832 FORTIFY_LOCK(); … … 794 835 { 795 836 #ifdef FORTIFY_NO_PERCENT_P 796 sprintf(st_Buffer, "\nFortify: Invalid pointer (0x%08lx) detected at %s.%lu\n",837 sprintf(st_Buffer, "\nFortify: Invalid pointer (0x%08lx) detected at %s.%lu\n", 797 838 #else 798 sprintf(st_Buffer, "\nFortify: Invalid pointer (%p) detected at %s.%lu\n",799 #endif 800 uptr, file, line);801 st_Output(st_Buffer);802 FORTIFY_UNLOCK();803 return(0);839 sprintf(st_Buffer, "\nFortify: Invalid pointer (%p) detected at %s.%lu\n", 840 #endif 841 uptr, file, line); 842 st_Output(st_Buffer); 843 FORTIFY_UNLOCK(); 844 return(0); 804 845 } 805 846 … … 808 849 { 809 850 #ifdef FORTIFY_NO_PERCENT_P 810 sprintf(st_Buffer, "\nFortify: Deallocated pointer (0x%08lx) detected at %s.%lu\n",851 sprintf(st_Buffer, "\nFortify: Deallocated pointer (0x%08lx) detected at %s.%lu\n", 811 852 #else 812 sprintf(st_Buffer, "\nFortify: Deallocated pointer (%p) detected at %s.%lu\n",813 #endif 814 uptr, file, line);815 st_Output(st_Buffer);816 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n",817 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);818 st_Output(st_Buffer);819 FORTIFY_UNLOCK();820 return(0);853 sprintf(st_Buffer, "\nFortify: Deallocated pointer (%p) detected at %s.%lu\n", 854 #endif 855 uptr, file, line); 856 st_Output(st_Buffer); 857 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 858 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 859 st_Output(st_Buffer); 860 FORTIFY_UNLOCK(); 861 return(0); 821 862 } 822 863 #endif … … 830 871 * Fortify_SetOutputFunc(Fortify_OutputFuncPtr Output) - 831 872 * Sets the function used to output all error and 832 * diagnostic messages. The output function takes 833 * a single const unsigned char * argument, and must be 834 * able to handle newlines. This function returns the 873 * diagnostic messages. The output function takes 874 * a single const unsigned char * argument, and must be 875 * able to handle newlines. This function returns the 835 876 * old output function. 836 877 */ … … 841 882 842 883 st_Output = Output; 843 884 844 885 return(Old); 845 886 } 846 887 847 888 /* 848 * Fortify_SetAllocateFailRate(int Percent) - 849 * Fortify_Allocate() will "fail" this Percent of 850 * the time, even if the memory is available. 851 * Useful to "stress-test" an application. 889 * Fortify_SetAllocateFailRate(int Percent) - 890 * Fortify_Allocate() will "fail" this Percent of 891 * the time, even if the memory is available. 892 * Useful to "stress-test" an application. 852 893 * Returns the old value. 853 894 * The fail rate defaults to 0 (a good default I think). … … 857 898 { 858 899 int Old = st_AllocateFailRate; 859 900 860 901 st_AllocateFailRate = Percent; 861 902 862 903 return(Old); 863 904 } 864 905 865 906 866 907 /* 867 908 * Fortify_CheckAllMemory() - Checks the fortifications 868 * of all memory on the allocated list. And, if 909 * of all memory on the allocated list. And, if 869 910 * FORTIFY_DEALLOCATED_MEMORY is enabled, all the 870 911 * known deallocated memory as well. 871 * Returns the number of blocks that failed. 912 * Returns the number of blocks that failed. 872 913 * Always returns 0 if Fortify is disabled. 873 914 */ … … 879 920 880 921 if(st_Disabled) 881 return 0;922 return 0; 882 923 883 924 FORTIFY_LOCK(); … … 885 926 /* 886 927 * Check the allocated memory 887 */ 928 */ 888 929 while(curr) 889 930 { 890 if(!st_CheckBlock(curr, file, line))891 count++;892 893 curr = curr->Next; 931 if(!st_CheckBlock(curr, file, line)) 932 count++; 933 934 curr = curr->Next; 894 935 } 895 936 … … 901 942 while(curr) 902 943 { 903 if(!st_CheckDeallocatedBlock(curr, file, line))904 count++;905 906 curr = curr->Next; 907 } 908 #endif 909 910 /* 944 if(!st_CheckDeallocatedBlock(curr, file, line)) 945 count++; 946 947 curr = curr->Next; 948 } 949 #endif 950 951 /* 911 952 * If we know where we are, and everything is cool, 912 953 * remember that. It might be important. … … 914 955 if(file && count == 0) 915 956 { 916 st_LastVerifiedFile = file;917 st_LastVerifiedLine = line;957 st_LastVerifiedFile = file; 958 st_LastVerifiedLine = line; 918 959 } 919 960 … … 924 965 925 966 /* 926 * Fortify_EnterScope() - enters a new Fortify scope 967 * Fortify_EnterScope() - enters a new Fortify scope 927 968 * level. Returns the new scope level. 928 969 */ … … 930 971 Fortify_EnterScope(const char *file, unsigned long line) 931 972 { 973 #ifdef MT_SCOPES 974 unsigned ordinal = Get_TID_Ordinal(); 975 976 if (ordinal >= st_cScopes) { 977 st_pScopes = realloc((void*)st_pScopes, sizeof(*st_pScopes) * (st_cScopes = (ordinal + 1))); 978 st_pScopes[ordinal] = 0; 979 } 980 return(++st_pScopes[ordinal]); 981 #else 932 982 return(++st_Scope); 983 #endif 933 984 } 934 985 935 986 /* Fortify_LeaveScope - leaves a Fortify scope level, 936 * also prints a memory dump of all non-freed memory 987 * also prints a memory dump of all non-freed memory 937 988 * that was allocated during the scope being exited. 938 989 * Does nothing and returns 0 if Fortify is disabled. … … 943 994 struct Header *curr = st_AllocatedHead; 944 995 unsigned long size = 0, count = 0; 996 #ifdef MT_SCOPES 997 unsigned ordinal; 998 #endif 945 999 946 1000 if(st_Disabled) 947 return 0;1001 return 0; 948 1002 949 1003 FORTIFY_LOCK(); 950 1004 951 st_Scope--; 1005 #ifdef MT_SCOPES 1006 // 06 May 08 SHL fixme to complain to leave without enter 1007 ordinal = Get_TID_Ordinal(); 1008 if (ordinal < st_cScopes && st_pScopes[ordinal] > 0) 1009 st_pScopes[ordinal]--; 1010 else { 1011 sprintf(st_Buffer, "\nFortify: attempting to leave scope before enter at %s.%lu\n", file, line); 1012 st_Output(st_Buffer); 1013 } 1014 #else 1015 if (st_Scope > 0) 1016 st_Scope--; 1017 else { 1018 sprintf(st_Buffer, "\nFortify: attempting to leave scope before enter at %s.%lu\n", file, line); 1019 st_Output(st_Buffer); 1020 } 1021 #endif 952 1022 while(curr) 953 1023 { 954 if(curr->Scope > st_Scope) 955 { 956 if(count == 0) 957 { 958 sprintf(st_Buffer, "\nFortify: Memory leak detected leaving scope at %s.%lu\n", file, line); 959 st_Output(st_Buffer); 960 sprintf(st_Buffer, "%10s %8s %s\n", "Address", "Size", "Allocator"); 961 st_Output(st_Buffer); 962 } 963 964 st_OutputHeader(curr); 965 count++; 966 size += curr->Size; 967 } 968 969 curr = curr->Next; 1024 #ifdef MT_SCOPES 1025 if(curr->Ordinal == ordinal && ordinal < st_cScopes && curr->Scope > st_pScopes[ordinal]) 1026 #else 1027 if(curr->Scope > st_Scope) 1028 #endif 1029 { 1030 if(count == 0) 1031 { 1032 // Report just first occurrance 1033 sprintf(st_Buffer, "\nFortify: Memory leak detected leaving scope at %s.%lu\n", file, line); 1034 st_Output(st_Buffer); 1035 sprintf(st_Buffer, "%10s %8s %s\n", "Address", "Size", "Allocator"); 1036 st_Output(st_Buffer); 1037 } 1038 1039 st_OutputHeader(curr); 1040 count++; 1041 size += curr->Size; 1042 } 1043 1044 curr = curr->Next; 970 1045 } 971 1046 972 1047 if(count) 973 1048 { 974 sprintf(st_Buffer,"%10s %8lu bytes in %lu blocks with %lu bytes overhead\n", 975 "total", size, count, count * FORTIFY_OVERHEAD);976 st_Output(st_Buffer);1049 sprintf(st_Buffer,"%10s %8lu bytes in %lu blocks with %lu bytes overhead\n", 1050 "total", size, count, count * FORTIFY_OVERHEAD); 1051 st_Output(st_Buffer); 977 1052 } 978 1053 979 1054 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 980 /* 981 * Quietly free all the deallocated memory 982 * that was allocated in this scope that 1055 /* 1056 * Quietly free all the deallocated memory 1057 * that was allocated in this scope that 983 1058 * we are still tracking 984 1059 */ 1060 #ifdef MT_SCOPES 1061 st_PurgeDeallocatedScope( ordinal < st_cScopes ? st_pScopes[ordinal] : 0, 1062 file, line ); 1063 #else 985 1064 st_PurgeDeallocatedScope( st_Scope, file, line ); 1065 #endif 986 1066 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 987 1067 988 1068 FORTIFY_UNLOCK(); 1069 #ifdef MT_SCOPES 1070 return(ordinal < st_cScopes ? st_pScopes[ordinal] : 0); 1071 #else 989 1072 return(st_Scope); 990 } 991 992 /* 993 * Fortify_ListAllMemory() - Outputs the entire 994 * list of currently allocated memory. For each block 995 * is output it's Address, Size, and the SourceFile and 1073 #endif 1074 } 1075 1076 /* 1077 * Fortify_ListAllMemory() - Outputs the entire 1078 * list of currently allocated memory. For each block 1079 * is output it's Address, Size, and the SourceFile and 996 1080 * Line that allocated it. 997 1081 * 998 * If there is no memory on the list, this function 1082 * If there is no memory on the list, this function 999 1083 * outputs nothing. 1000 1084 * 1001 * It returns the number of blocks on the list, unless 1002 * Fortify has been disabled, in which case it always 1085 * It returns the number of blocks on the list, unless 1086 * Fortify has been disabled, in which case it always 1003 1087 * returns 0. 1004 1088 */ … … 1010 1094 1011 1095 if(st_Disabled) 1012 return 0;1096 return 0; 1013 1097 1014 1098 Fortify_CheckAllMemory(file, line); … … 1018 1102 if(curr) 1019 1103 { 1020 sprintf(st_Buffer, "\nFortify: Memory List at %s.%lu\n", file, line);1021 st_Output(st_Buffer);1022 sprintf(st_Buffer, "%10s %8s %s\n", "Address", "Size", "Allocator");1023 st_Output(st_Buffer);1024 1025 while(curr)1026 {1027 st_OutputHeader(curr);1028 count++;1029 size += curr->Size;1030 curr = curr->Next; 1031 }1032 1033 sprintf(st_Buffer, "%10s %8lu bytes in %lu blocks and %lu bytes overhead\n", 1034 "total", size, count, count * FORTIFY_OVERHEAD);1035 st_Output(st_Buffer);1036 } 1037 1104 sprintf(st_Buffer, "\nFortify: Memory List at %s.%lu\n", file, line); 1105 st_Output(st_Buffer); 1106 sprintf(st_Buffer, "%10s %8s %s\n", "Address", "Size", "Allocator"); 1107 st_Output(st_Buffer); 1108 1109 while(curr) 1110 { 1111 st_OutputHeader(curr); 1112 count++; 1113 size += curr->Size; 1114 curr = curr->Next; 1115 } 1116 1117 sprintf(st_Buffer, "%10s %8lu bytes in %lu blocks and %lu bytes overhead\n", 1118 "total", size, count, count * FORTIFY_OVERHEAD); 1119 st_Output(st_Buffer); 1120 } 1121 1038 1122 FORTIFY_UNLOCK(); 1039 1123 return(count); … … 1041 1125 1042 1126 /* 1043 * Fortify_DumpAllMemory() - Outputs the entire list of 1044 * currently allocated memory. For each allocated block 1127 * Fortify_DumpAllMemory() - Outputs the entire list of 1128 * currently allocated memory. For each allocated block 1045 1129 * is output it's Address, Size, the SourceFile and Line 1046 * that allocated it, a hex dump of the contents of the 1130 * that allocated it, a hex dump of the contents of the 1047 1131 * memory and an ascii dump of printable characters. 1048 1132 * … … 1056 1140 1057 1141 if(st_Disabled) 1058 return 0;1142 return 0; 1059 1143 1060 1144 Fortify_CheckAllMemory(file, line); … … 1064 1148 while(curr) 1065 1149 { 1066 sprintf(st_Buffer, "\nFortify: Hex Dump of %s at %s.%lu\n",1067 st_MemoryBlockString(curr), file, line);1068 st_Output(st_Buffer);1069 st_OutputMemory(curr);1070 st_Output("\n");1071 count++;1072 1073 curr = curr->Next;1150 sprintf(st_Buffer, "\nFortify: Hex Dump of %s at %s.%lu\n", 1151 st_MemoryBlockString(curr), file, line); 1152 st_Output(st_Buffer); 1153 st_OutputMemory(curr); 1154 st_Output("\n"); 1155 count++; 1156 1157 curr = curr->Next; 1074 1158 } 1075 1159 … … 1078 1162 } 1079 1163 1080 /* Fortify_OutputStatistics() - displays statistics 1081 * about the maximum amount of memory that was 1164 /* Fortify_OutputStatistics() - displays statistics 1165 * about the maximum amount of memory that was 1082 1166 * allocated at any one time. 1083 1167 */ … … 1086 1170 { 1087 1171 if(st_Disabled) 1088 return;1172 return; 1089 1173 1090 1174 sprintf(st_Buffer, "\nFortify: Statistics at %s.%lu\n", file, line); … … 1092 1176 1093 1177 sprintf(st_Buffer, " Memory currently allocated: %lu bytes in %lu blocks\n", 1094 st_CurAllocation, st_CurBlocks);1178 st_CurAllocation, st_CurBlocks); 1095 1179 st_Output(st_Buffer); 1096 sprintf(st_Buffer, " Maximum memory allocated at one time: %lu bytes in %lu blocks\n", 1097 st_MaxAllocation, st_MaxBlocks);1180 sprintf(st_Buffer, " Maximum memory allocated at one time: %lu bytes in %lu blocks\n", 1181 st_MaxAllocation, st_MaxBlocks); 1098 1182 st_Output(st_Buffer); 1099 1183 sprintf(st_Buffer, " There have been %lu allocations and %lu deallocations\n", 1100 st_Allocations, st_Frees);1184 st_Allocations, st_Frees); 1101 1185 st_Output(st_Buffer); 1102 1186 sprintf(st_Buffer, " There was a total of %lu bytes allocated\n", 1103 st_TotalAllocation);1187 st_TotalAllocation); 1104 1188 st_Output(st_Buffer); 1105 1189 1106 1190 if(st_Allocations > 0) 1107 1191 { 1108 sprintf(st_Buffer, " The average allocation was %lu bytes\n",1109 st_TotalAllocation / st_Allocations);1110 st_Output(st_Buffer); 1111 } 1192 sprintf(st_Buffer, " The average allocation was %lu bytes\n", 1193 st_TotalAllocation / st_Allocations); 1194 st_Output(st_Buffer); 1195 } 1112 1196 } 1113 1197 … … 1119 1203 { 1120 1204 if(st_Disabled) 1121 return 0;1205 return 0; 1122 1206 1123 1207 return st_CurAllocation; … … 1139 1223 * The less memory allocated by Fortify when it is disabled 1140 1224 * the better. 1141 * (Previous versions of Fortify did not allow it to be 1225 * (Previous versions of Fortify did not allow it to be 1142 1226 * disabled if there was any memory allocated at the time, 1143 1227 * but since in C++ memory is often allocated before main … … 1170 1254 if(!st_IsHeaderValid(h)) 1171 1255 { 1172 sprintf(st_Buffer,1256 sprintf(st_Buffer, 1173 1257 #ifdef FORTIFY_NO_PERCENT_P 1174 "\nFortify: Invalid pointer (0x%08lx) or corrupted header detected at %s.%lu\n",1258 "\nFortify: Invalid pointer (0x%08lx) or corrupted header detected at %s.%lu\n", 1175 1259 #else 1176 "\nFortify: Invalid pointer (%p) or corrupted header detected at %s.%lu\n",1177 #endif 1178 ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, file, line);1179 st_Output(st_Buffer);1180 st_OutputLastVerifiedPoint();1181 return(0);1260 "\nFortify: Invalid pointer (%p) or corrupted header detected at %s.%lu\n", 1261 #endif 1262 ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, file, line); 1263 st_Output(st_Buffer); 1264 st_OutputLastVerifiedPoint(); 1265 return(0); 1182 1266 } 1183 1267 1184 1268 if(!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE, 1185 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE))1186 { 1187 sprintf(st_Buffer, "\nFortify: Underwrite detected before block %s at %s.%lu\n",1188 st_MemoryBlockString(h), file, line);1189 st_Output(st_Buffer);1190 1191 st_OutputLastVerifiedPoint();1192 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE,1193 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);1194 result = 0; 1269 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE)) 1270 { 1271 sprintf(st_Buffer, "\nFortify: Underwrite detected before block %s at %s.%lu\n", 1272 st_MemoryBlockString(h), file, line); 1273 st_Output(st_Buffer); 1274 1275 st_OutputLastVerifiedPoint(); 1276 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE, 1277 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE); 1278 result = 0; 1195 1279 1196 1280 #ifdef FORTIFY_FILL_ON_CORRUPTION 1197 st_SetFortification(ptr + FORTIFY_HEADER_SIZE, FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);1198 #endif 1199 } 1200 1281 st_SetFortification(ptr + FORTIFY_HEADER_SIZE, FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE); 1282 #endif 1283 } 1284 1201 1285 if(!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size, 1202 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE))1203 { 1204 sprintf(st_Buffer, "\nFortify: Overwrite detected after block %s at %s.%lu\n",1205 st_MemoryBlockString(h), file, line);1206 st_Output(st_Buffer);1207 1208 st_OutputLastVerifiedPoint();1209 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,1210 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);1211 result = 0;1286 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE)) 1287 { 1288 sprintf(st_Buffer, "\nFortify: Overwrite detected after block %s at %s.%lu\n", 1289 st_MemoryBlockString(h), file, line); 1290 st_Output(st_Buffer); 1291 1292 st_OutputLastVerifiedPoint(); 1293 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size, 1294 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE); 1295 result = 0; 1212 1296 1213 1297 #ifdef FORTIFY_FILL_ON_CORRUPTION 1214 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,1215 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);1216 #endif 1217 } 1218 1219 return(result); 1298 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size, 1299 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE); 1300 #endif 1301 } 1302 1303 return(result); 1220 1304 } 1221 1305 1222 1306 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 1223 1307 1224 /* 1308 /* 1225 1309 * st_CheckDeallocatedBlock - Check a deallocated block's header and fortifications. 1226 1310 * Returns true if the block is happy. 1227 1311 */ 1228 static int 1312 static int 1229 1313 st_CheckDeallocatedBlock(struct Header *h, const char *file, unsigned long line) 1230 1314 { … … 1234 1318 if(!st_IsHeaderValid(h)) 1235 1319 { 1236 sprintf(st_Buffer,1320 sprintf(st_Buffer, 1237 1321 #ifdef FORTIFY_NO_PERCENT_P 1238 "\nFortify: Invalid deallocated pointer (0x%08lx) or corrupted header detected at %s.%lu\n",1322 "\nFortify: Invalid deallocated pointer (0x%08lx) or corrupted header detected at %s.%lu\n", 1239 1323 #else 1240 "\nFortify: Invalid deallocated pointer (%p) or corrupted header detected at %s.%lu\n",1241 #endif 1242 ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, file, line);1243 st_Output(st_Buffer);1244 st_OutputLastVerifiedPoint();1245 return(0);1324 "\nFortify: Invalid deallocated pointer (%p) or corrupted header detected at %s.%lu\n", 1325 #endif 1326 ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, file, line); 1327 st_Output(st_Buffer); 1328 st_OutputLastVerifiedPoint(); 1329 return(0); 1246 1330 } 1247 1331 1248 1332 if(!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE, 1249 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE))1250 { 1251 sprintf(st_Buffer, "\nFortify: Underwrite detected before deallocated block %s at %s.%lu\n",1252 st_MemoryBlockString(h), file, line);1253 st_Output(st_Buffer);1254 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n",1255 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);1256 st_Output(st_Buffer);1257 1258 st_OutputLastVerifiedPoint();1259 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE,1260 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);1333 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE)) 1334 { 1335 sprintf(st_Buffer, "\nFortify: Underwrite detected before deallocated block %s at %s.%lu\n", 1336 st_MemoryBlockString(h), file, line); 1337 st_Output(st_Buffer); 1338 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 1339 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 1340 st_Output(st_Buffer); 1341 1342 st_OutputLastVerifiedPoint(); 1343 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE, 1344 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE); 1261 1345 1262 1346 #ifdef FORTIFY_FILL_ON_CORRUPTION 1263 st_SetFortification(ptr + FORTIFY_HEADER_SIZE, FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);1264 #endif 1265 result = 0;1266 } 1267 1347 st_SetFortification(ptr + FORTIFY_HEADER_SIZE, FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE); 1348 #endif 1349 result = 0; 1350 } 1351 1268 1352 if(!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size, 1269 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE))1270 { 1271 sprintf(st_Buffer, "\nFortify: Overwrite detected after deallocated block %s at %s.%lu\n",1272 st_MemoryBlockString(h), file, line);1273 st_Output(st_Buffer);1274 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n",1275 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);1276 st_Output(st_Buffer);1277 1278 st_OutputLastVerifiedPoint();1279 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,1280 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);1353 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE)) 1354 { 1355 sprintf(st_Buffer, "\nFortify: Overwrite detected after deallocated block %s at %s.%lu\n", 1356 st_MemoryBlockString(h), file, line); 1357 st_Output(st_Buffer); 1358 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 1359 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 1360 st_Output(st_Buffer); 1361 1362 st_OutputLastVerifiedPoint(); 1363 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size, 1364 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE); 1281 1365 1282 1366 #ifdef FORTIFY_FILL_ON_CORRUPTION 1283 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,1284 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE);1285 #endif 1286 result = 0;1367 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size, 1368 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE); 1369 #endif 1370 result = 0; 1287 1371 } 1288 1372 1289 1373 #ifdef FORTIFY_FILL_ON_DEALLOCATE 1290 1374 if(!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1291 FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size))1292 { 1293 sprintf(st_Buffer, "\nFortify: Write to deallocated block %s detected at %s.%lu\n",1294 st_MemoryBlockString(h), file, line);1295 st_Output(st_Buffer);1296 1297 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n",1298 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);1299 st_Output(st_Buffer);1300 st_OutputLastVerifiedPoint();1301 1302 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,1303 FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size);1375 FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size)) 1376 { 1377 sprintf(st_Buffer, "\nFortify: Write to deallocated block %s detected at %s.%lu\n", 1378 st_MemoryBlockString(h), file, line); 1379 st_Output(st_Buffer); 1380 1381 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 1382 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 1383 st_Output(st_Buffer); 1384 st_OutputLastVerifiedPoint(); 1385 1386 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1387 FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size); 1304 1388 1305 1389 #ifdef FORTIFY_FILL_ON_CORRUPTION 1306 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,1307 FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size);1390 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1391 FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size); 1308 1392 #endif /* FORTIFY_FILL_ON_CORRUPTION */ 1309 result = 0;1393 result = 0; 1310 1394 } 1311 1395 #endif /* FORTIFY_FILL_ON_DEALLOCATE */ … … 1317 1401 1318 1402 /* 1319 * st_CheckFortification - Checks if the _size_ 1403 * st_CheckFortification - Checks if the _size_ 1320 1404 * bytes from _ptr_ are all set to _value_ 1321 1405 * Returns true if all is happy. 1322 1406 */ 1323 static int 1407 static int 1324 1408 st_CheckFortification(unsigned char *ptr, unsigned char value, size_t size) 1325 1409 { 1326 1410 while(size--) 1327 if(*ptr++ != value)1328 return(0);1329 1330 return(1); 1411 if(*ptr++ != value) 1412 return(0); 1413 1414 return(1); 1331 1415 } 1332 1416 … … 1334 1418 * st_SetFortification - Set the _size_ bytes from _ptr_ to _value_. 1335 1419 */ 1336 static void 1420 static void 1337 1421 st_SetFortification(unsigned char *ptr, unsigned char value, size_t size) 1338 1422 { … … 1341 1425 1342 1426 /* 1343 * st_OutputFortification - Output the corrupted section of the fortification 1427 * st_OutputFortification - Output the corrupted section of the fortification 1344 1428 */ 1345 1429 static void … … 1354 1438 while(offset < size) 1355 1439 { 1356 /* 1357 * Skip 3 or more 'correct' lines1358 */1359 if((size - offset) < 3 * 16) 1360 advance = size - offset;1361 else1362 advance = 3 * 16;1363 if(advance > 0 && st_CheckFortification(ptr+offset, value, advance))1364 {1365 offset += advance;1366 skipped = advance;1367 1368 if(size - offset < 16) 1369 advance = size - offset;1370 else1371 advance = 16;1372 1373 while(advance > 0 && st_CheckFortification(ptr+offset, value, advance))1374 {1375 offset += advance;1376 skipped += advance;1377 if(size - offset < 16) 1378 advance = size - offset;1379 else1380 advance = 16;1381 } 1382 sprintf(st_Buffer, "\n ...%lu bytes skipped...", (unsigned long)skipped);1383 st_Output(st_Buffer);1384 continue;1385 }1386 else1387 {1388 if(size - offset < 16)1389 st_HexDump(ptr, offset, size-offset, 0);1390 else1391 st_HexDump(ptr, offset, 16, 0);1392 1393 offset += 16;1394 }1440 /* 1441 * Skip 3 or more 'correct' lines 1442 */ 1443 if((size - offset) < 3 * 16) 1444 advance = size - offset; 1445 else 1446 advance = 3 * 16; 1447 if(advance > 0 && st_CheckFortification(ptr+offset, value, advance)) 1448 { 1449 offset += advance; 1450 skipped = advance; 1451 1452 if(size - offset < 16) 1453 advance = size - offset; 1454 else 1455 advance = 16; 1456 1457 while(advance > 0 && st_CheckFortification(ptr+offset, value, advance)) 1458 { 1459 offset += advance; 1460 skipped += advance; 1461 if(size - offset < 16) 1462 advance = size - offset; 1463 else 1464 advance = 16; 1465 } 1466 sprintf(st_Buffer, "\n ...%lu bytes skipped...", (unsigned long)skipped); 1467 st_Output(st_Buffer); 1468 continue; 1469 } 1470 else 1471 { 1472 if(size - offset < 16) 1473 st_HexDump(ptr, offset, size-offset, 0); 1474 else 1475 st_HexDump(ptr, offset, 16, 0); 1476 1477 offset += 16; 1478 } 1395 1479 } 1396 1480 … … 1409 1493 1410 1494 if(title) 1411 st_Output(" Address Offset Data");1495 st_Output(" Address Offset Data"); 1412 1496 1413 1497 column = 0; … … 1417 1501 while(output < size) 1418 1502 { 1419 if(column == 0)1420 {1503 if(column == 0) 1504 { 1421 1505 #ifdef FORTIFY_NO_PERCENT_P 1422 sprintf(st_Buffer, "\n0x%08lx %8lu ", ptr, (unsigned long)offset);1506 sprintf(st_Buffer, "\n0x%08lx %8lu ", ptr, (unsigned long)offset); 1423 1507 #else 1424 sprintf(st_Buffer, "\n%10p %8lu ", ptr, (unsigned long)offset);1425 #endif 1426 st_Output(st_Buffer);1427 }1428 1429 sprintf(st_Buffer, "%02x%s", *ptr, ((column % 4) == 3) ? " " : "");1430 st_Output(st_Buffer);1431 1432 ascii[ column ] = isprint( *ptr ) ? (char)(*ptr) : (char)('.');1433 ascii[ column + 1 ] = '\0';1434 1435 ptr++;1436 offset++;1437 output++;1438 column++;1439 1440 if(column == 16)1441 {1442 st_Output( " \"" );1443 st_Output( ascii );1444 st_Output( "\"" );1445 column = 0;1446 }1508 sprintf(st_Buffer, "\n%10p %8lu ", ptr, (unsigned long)offset); 1509 #endif 1510 st_Output(st_Buffer); 1511 } 1512 1513 sprintf(st_Buffer, "%02x%s", *ptr, ((column % 4) == 3) ? " " : ""); 1514 st_Output(st_Buffer); 1515 1516 ascii[ column ] = isprint( *ptr ) ? (char)(*ptr) : (char)('.'); 1517 ascii[ column + 1 ] = '\0'; 1518 1519 ptr++; 1520 offset++; 1521 output++; 1522 column++; 1523 1524 if(column == 16) 1525 { 1526 st_Output( " \"" ); 1527 st_Output( ascii ); 1528 st_Output( "\"" ); 1529 column = 0; 1530 } 1447 1531 } 1448 1532 1449 1533 if ( column != 0 ) 1450 1534 { 1451 while ( column < 16 )1452 {1453 if( column % 4 == 3 )1454 st_Output( " " );1455 else1456 st_Output( " " );1457 1458 column++;1459 }1460 st_Output( " \"" );1461 st_Output( ascii );1462 st_Output( "\"" );1463 } 1464 } 1465 1466 /* 1467 * st_IsHeaderValid - Returns true if the 1468 * supplied pointer does indeed point to a 1535 while ( column < 16 ) 1536 { 1537 if( column % 4 == 3 ) 1538 st_Output( " " ); 1539 else 1540 st_Output( " " ); 1541 1542 column++; 1543 } 1544 st_Output( " \"" ); 1545 st_Output( ascii ); 1546 st_Output( "\"" ); 1547 } 1548 } 1549 1550 /* 1551 * st_IsHeaderValid - Returns true if the 1552 * supplied pointer does indeed point to a 1469 1553 * real Header 1470 1554 */ 1471 static int 1472 st_IsHeaderValid(struct Header *h) 1555 static int 1556 st_IsHeaderValid(struct Header *h) 1473 1557 { 1474 1558 return(st_ChecksumHeader(h) == FORTIFY_CHECKSUM_VALUE); … … 1476 1560 1477 1561 /* 1478 * st_MakeHeaderValid - Updates the checksum 1562 * st_MakeHeaderValid - Updates the checksum 1479 1563 * to make the header valid 1480 1564 */ 1481 static void 1565 static void 1482 1566 st_MakeHeaderValid(struct Header *h) 1483 1567 { … … 1487 1571 1488 1572 /* 1489 * st_ChecksumHeader - Calculate (and return) 1490 * the checksum of the header. (Including the 1491 * Checksum field itself. If all is well, the 1573 * st_ChecksumHeader - Calculate (and return) 1574 * the checksum of the header. (Including the 1575 * Checksum field itself. If all is well, the 1492 1576 * checksum returned by this function should 1493 1577 * be FORTIFY_CHECKSUM_VALUE … … 1497 1581 { 1498 1582 unsigned short c, checksum, *p; 1499 1500 for(c = 0, checksum = 0, p = (unsigned short *)h; 1501 c < FORTIFY_HEADER_SIZE/sizeof(unsigned short); c++)1502 { 1503 checksum += *p++; 1504 } 1505 1583 1584 for(c = 0, checksum = 0, p = (unsigned short *)h; 1585 c < FORTIFY_HEADER_SIZE/sizeof(unsigned short); c++) 1586 { 1587 checksum += *p++; 1588 } 1589 1506 1590 return(checksum); 1507 } 1508 1509 /* 1510 * st_IsOnAllocatedList - Examines the allocated 1591 } 1592 1593 /* 1594 * st_IsOnAllocatedList - Examines the allocated 1511 1595 * list to see if the given header is on it. 1512 */ 1513 static int 1596 */ 1597 static int 1514 1598 st_IsOnAllocatedList(struct Header *h) 1515 1599 { 1516 1600 struct Header *curr; 1517 1601 1518 1602 curr = st_AllocatedHead; 1519 1603 while(curr) 1520 1604 { 1521 if(curr == h)1522 return(1);1523 1524 curr = curr->Next;1525 } 1526 1605 if(curr == h) 1606 return(1); 1607 1608 curr = curr->Next; 1609 } 1610 1527 1611 return(0); 1528 1612 } 1529 1613 1530 1614 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 1531 /* 1532 * st_IsOnDeallocatedList - Examines the deallocated 1615 /* 1616 * st_IsOnDeallocatedList - Examines the deallocated 1533 1617 * list to see if the given header is on it. 1534 */ 1535 static int 1618 */ 1619 static int 1536 1620 st_IsOnDeallocatedList(struct Header *h) 1537 1621 { 1538 1622 struct Header *curr; 1539 1623 1540 1624 curr = st_DeallocatedHead; 1541 1625 while(curr) 1542 1626 { 1543 if(curr == h)1544 return(1);1545 1546 curr = curr->Next;1547 } 1548 1627 if(curr == h) 1628 return(1); 1629 1630 curr = curr->Next; 1631 } 1632 1549 1633 return(0); 1550 1634 } … … 1552 1636 /* 1553 1637 * st_PurgeDeallocatedBlocks - free at least "Bytes" 1554 * worth of deallocated memory, starting at the 1638 * worth of deallocated memory, starting at the 1555 1639 * oldest deallocated block. 1556 1640 * Returns true if any blocks were freed. … … 1563 1647 1564 1648 #ifdef FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY 1565 sprintf(st_Buffer, "\nFortify: Warning - Discarding deallocated memory at %s.%lu\n", 1566 file, line);1649 sprintf(st_Buffer, "\nFortify: Warning - Discarding deallocated memory at %s.%lu\n", 1650 file, line); 1567 1651 st_Output(st_Buffer); 1568 1652 #endif /* FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */ … … 1570 1654 while(st_DeallocatedTail && FreedBytes < Bytes) 1571 1655 { 1572 st_CheckDeallocatedBlock(st_DeallocatedTail, file, line);1573 FreedBytes += st_DeallocatedTail->Size;1574 FreedBlocks++;1656 st_CheckDeallocatedBlock(st_DeallocatedTail, file, line); 1657 FreedBytes += st_DeallocatedTail->Size; 1658 FreedBlocks++; 1575 1659 #ifdef FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY 1576 1660 #ifdef FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY 1577 sprintf(st_Buffer, " %s\n",1578 st_DeallocatedMemoryBlockString(st_DeallocatedTail));1579 st_Output(st_Buffer);1661 sprintf(st_Buffer, " %s\n", 1662 st_DeallocatedMemoryBlockString(st_DeallocatedTail)); 1663 st_Output(st_Buffer); 1580 1664 #endif /* FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */ 1581 1665 #endif /* FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */ 1582 st_FreeDeallocatedBlock(st_DeallocatedTail, file, line);1666 st_FreeDeallocatedBlock(st_DeallocatedTail, file, line); 1583 1667 } 1584 1668 … … 1595 1679 struct Header *curr, *next; 1596 1680 unsigned long FreedBlocks = 0; 1681 #ifdef MT_SCOPES 1682 unsigned short ordinal = Get_TID_Ordinal(); 1683 #endif 1597 1684 1598 1685 curr = st_DeallocatedHead; 1599 1686 while(curr) 1600 1687 { 1601 next = curr->Next; 1602 if(curr->Scope >= Scope) 1603 { 1604 st_FreeDeallocatedBlock(curr, file, line); 1605 FreedBlocks++; 1606 } 1607 1608 curr = next; 1609 } 1610 1688 next = curr->Next; 1689 #ifdef MT_SCOPES 1690 if(curr->Ordinal == ordinal && curr->Scope >= Scope) 1691 #else 1692 if(curr->Scope >= Scope) 1693 #endif 1694 { 1695 st_FreeDeallocatedBlock(curr, file, line); 1696 FreedBlocks++; 1697 } 1698 1699 curr = next; 1700 } 1701 1611 1702 return FreedBlocks != 0; 1612 1703 } … … 1614 1705 /* 1615 1706 * st_FreeDeallocatedBlock - actually remove 1616 * a deallocated block from the deallocated 1707 * a deallocated block from the deallocated 1617 1708 * list, and actually free it's memory. 1618 1709 */ … … 1622 1713 st_CheckDeallocatedBlock( h, file, line ); 1623 1714 1624 /* 1625 * Begin Critical region 1715 /* 1716 * Begin Critical region 1626 1717 */ 1627 1718 FORTIFY_LOCK(); 1628 1719 1629 1720 st_TotalDeallocated -= h->Size; 1630 1721 1631 1722 if(st_DeallocatedHead == h) 1632 1723 { 1633 st_DeallocatedHead = h->Next;1634 } 1635 1724 st_DeallocatedHead = h->Next; 1725 } 1726 1636 1727 if(st_DeallocatedTail == h) 1637 1728 { 1638 st_DeallocatedTail = h->Prev;1639 } 1640 1729 st_DeallocatedTail = h->Prev; 1730 } 1731 1641 1732 if(h->Prev) 1642 1733 { 1643 st_CheckDeallocatedBlock(h->Prev, file, line);1644 h->Prev->Next = h->Next;1645 st_MakeHeaderValid(h->Prev); 1646 } 1647 1734 st_CheckDeallocatedBlock(h->Prev, file, line); 1735 h->Prev->Next = h->Next; 1736 st_MakeHeaderValid(h->Prev); 1737 } 1738 1648 1739 if(h->Next) 1649 1740 { 1650 st_CheckDeallocatedBlock(h->Next, file, line);1651 h->Next->Prev = h->Prev;1652 st_MakeHeaderValid(h->Next); 1741 st_CheckDeallocatedBlock(h->Next, file, line); 1742 h->Next->Prev = h->Prev; 1743 st_MakeHeaderValid(h->Next); 1653 1744 } 1654 1745 … … 1656 1747 * Free the label 1657 1748 */ 1658 if(h->Label) 1749 if(h->Label) 1659 1750 { 1660 1751 free(h->Label); … … 1665 1756 */ 1666 1757 st_SetFortification((unsigned char*)h, FORTIFY_FILL_ON_DEALLOCATE_VALUE, 1667 FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size + FORTIFY_AFTER_SIZE);1758 FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size + FORTIFY_AFTER_SIZE); 1668 1759 1669 1760 /* … … 1671 1762 */ 1672 1763 free(h); 1673 1764 1674 1765 /* 1675 1766 * End critical region 1676 1767 */ 1677 FORTIFY_UNLOCK(); 1768 FORTIFY_UNLOCK(); 1678 1769 } 1679 1770 … … 1681 1772 1682 1773 /* 1683 * st_OutputMemory - Hex and ascii dump the 1774 * st_OutputMemory - Hex and ascii dump the 1684 1775 * user memory of a block. 1685 1776 */ … … 1688 1779 { 1689 1780 st_HexDump((unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1690 0, h->Size, 1);1781 0, h->Size, 1); 1691 1782 } 1692 1783 … … 1695 1786 * st_OutputHeader - Output the header 1696 1787 */ 1697 static void 1788 static void 1698 1789 st_OutputHeader(struct Header *h) 1699 1790 { … … 1701 1792 { 1702 1793 #ifdef FORTIFY_NO_PERCENT_P 1703 sprintf(st_Buffer, "0x%08lx %8lu %s.%lu\n", 1794 sprintf(st_Buffer, "0x%08lx %8lu %s.%lu\n", 1704 1795 #else 1705 sprintf(st_Buffer, "%10p %8lu %s.%lu\n", 1706 #endif 1707 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,1708 (unsigned long)h->Size,1709 h->File, h->Line);1710 } 1796 sprintf(st_Buffer, "%10p %8lu %s.%lu\n", 1797 #endif 1798 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1799 (unsigned long)h->Size, 1800 h->File, h->Line); 1801 } 1711 1802 else 1712 1803 { 1713 1804 #ifdef FORTIFY_NO_PERCENT_P 1714 sprintf(st_Buffer, "0x%08lx %8lu %s.%lu %s\n", 1805 sprintf(st_Buffer, "0x%08lx %8lu %s.%lu %s\n", 1715 1806 #else 1716 sprintf(st_Buffer, "%10p %8lu %s.%lu %s\n", 1717 #endif 1718 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,1719 (unsigned long)h->Size,1720 h->File, h->Line, h->Label);1807 sprintf(st_Buffer, "%10p %8lu %s.%lu %s\n", 1808 #endif 1809 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1810 (unsigned long)h->Size, 1811 h->File, h->Line, h->Label); 1721 1812 } 1722 1813 st_Output(st_Buffer); … … 1727 1818 * known point where everything was hoopy. 1728 1819 */ 1729 static void 1820 static void 1730 1821 st_OutputLastVerifiedPoint() 1731 1822 { 1732 sprintf(st_Buffer, " Memory integrity was last verified at %s.%lu\n", 1733 st_LastVerifiedFile,1734 st_LastVerifiedLine);1823 sprintf(st_Buffer, " Memory integrity was last verified at %s.%lu\n", 1824 st_LastVerifiedFile, 1825 st_LastVerifiedLine); 1735 1826 st_Output(st_Buffer); 1736 1827 } 1737 1828 1738 1829 /* 1739 * st_MemoryBlockString - constructs a string that 1830 * st_MemoryBlockString - constructs a string that 1740 1831 * desribes a memory block. (pointer,size,allocator,label) 1741 1832 */ … … 1744 1835 { 1745 1836 static char st_BlockString[512]; 1746 1837 1747 1838 if(h->Label == 0) 1748 1839 { … … 1752 1843 sprintf(st_BlockString,"(%p,%lu,%s.%lu)", 1753 1844 #endif 1754 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,1755 (unsigned long)h->Size, h->File, h->Line);1756 } 1845 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1846 (unsigned long)h->Size, h->File, h->Line); 1847 } 1757 1848 else 1758 1849 { … … 1762 1853 sprintf(st_BlockString,"(%p,%lu,%s.%lu,%s)", 1763 1854 #endif 1764 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,1765 (unsigned long)h->Size, h->File, h->Line, h->Label);1855 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1856 (unsigned long)h->Size, h->File, h->Line, h->Label); 1766 1857 } 1767 1858 … … 1790 1881 sprintf(st_BlockString,"(%p,%lu,%s.%lu,%s.%lu)", 1791 1882 #endif 1792 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,1793 (unsigned long)h->Size, h->File, h->Line, h->FreedFile, h->FreedLine);1794 } 1883 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1884 (unsigned long)h->Size, h->File, h->Line, h->FreedFile, h->FreedLine); 1885 } 1795 1886 else 1796 1887 { … … 1800 1891 sprintf(st_BlockString,"(%p,%lu,%s.%lu,%s.%lu,%s)", 1801 1892 #endif 1802 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,1803 (unsigned long)h->Size, h->File, h->Line, h->FreedFile, h->FreedLine, h->Label);1893 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1894 (unsigned long)h->Size, h->File, h->Line, h->FreedFile, h->FreedLine, h->Label); 1804 1895 } 1805 1896 … … 1841 1932 1842 1933 /* 1843 * If Fortify is disabled, we gotta do this a little 1934 * If Fortify is disabled, we gotta do this a little 1844 1935 * differently. 1845 1936 */ 1846 if(!st_Disabled) 1847 { 1848 if(!uptr)1849 return(Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line));1850 1851 if(!st_IsOnAllocatedList(h))1852 {1937 if(!st_Disabled) 1938 { 1939 if(!uptr) 1940 return(Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line)); 1941 1942 if(!st_IsOnAllocatedList(h)) 1943 { 1853 1944 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 1854 if(st_IsOnDeallocatedList(h))1855 {1856 sprintf(st_Buffer, "\nFortify: Deallocated memory block passed to \"%s\" at %s.%lu\n",1857 st_AllocatorName[Fortify_Allocator_realloc], file, line);1858 st_Output(st_Buffer);1859 sprintf(st_Buffer, " Memory block %s was deallocated by \"%s\" at %s.%lu\n",1860 st_MemoryBlockString(h),1861 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine);1862 st_Output(st_Buffer);1863 return 0;1864 }1865 #endif 1866 1867 sprintf(st_Buffer, 1945 if(st_IsOnDeallocatedList(h)) 1946 { 1947 sprintf(st_Buffer, "\nFortify: Deallocated memory block passed to \"%s\" at %s.%lu\n", 1948 st_AllocatorName[Fortify_Allocator_realloc], file, line); 1949 st_Output(st_Buffer); 1950 sprintf(st_Buffer, " Memory block %s was deallocated by \"%s\" at %s.%lu\n", 1951 st_MemoryBlockString(h), 1952 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 1953 st_Output(st_Buffer); 1954 return 0; 1955 } 1956 #endif 1957 1958 sprintf(st_Buffer, 1868 1959 #ifdef FORTIFY_NO_PERCENT_P 1869 "\nFortify: Invalid pointer (0x%08lx) passed to realloc at %s.%lu\n",1960 "\nFortify: Invalid pointer (0x%08lx) passed to realloc at %s.%lu\n", 1870 1961 #else 1871 "\nFortify: Invalid pointer (%p) passed to realloc at %s.%lu\n",1872 #endif 1873 ptr, file, line);1874 st_Output(st_Buffer);1875 return 0;1876 }1877 1878 if(!st_CheckBlock(h, file, line))1879 return 0;1880 1881 new_ptr = Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line);1882 if(!new_ptr)1883 {1884 return(0);1885 }1886 1887 if(h->Size < new_size) 1888 memcpy(new_ptr, uptr, h->Size);1889 else1890 memcpy(new_ptr, uptr, new_size);1891 1892 Fortify_Deallocate(uptr, Fortify_Deallocator_realloc, file, line);1893 return(new_ptr);1962 "\nFortify: Invalid pointer (%p) passed to realloc at %s.%lu\n", 1963 #endif 1964 ptr, file, line); 1965 st_Output(st_Buffer); 1966 return 0; 1967 } 1968 1969 if(!st_CheckBlock(h, file, line)) 1970 return 0; 1971 1972 new_ptr = Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line); 1973 if(!new_ptr) 1974 { 1975 return(0); 1976 } 1977 1978 if(h->Size < new_size) 1979 memcpy(new_ptr, uptr, h->Size); 1980 else 1981 memcpy(new_ptr, uptr, new_size); 1982 1983 Fortify_Deallocate(uptr, Fortify_Deallocator_realloc, file, line); 1984 return(new_ptr); 1894 1985 } 1895 1986 else 1896 1987 { 1897 /*1898 * If the old block was fortified, we can't use normal realloc.1899 */1900 if(st_IsOnAllocatedList(h))1901 {1902 new_ptr = Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line);1903 if(!new_ptr)1904 return(0);1905 1906 if(h->Size < new_size) 1907 memcpy(new_ptr, uptr, h->Size);1908 else1909 memcpy(new_ptr, uptr, new_size);1910 1911 Fortify_Deallocate(uptr, Fortify_Deallocator_realloc, file, line);1912 return(new_ptr);1913 }1914 else /* easy */1915 {1916 return realloc(uptr, new_size);1917 }1988 /* 1989 * If the old block was fortified, we can't use normal realloc. 1990 */ 1991 if(st_IsOnAllocatedList(h)) 1992 { 1993 new_ptr = Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line); 1994 if(!new_ptr) 1995 return(0); 1996 1997 if(h->Size < new_size) 1998 memcpy(new_ptr, uptr, h->Size); 1999 else 2000 memcpy(new_ptr, uptr, new_size); 2001 2002 Fortify_Deallocate(uptr, Fortify_Deallocator_realloc, file, line); 2003 return(new_ptr); 2004 } 2005 else /* easy */ 2006 { 2007 return realloc(uptr, new_size); 2008 } 1918 2009 } 1919 2010 } … … 1927 2018 if(!st_Disabled) 1928 2019 { 1929 void *ptr = Fortify_Allocate(size * num, Fortify_Allocator_calloc, file, line);1930 if(ptr)1931 {1932 memset(ptr, 0, size*num);1933 }1934 return ptr;1935 } 2020 void *ptr = Fortify_Allocate(size * num, Fortify_Allocator_calloc, file, line); 2021 if(ptr) 2022 { 2023 memset(ptr, 0, size*num); 2024 } 2025 return ptr; 2026 } 1936 2027 else 1937 2028 { 1938 return calloc(num, size);2029 return calloc(num, size); 1939 2030 } 1940 2031 } … … 1948 2039 /* it is defined to be safe to free(0) */ 1949 2040 if(uptr == 0) 1950 return;2041 return; 1951 2042 1952 2043 Fortify_Deallocate(uptr, Fortify_Deallocator_free, file, line); … … 1963 2054 if(!st_Disabled) 1964 2055 { 1965 char *newStr = (char *)Fortify_Allocate(strlen(oldStr)+1, Fortify_Allocator_strdup, file, line);1966 if(newStr)1967 {1968 strcpy(newStr, oldStr);1969 }1970 1971 return newStr;1972 } 2056 char *newStr = (char *)Fortify_Allocate(strlen(oldStr)+1, Fortify_Allocator_strdup, file, line); 2057 if(newStr) 2058 { 2059 strcpy(newStr, oldStr); 2060 } 2061 2062 return newStr; 2063 } 1973 2064 else 1974 2065 { 1975 return strdup(oldStr);2066 return strdup(oldStr); 1976 2067 } 1977 2068 } … … 1984 2075 if(st_DeleteStackTop > 1) 1985 2076 { 1986 sprintf(st_Buffer, "Delete Trace: %s.%lu\n", st_DeleteFile[st_DeleteStackTop-1],1987 st_DeleteLine[st_DeleteStackTop-1]);1988 st_Output(st_Buffer);1989 for(int c = st_DeleteStackTop-2; c >= 0; c--)1990 {1991 sprintf(st_Buffer, " %s.%lu\n", st_DeleteFile[c],1992 st_DeleteLine[c]);1993 st_Output(st_Buffer);1994 }2077 sprintf(st_Buffer, "Delete Trace: %s.%lu\n", st_DeleteFile[st_DeleteStackTop-1], 2078 st_DeleteLine[st_DeleteStackTop-1]); 2079 st_Output(st_Buffer); 2080 for(int c = st_DeleteStackTop-2; c >= 0; c--) 2081 { 2082 sprintf(st_Buffer, " %s.%lu\n", st_DeleteFile[c], 2083 st_DeleteLine[c]); 2084 st_Output(st_Buffer); 2085 } 1995 2086 } 1996 2087 #endif … … 2012 2103 Fortify_NewHandlerFunc handler = set_new_handler(0); 2013 2104 2014 /* and set it back (since we cant 2105 /* and set it back (since we cant 2015 2106 * get it without changing it) 2016 2107 */ 2017 2108 set_new_handler(handler); 2018 2109 2019 2110 return handler; 2020 2111 } 2021 2112 2022 2113 /* 2023 * operator new - Fortify's replacement new, 2114 * operator new - Fortify's replacement new, 2024 2115 * without source-code information. 2025 2116 */ … … 2028 2119 { 2029 2120 void *p; 2030 2031 while((p = Fortify_Allocate(size, Fortify_Allocator_new, 2032 st_AllocatorName[Fortify_Allocator_new], 0)) == 0)2033 { 2034 if(st_NewHandler())2035 (*st_NewHandler())();2036 else2037 return 0;2121 2122 while((p = Fortify_Allocate(size, Fortify_Allocator_new, 2123 st_AllocatorName[Fortify_Allocator_new], 0)) == 0) 2124 { 2125 if(st_NewHandler()) 2126 (*st_NewHandler())(); 2127 else 2128 return 0; 2038 2129 } 2039 2130 … … 2052 2143 while((p = Fortify_Allocate(size, Fortify_Allocator_new, file, line)) == 0) 2053 2144 { 2054 if(st_NewHandler())2055 (*st_NewHandler())();2056 else2057 return 0;2058 } 2059 2145 if(st_NewHandler()) 2146 (*st_NewHandler())(); 2147 else 2148 return 0; 2149 } 2150 2060 2151 return p; 2061 2152 } … … 2067 2158 */ 2068 2159 void *FORTIFY_STORAGE 2069 operator new[](size_t size) 2160 operator new[](size_t size) 2070 2161 { 2071 2162 void *p; 2072 2163 2073 2164 while((p = Fortify_Allocate(size, Fortify_Allocator_array_new, 2074 st_AllocatorName[Fortify_Allocator_array_new], 0)) == 0)2075 { 2076 if(st_NewHandler())2077 (*st_NewHandler())(); 2078 else 2079 return 0;2080 } 2081 2165 st_AllocatorName[Fortify_Allocator_array_new], 0)) == 0) 2166 { 2167 if(st_NewHandler()) 2168 (*st_NewHandler())(); 2169 else 2170 return 0; 2171 } 2172 2082 2173 return p; 2083 2174 } … … 2093 2184 while((p = Fortify_Allocate(size, Fortify_Allocator_array_new, file, line)) == 0) 2094 2185 { 2095 if(st_NewHandler())2096 (*st_NewHandler())(); 2097 else2098 return 0;2186 if(st_NewHandler()) 2187 (*st_NewHandler())(); 2188 else 2189 return 0; 2099 2190 } 2100 2191 … … 2120 2211 if(st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE) 2121 2212 { 2122 st_DeleteFile[st_DeleteStackTop] = file;2123 st_DeleteLine[st_DeleteStackTop] = line;2213 st_DeleteFile[st_DeleteStackTop] = file; 2214 st_DeleteLine[st_DeleteStackTop] = line; 2124 2215 } 2125 2216 … … 2152 2243 */ 2153 2244 if(uptr == 0) 2154 return;2245 return; 2155 2246 2156 2247 /* … … 2159 2250 if(st_DeleteStackTop) 2160 2251 { 2161 if(st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE)2162 {2163 file = st_DeleteFile[st_DeleteStackTop-1];2164 line = st_DeleteLine[st_DeleteStackTop-1];2165 }2166 else2167 {2168 file = st_DeleteFile[FORTIFY_DELETE_STACK_SIZE-1];2169 line = st_DeleteLine[FORTIFY_DELETE_STACK_SIZE-1];2170 }2252 if(st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE) 2253 { 2254 file = st_DeleteFile[st_DeleteStackTop-1]; 2255 line = st_DeleteLine[st_DeleteStackTop-1]; 2256 } 2257 else 2258 { 2259 file = st_DeleteFile[FORTIFY_DELETE_STACK_SIZE-1]; 2260 line = st_DeleteLine[FORTIFY_DELETE_STACK_SIZE-1]; 2261 } 2171 2262 } 2172 2263 else 2173 2264 { 2174 file = st_DeallocatorName[Fortify_Deallocator_delete];2175 line = 0;2265 file = st_DeallocatorName[Fortify_Deallocator_delete]; 2266 line = 0; 2176 2267 } 2177 2268 … … 2194 2285 */ 2195 2286 if(uptr == 0) 2196 return;2287 return; 2197 2288 2198 2289 /* … … 2201 2292 if(st_DeleteStackTop) 2202 2293 { 2203 if(st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE)2204 {2205 file = st_DeleteFile[st_DeleteStackTop-1];2206 line = st_DeleteLine[st_DeleteStackTop-1];2207 }2208 else2209 {2210 file = st_DeleteFile[FORTIFY_DELETE_STACK_SIZE-1];2211 line = st_DeleteLine[FORTIFY_DELETE_STACK_SIZE-1];2212 }2294 if(st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE) 2295 { 2296 file = st_DeleteFile[st_DeleteStackTop-1]; 2297 line = st_DeleteLine[st_DeleteStackTop-1]; 2298 } 2299 else 2300 { 2301 file = st_DeleteFile[FORTIFY_DELETE_STACK_SIZE-1]; 2302 line = st_DeleteLine[FORTIFY_DELETE_STACK_SIZE-1]; 2303 } 2213 2304 } 2214 2305 else 2215 2306 { 2216 file = st_DeallocatorName[Fortify_Deallocator_array_delete];2217 line = 0;2307 file = st_DeallocatorName[Fortify_Deallocator_array_delete]; 2308 line = 0; 2218 2309 } 2219 2310 … … 2243 2334 Fortify_AutoLogFile() 2244 2335 { 2245 written_something = 0;2246 Fortify_SetOutputFunc(Fortify_AutoLogFile::Output);2247 Fortify_EnterScope(init_string, 0);2336 written_something = 0; 2337 Fortify_SetOutputFunc(Fortify_AutoLogFile::Output); 2338 Fortify_EnterScope(init_string, 0); 2248 2339 } 2249 2340 2250 2341 static void Output(const char *s) 2251 2342 { 2252 if(written_something == 0)2253 {2254 FORTIFY_FIRST_ERROR_FUNCTION;2255 fp = fopen(FORTIFY_LOG_FILENAME, "w");2256 if(fp)2257 {2258 time_t t;2259 time(&t);2260 fprintf(fp, "Fortify log started at %s\n", ctime(&t));2261 written_something = 1;2262 } 2263 }2264 2265 if(fp)2266 {2267 fputs(s, fp);2268 fflush(fp);2269 } 2270 } 2271 2343 if(written_something == 0) 2344 { 2345 FORTIFY_FIRST_ERROR_FUNCTION; 2346 fp = fopen(FORTIFY_LOG_FILENAME, "w"); 2347 if(fp) 2348 { 2349 time_t t; 2350 time(&t); 2351 fprintf(fp, "Fortify log started at %s\n", ctime(&t)); 2352 written_something = 1; 2353 } 2354 } 2355 2356 if(fp) 2357 { 2358 fputs(s, fp); 2359 fflush(fp); 2360 } 2361 } 2362 2272 2363 ~Fortify_AutoLogFile() 2273 2364 { 2274 Fortify_LeaveScope(term_string, 0);2275 Fortify_CheckAllMemory(term_string, 0);2276 if(fp)2277 {2278 time_t t;2279 time(&t);2280 fprintf(fp, "\nFortify log closed at %s\n", ctime(&t));2281 fclose(fp);2282 fp = 0;2283 } 2365 Fortify_LeaveScope(term_string, 0); 2366 Fortify_CheckAllMemory(term_string, 0); 2367 if(fp) 2368 { 2369 time_t t; 2370 time(&t); 2371 fprintf(fp, "\nFortify log closed at %s\n", ctime(&t)); 2372 fclose(fp); 2373 fp = 0; 2374 } 2284 2375 } 2285 2376 };  
  Note:
 See   TracChangeset
 for help on using the changeset viewer.
  