Changeset 1078 for trunk/dll/fortify.c
- Timestamp:
- Jul 19, 2008, 6:08:02 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/dll/fortify.c
r1077 r1078 2 2 /* $Id$ */ 3 3 /* fortify.cxx - A fortified memory allocation shell - V2.2 */ 4 /* vim: tabs 4 */ 4 5 5 6 /* … … 42 43 43 44 /* 06 May 08 SHL Rework scope logic to be MT capable 44 26 May 08 SHL Show TID for leaking scope 45 17 Jul 08 SHL Add Fortify_SetOwner Fortify_ChangeOwner Fortify_ChangeScope 46 18 Jul 08 SHL Add FORTIFY_VERBOSE_SCOPE_ENTER_EXIT 45 26 May 08 SHL Show TID for leaking scope 46 17 Jul 08 SHL Add Fortify_PresetOwner Fortify_BecomeOwner Fortify_ChangeScope 47 18 Jul 08 SHL Add FORTIFY_VERBOSE_SCOPE_ENTER_EXIT 48 18 Jul 08 SHL Add Fortify_SetScope 49 18 Jul 08 SHL Rename Fortify_ChangeOwner to Fortify_BecomeOwner 50 18 Jul 08 SHL Add reworked Fortify_SetOwner 47 51 */ 48 52 … … 89 93 struct Header 90 94 { 91 92 93 94 # ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY95 96 97 98 # endif99 100 101 102 103 104 105 # 106 107 # 95 unsigned short Checksum; /* For the integrity of our goodies */ 96 const char *File; /* The sourcefile of the allocator */ 97 unsigned long Line; /* The sourceline of the allocator */ 98 # ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 99 const char *FreedFile; /* The sourcefile of the deallocator */ 100 unsigned long FreedLine; /* The sourceline of the deallocator */ 101 unsigned char Deallocator; /* The deallocator used */ 102 # endif 103 size_t Size; /* The size of the malloc'd block */ 104 struct Header *Prev; /* Previous link */ 105 struct Header *Next; /* Next link */ 106 char *Label; /* User's Label (may be null) */ 107 unsigned char Scope; /* Scope level of the owner */ 108 unsigned char Allocator; /* malloc/realloc/new/etc */ 109 # ifdef MT_SCOPES 110 unsigned short Owner; /* TID ordinal of block owner */ 111 # endif 108 112 }; 109 113 … … 153 157 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 154 158 #ifdef FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY 159 155 160 #ifdef FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY 156 161 static const char *st_DeallocatedMemoryBlockString(struct Header *h); 157 162 #endif /* FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */ 163 158 164 #endif /* FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */ 159 160 161 162 163 165 static int st_IsOnDeallocatedList(struct Header *h); 166 static int st_PurgeDeallocatedBlocks(unsigned long Bytes, const char *file, unsigned long line); 167 static int st_PurgeDeallocatedScope(unsigned char Scope, const char *file, unsigned long line); 168 static int st_CheckDeallocatedBlock(struct Header *h, const char *file, unsigned long line); 169 static void st_FreeDeallocatedBlock(struct Header *h, const char *file, unsigned long line); 164 170 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 165 171 … … 176 182 static const char *st_LastVerifiedFile = "unknown"; 177 183 static unsigned long st_LastVerifiedLine; 184 178 185 #ifdef MT_SCOPES 179 186 static unsigned volatile st_cOrdinals; // Number of known threads … … 183 190 static unsigned char st_Scope = 0; 184 191 #endif 192 185 193 static unsigned char st_Disabled = 0; 186 194 187 195 #ifdef __cplusplus 188 189 190 191 196 int FORTIFY_STORAGE gbl_FortifyMagic = 0; // 28 Jan 08 SHL 197 static const char *st_DeleteFile[FORTIFY_DELETE_STACK_SIZE]; 198 static unsigned long st_DeleteLine[FORTIFY_DELETE_STACK_SIZE]; 199 static unsigned long st_DeleteStackTop; 192 200 #endif /* __cplusplus */ 193 201 … … 203 211 204 212 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 205 206 207 213 static struct Header *st_DeallocatedHead = 0; 214 static struct Header *st_DeallocatedTail = 0; 215 static unsigned long st_TotalDeallocated = 0; 208 216 #endif 209 217 … … 212 220 static const char *st_AllocatorName[] = 213 221 { 214 215 216 217 218 219 222 "malloc()", 223 "calloc()", 224 "realloc()", 225 "strdup()", 226 "new", 227 "new[]" 220 228 }; 221 229 … … 223 231 static const char *st_DeallocatorName[] = 224 232 { 225 226 227 228 229 233 "nobody", 234 "free()", 235 "realloc()", 236 "delete", 237 "delete[]" 230 238 }; 231 239 232 240 static const unsigned char st_ValidDeallocator[] = 233 241 { 234 235 236 237 242 (1<<Fortify_Deallocator_free) | (1<<Fortify_Deallocator_realloc), 243 (1<<Fortify_Deallocator_free) | (1<<Fortify_Deallocator_realloc), 244 (1<<Fortify_Deallocator_free) | (1<<Fortify_Deallocator_realloc), 245 (1<<Fortify_Deallocator_free) | (1<<Fortify_Deallocator_realloc), 238 246 #if defined(FORTIFY_PROVIDE_ARRAY_NEW) && defined(FORTIFY_PROVIDE_ARRAY_DELETE) 239 240 247 (1<<Fortify_Deallocator_delete), 248 (1<<Fortify_Deallocator_array_delete) 241 249 #else 242 243 250 (1<<Fortify_Deallocator_delete) | (1<<Fortify_Deallocator_array_delete), 251 (1<<Fortify_Deallocator_delete) | (1<<Fortify_Deallocator_array_delete) 244 252 #endif 245 253 }; … … 252 260 Fortify_Allocate(size_t size, unsigned char allocator, const char *file, unsigned long line) 253 261 { 254 255 256 262 unsigned char *ptr; 263 struct Header *h; 264 int another_try; 257 265 258 266 #ifdef MT_SCOPES 259 267 unsigned ordinal; 260 268 #endif 261 269 262 263 264 265 266 267 # ifdef FORTIFY_FAIL_ON_ZERO_MALLOC268 if(size == 0 && (allocator == Fortify_Allocator_new269 270 /* 271 * If Fortify has been disabled, then it's easy 272 */ 273 if(st_Disabled) 274 { 275 # ifdef FORTIFY_FAIL_ON_ZERO_MALLOC 276 if(size == 0 && (allocator == Fortify_Allocator_new 277 || allocator == Fortify_Allocator_array_new)) 270 278 { 271 279 /* 272 280 * A new of zero bytes must succeed, but a malloc of 273 274 281 * zero bytes probably won't 282 */ 275 283 return malloc(1); 276 284 } 285 # endif 286 287 return malloc(size); 288 } 289 290 #ifdef FORTIFY_CHECK_ALL_MEMORY_ON_ALLOCATE 291 Fortify_CheckAllMemory(file, line); 277 292 #endif 278 293 279 return malloc(size); 280 } 281 282 #ifdef FORTIFY_CHECK_ALL_MEMORY_ON_ALLOCATE 283 Fortify_CheckAllMemory(file, line); 284 #endif 285 286 if(st_AllocateFailRate > 0) 287 { 288 if(rand() % 100 < st_AllocateFailRate) 289 { 290 #ifdef FORTIFY_WARN_ON_FALSE_FAIL 291 sprintf(st_Buffer, 292 "\nFortify: A \"%s\" of %lu bytes \"false failed\" at %s.%lu\n", 293 st_AllocatorName[allocator], (unsigned long)size, file, line); 294 st_Output(st_Buffer); 295 #endif 296 return(0); 297 } 298 } 299 300 /* Check to see if this allocation will 301 * push us over the artificial limit 302 */ 303 if(st_CurAllocation + size > st_AllocationLimit) 304 { 305 #ifdef FORTIFY_WARN_ON_FALSE_FAIL 306 sprintf(st_Buffer, 307 "\nFortify: A \"%s\" of %lu bytes \"false failed\" at %s.%lu\n", 308 st_AllocatorName[allocator], (unsigned long)size, file, line); 309 st_Output(st_Buffer); 310 #endif 311 return(0); 312 } 294 if(st_AllocateFailRate > 0) 295 { 296 if(rand() % 100 < st_AllocateFailRate) 297 { 298 # ifdef FORTIFY_WARN_ON_FALSE_FAIL 299 sprintf(st_Buffer, 300 "\nFortify: A \"%s\" of %lu bytes \"false failed\" at %s.%lu\n", 301 st_AllocatorName[allocator], (unsigned long)size, file, line); 302 st_Output(st_Buffer); 303 # endif 304 return(0); 305 } 306 } 307 308 /* Check to see if this allocation will 309 * push us over the artificial limit 310 */ 311 if(st_CurAllocation + size > st_AllocationLimit) 312 { 313 # ifdef FORTIFY_WARN_ON_FALSE_FAIL 314 sprintf(st_Buffer, 315 "\nFortify: A \"%s\" of %lu bytes \"false failed\" at %s.%lu\n", 316 st_AllocatorName[allocator], (unsigned long)size, file, line); 317 st_Output(st_Buffer); 318 # endif 319 return(0); 320 } 313 321 314 322 #ifdef FORTIFY_WARN_ON_ZERO_MALLOC 315 323 if(size == 0 && (allocator == Fortify_Allocator_malloc || 316 317 324 allocator == Fortify_Allocator_calloc || 325 allocator == Fortify_Allocator_realloc )) 318 326 { 319 327 sprintf(st_Buffer, 320 "\nFortify: A \"%s\" of 0 bytes attempted at %s.%lu\n",321 st_AllocatorName[allocator], file, line);322 st_Output(st_Buffer);328 "\nFortify: A \"%s\" of 0 bytes attempted at %s.%lu\n", 329 st_AllocatorName[allocator], file, line); 330 st_Output(st_Buffer); 323 331 } 324 332 #endif /* FORTIFY_WARN_ON_ZERO_MALLOC */ … … 326 334 #ifdef FORTIFY_FAIL_ON_ZERO_MALLOC 327 335 if(size == 0 && (allocator == Fortify_Allocator_malloc || 328 329 336 allocator == Fortify_Allocator_calloc || 337 allocator == Fortify_Allocator_realloc )) 330 338 { 331 339 #ifdef FORTIFY_WARN_ON_ALLOCATE_FAIL 332 sprintf(st_Buffer, "\nFortify: A \"%s\" of %lu bytes failed at %s.%lu\n",333 st_AllocatorName[allocator], (unsigned long)size, file, line);334 st_Output(st_Buffer);340 sprintf(st_Buffer, "\nFortify: A \"%s\" of %lu bytes failed at %s.%lu\n", 341 st_AllocatorName[allocator], (unsigned long)size, file, line); 342 st_Output(st_Buffer); 335 343 #endif /* FORTIFY_WARN_ON_ALLOCATE_FAIL */ 336 344 return 0; … … 339 347 340 348 #ifdef FORTIFY_WARN_ON_SIZE_T_OVERFLOW 341 342 343 344 345 346 349 /* 350 * Ensure the size of the memory block 351 * plus the overhead isn't bigger than 352 * size_t (that'd be a drag) 353 */ 354 { 347 355 size_t private_size = FORTIFY_HEADER_SIZE 348 356 + FORTIFY_ALIGNED_BEFORE_SIZE + size + FORTIFY_AFTER_SIZE; 349 357 350 358 if(private_size < size) 351 359 { 352 353 354 355 356 357 } 358 360 sprintf(st_Buffer, 361 "\nFortify: A \"%s\" of %lu bytes has overflowed size_t at %s.%lu\n", 362 st_AllocatorName[allocator], (unsigned long)size, file, line); 363 st_Output(st_Buffer); 364 return(0); 365 } 366 } 359 367 #endif 360 368 361 another_try = 1; 362 do 363 { 364 /* 365 * malloc the memory, including the space 366 * for the header and fortification buffers 367 */ 368 ptr = (unsigned char *)malloc( FORTIFY_HEADER_SIZE 369 + FORTIFY_ALIGNED_BEFORE_SIZE 370 + size 371 + FORTIFY_AFTER_SIZE ); 372 369 another_try = 1; 370 do 371 { 372 /* 373 * malloc the memory, including the space 374 * for the header and fortification buffers 375 */ 376 ptr = (unsigned char *)malloc( FORTIFY_HEADER_SIZE 377 + FORTIFY_ALIGNED_BEFORE_SIZE 378 + size 379 + FORTIFY_AFTER_SIZE ); 380 381 # ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 382 /* 383 * If we're tracking deallocated memory, then 384 * we can free some of it, rather than let 385 * this malloc fail 386 */ 387 if(!ptr) 388 { 389 another_try = st_PurgeDeallocatedBlocks(size, file, line); 390 } 391 # endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 392 393 } 394 while(!ptr && another_try); 395 396 if(!ptr) 397 { 398 # ifdef FORTIFY_WARN_ON_ALLOCATE_FAIL 399 sprintf(st_Buffer, "\nFortify: A \"%s\" of %lu bytes failed at %s.%lu\n", 400 st_AllocatorName[allocator], (unsigned long)size, file, line); 401 st_Output(st_Buffer); 402 # endif 403 return(0); 404 } 405 406 /* 407 * Begin Critical Region 408 */ 409 FORTIFY_LOCK(); 410 411 412 /* 413 * Make the head's prev pointer point to us 414 * ('cos we're about to become the head) 415 */ 416 if(st_AllocatedHead) 417 { 418 st_CheckBlock(st_AllocatedHead, file, line); 419 /* what should we do if this fails? (apart from panic) */ 420 421 st_AllocatedHead->Prev = (struct Header *)ptr; 422 st_MakeHeaderValid(st_AllocatedHead); 423 } 424 425 # ifdef MT_SCOPES 426 ordinal = Get_TID_Ordinal(); 427 # endif 428 429 /* 430 * Initialize and validate the header 431 */ 432 h = (struct Header *)ptr; 433 h->Size = size; 434 h->File = file; 435 h->Line = line; 436 h->Next = st_AllocatedHead; 437 h->Prev = 0; 438 # ifdef MT_SCOPES 439 h->Owner = ordinal < st_cOrdinals ? st_pOwners[ordinal] : ordinal; 440 h->Scope = h->Owner < st_cOrdinals ? st_pScopes[h->Owner] : 0; 441 # else 442 h->Scope = st_Scope; 443 # endif 444 h->Allocator = allocator; 445 h->Label = 0; 373 446 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 374 /* 375 * If we're tracking deallocated memory, then 376 * we can free some of it, rather than let 377 * this malloc fail 378 */ 379 if(!ptr) 380 { 381 another_try = st_PurgeDeallocatedBlocks(size, file, line); 382 } 447 h->FreedFile = 0; 448 h->FreedLine = 0; 449 h->Deallocator = Fortify_Deallocator_nobody; 383 450 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 384 385 } 386 while(!ptr && another_try); 387 388 if(!ptr) 389 { 390 #ifdef FORTIFY_WARN_ON_ALLOCATE_FAIL 391 sprintf(st_Buffer, "\nFortify: A \"%s\" of %lu bytes failed at %s.%lu\n", 392 st_AllocatorName[allocator], (unsigned long)size, file, line); 393 st_Output(st_Buffer); 394 #endif 395 return(0); 396 } 397 398 /* 399 * Begin Critical Region 400 */ 401 FORTIFY_LOCK(); 402 403 404 /* 405 * Make the head's prev pointer point to us 406 * ('cos we're about to become the head) 407 */ 408 if(st_AllocatedHead) 409 { 410 st_CheckBlock(st_AllocatedHead, file, line); 411 /* what should we do if this fails? (apart from panic) */ 412 413 st_AllocatedHead->Prev = (struct Header *)ptr; 414 st_MakeHeaderValid(st_AllocatedHead); 415 } 416 417 # ifdef MT_SCOPES 418 ordinal = Get_TID_Ordinal(); 419 // In case owner overridden by Fortify_SetOwner 420 if (ordinal < st_cOrdinals) 421 ordinal = st_pOwners[ordinal]; 422 # endif 423 424 /* 425 * Initialize and validate the header 426 */ 427 h = (struct Header *)ptr; 428 h->Size = size; 429 h->File = file; 430 h->Line = line; 431 h->Next = st_AllocatedHead; 432 h->Prev = 0; 433 # ifdef MT_SCOPES 434 h->Scope = ordinal < st_cOrdinals ? st_pScopes[ordinal] : 0; 435 h->Owner = ordinal; 436 # else 437 h->Scope = st_Scope; 438 # endif 439 h->Allocator = allocator; 440 h->Label = 0; 441 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 442 h->FreedFile = 0; 443 h->FreedLine = 0; 444 h->Deallocator = Fortify_Deallocator_nobody; 445 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 446 st_MakeHeaderValid(h); 447 st_AllocatedHead = h; 448 449 /* 450 * Initialize the fortifications 451 */ 452 st_SetFortification(ptr + FORTIFY_HEADER_SIZE, 453 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE); 454 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + size, 455 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE); 456 457 #ifdef FORTIFY_FILL_ON_ALLOCATE 458 /* 459 * Fill the actual user memory 460 */ 461 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 462 FORTIFY_FILL_ON_ALLOCATE_VALUE, size); 463 #endif 464 465 /* 466 * End Critical Region 467 */ 468 FORTIFY_UNLOCK(); 469 470 471 /* 472 * update the statistics 473 */ 474 st_TotalAllocation += size; 475 st_Allocations++; 476 st_CurBlocks++; 477 st_CurAllocation += size; 478 if(st_CurBlocks > st_MaxBlocks) 479 st_MaxBlocks = st_CurBlocks; 480 if(st_CurAllocation > st_MaxAllocation) 481 st_MaxAllocation = st_CurAllocation; 482 483 /* 484 * We return the address of the user's memory, not the start of the block, 485 * which points to our magic cookies 486 */ 487 return(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE); 451 st_MakeHeaderValid(h); 452 st_AllocatedHead = h; 453 454 /* 455 * Initialize the fortifications 456 */ 457 st_SetFortification(ptr + FORTIFY_HEADER_SIZE, 458 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE); 459 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + size, 460 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE); 461 462 # ifdef FORTIFY_FILL_ON_ALLOCATE 463 /* 464 * Fill the actual user memory 465 */ 466 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 467 FORTIFY_FILL_ON_ALLOCATE_VALUE, size); 468 # endif 469 470 /* 471 * End Critical Region 472 */ 473 FORTIFY_UNLOCK(); 474 475 476 /* 477 * update the statistics 478 */ 479 st_TotalAllocation += size; 480 st_Allocations++; 481 st_CurBlocks++; 482 st_CurAllocation += size; 483 if(st_CurBlocks > st_MaxBlocks) 484 st_MaxBlocks = st_CurBlocks; 485 if(st_CurAllocation > st_MaxAllocation) 486 st_MaxAllocation = st_CurAllocation; 487 488 /* 489 * We return the address of the user's memory, not the start of the block, 490 * which points to our magic cookies 491 */ 492 return(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE); 488 493 } 489 494 … … 496 501 Fortify_Deallocate(void *uptr, unsigned char deallocator, const char *file, unsigned long line) 497 502 { 498 503 unsigned char *ptr = (unsigned char *)uptr 499 504 - FORTIFY_HEADER_SIZE 500 505 - FORTIFY_ALIGNED_BEFORE_SIZE; 501 struct Header *h = (struct Header *)ptr; 506 struct Header *h = (struct Header *)ptr; 507 508 # ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 509 # ifdef MT_SCOPES 510 unsigned ordinal = Get_TID_Ordinal(); 511 # endif 512 # endif 513 514 # ifdef FORTIFY_CHECK_ALL_MEMORY_ON_DEALLOCATE 515 Fortify_CheckAllMemory(file, line); 516 # endif 517 518 /* 519 * If Fortify has been disabled, then it's easy 520 * (well, almost) 521 */ 522 if(st_Disabled) 523 { 524 /* there is a possibility that this memory 525 * block was allocated when Fortify was 526 * enabled, so we must check the Allocated 527 * list before we free it. 528 */ 529 if(!st_IsOnAllocatedList(h)) 530 { 531 free(uptr); 532 return; 533 } 534 else 535 { 536 /* the block was allocated by Fortify, so we 537 * gotta free it differently. 538 */ 539 /* 540 * Begin critical region 541 */ 542 FORTIFY_LOCK(); 543 544 /* 545 * Remove the block from the list 546 */ 547 if(h->Prev) 548 h->Prev->Next = h->Next; 549 else 550 st_AllocatedHead = h->Next; 551 552 if(h->Next) 553 h->Next->Prev = h->Prev; 554 555 /* 556 * End Critical Region 557 */ 558 FORTIFY_UNLOCK(); 559 560 /* 561 * actually free the memory 562 */ 563 free(ptr); 564 return; 565 } 566 } 567 568 569 # ifdef FORTIFY_PARANOID_DEALLOCATE 570 if(!st_IsOnAllocatedList(h)) 571 { 572 # ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 573 if(st_IsOnDeallocatedList(h)) 574 { 575 sprintf(st_Buffer, "\nFortify: \"%s\" twice of %s detected at %s.%lu\n", 576 st_DeallocatorName[deallocator], 577 st_MemoryBlockString(h), file, line); 578 st_Output(st_Buffer); 579 580 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 581 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 582 st_Output(st_Buffer); 583 st_OutputDeleteTrace(); 584 return; 585 } 586 # endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 587 588 # ifdef FORTIFY_NO_PERCENT_P 589 sprintf(st_Buffer, "\nFortify: Possible \"%s\" twice of (0x%08lx) was detected at %s.%lu\n", 590 # else 591 sprintf(st_Buffer, "\nFortify: Possible \"%s\" twice of (%p) was detected at %s.%lu\n", 592 # endif 593 st_DeallocatorName[deallocator], 594 uptr, file, line); 595 st_Output(st_Buffer); 596 st_OutputDeleteTrace(); 597 return; 598 } 599 # endif /* FORTIFY_PARANOID_DEALLOCATE */ 600 601 /* 602 * Make sure the block is okay before we free it. 603 * If it's not okay, don't free it - it might not 604 * be a real memory block. Or worse still, someone 605 * might still be writing to it 606 */ 607 if(!st_CheckBlock(h, file, line)) 608 { 609 st_OutputDeleteTrace(); 610 return; 611 } 612 613 # ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 614 /* 615 * Make sure the block hasn't been freed already 616 * (we can get to here if FORTIFY_PARANOID_DEALLOCATE 617 * is off, but FORTIFY_TRACK_DEALLOCATED_MEMORY 618 * is on). 619 */ 620 if(h->Deallocator != Fortify_Deallocator_nobody) 621 { 622 sprintf(st_Buffer, "\nFortify: \"%s\" twice of %s detected at %s.%lu\n", 623 st_DeallocatorName[deallocator], 624 st_MemoryBlockString(h), file, line); 625 st_Output(st_Buffer); 626 627 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 628 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 629 st_Output(st_Buffer); 630 st_OutputDeleteTrace(); 631 return; 632 } 633 # endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 634 635 /* 636 * Make sure the block is being freed with a valid 637 * deallocator. If not, complain. (but free it anyway) 638 */ 639 if((st_ValidDeallocator[h->Allocator] & (1<<deallocator)) == 0) 640 { 641 sprintf(st_Buffer, "\nFortify: Incorrect deallocator \"%s\" detected at %s.%lu\n", 642 st_DeallocatorName[deallocator], file, line); 643 st_Output(st_Buffer); 644 sprintf(st_Buffer, " %s was allocated with \"%s\"\n", 645 st_MemoryBlockString(h), st_AllocatorName[h->Allocator]); 646 st_Output(st_Buffer); 647 st_OutputDeleteTrace(); 648 } 649 650 /* 651 * Begin critical region 652 */ 653 FORTIFY_LOCK(); 654 655 /* 656 * Remove the block from the list 657 */ 658 if(h->Prev) 659 { 660 if(!st_CheckBlock(h->Prev, file, line)) 661 { 662 FORTIFY_UNLOCK(); 663 st_OutputDeleteTrace(); 664 return; 665 } 666 667 h->Prev->Next = h->Next; 668 st_MakeHeaderValid(h->Prev); 669 } 670 else 671 st_AllocatedHead = h->Next; 672 673 if(h->Next) 674 { 675 if(!st_CheckBlock(h->Next, file, line)) 676 { 677 FORTIFY_UNLOCK(); 678 st_OutputDeleteTrace(); 679 return; 680 } 681 682 h->Next->Prev = h->Prev; 683 st_MakeHeaderValid(h->Next); 684 } 685 686 /* 687 * End Critical Region 688 */ 689 FORTIFY_UNLOCK(); 690 691 /* 692 * update the statistics 693 */ 694 st_Frees++; 695 st_CurBlocks--; 696 st_CurAllocation -= h->Size; 502 697 503 698 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 504 699 #ifdef MT_SCOPES 505 unsigned ordinal = Get_TID_Ordinal(); 700 ordinal = Get_TID_Ordinal(); 701 if (ordinal < st_cOrdinals && st_pScopes[ordinal] > 0) 702 #else 703 if(st_Scope > 0) 506 704 #endif 507 #endif 508 509 #ifdef FORTIFY_CHECK_ALL_MEMORY_ON_DEALLOCATE 510 Fortify_CheckAllMemory(file, line); 511 #endif 512 513 /* 514 * If Fortify has been disabled, then it's easy 515 * (well, almost) 516 */ 517 if(st_Disabled) 518 { 519 /* there is a possibility that this memory 520 * block was allocated when Fortify was 521 * enabled, so we must check the Allocated 522 * list before we free it. 523 */ 524 if(!st_IsOnAllocatedList(h)) 525 { 526 free(uptr); 527 return; 705 { 706 /* 707 * Don't _actually_ free the memory block, just yet. 708 * Place it onto the deallocated list, instead, so 709 * we can check later to see if it's been written to. 710 */ 711 # ifdef FORTIFY_FILL_ON_DEALLOCATE 712 /* 713 * Nuke out all user memory that is about to be freed 714 */ 715 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 716 FORTIFY_FILL_ON_DEALLOCATE_VALUE, 717 h->Size); 718 # endif /* FORTIFY_FILL_ON_DEALLOCATE */ 719 720 /* 721 * Begin critical region 722 */ 723 FORTIFY_LOCK(); 724 725 /* 726 * Place the block on the deallocated list 727 */ 728 if(st_DeallocatedHead) 729 { 730 st_DeallocatedHead->Prev = (struct Header *)ptr; 731 st_MakeHeaderValid(st_DeallocatedHead); 732 } 733 734 h = (struct Header *)ptr; 735 h->FreedFile = file; 736 h->FreedLine = line; 737 h->Deallocator = deallocator; 738 h->Next = st_DeallocatedHead; 739 h->Prev = 0; 740 st_MakeHeaderValid(h); 741 st_DeallocatedHead = h; 742 743 if(!st_DeallocatedTail) 744 st_DeallocatedTail = h; 745 746 st_TotalDeallocated += h->Size; 747 748 # ifdef FORTIFY_DEALLOCATED_MEMORY_LIMIT 749 /* 750 * If we've got too much on the deallocated list; free some 751 */ 752 if(st_TotalDeallocated > FORTIFY_DEALLOCATED_MEMORY_LIMIT) 753 { 754 st_PurgeDeallocatedBlocks(st_TotalDeallocated - FORTIFY_DEALLOCATED_MEMORY_LIMIT, file, line); 755 } 756 # endif 757 758 /* 759 * End critical region 760 */ 761 FORTIFY_UNLOCK(); 528 762 } 529 763 else 530 { 531 /* the block was allocated by Fortify, so we 532 * gotta free it differently. 533 */ 534 /* 535 * Begin critical region 536 */ 537 FORTIFY_LOCK(); 538 539 /* 540 * Remove the block from the list 541 */ 542 if(h->Prev) 543 h->Prev->Next = h->Next; 544 else 545 st_AllocatedHead = h->Next; 546 547 if(h->Next) 548 h->Next->Prev = h->Prev; 549 550 /* 551 * End Critical Region 552 */ 553 FORTIFY_UNLOCK(); 554 555 /* 556 * actually free the memory 557 */ 558 free(ptr); 559 return; 560 } 561 } 562 563 564 #ifdef FORTIFY_PARANOID_DEALLOCATE 565 if(!st_IsOnAllocatedList(h)) 566 { 567 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 568 if(st_IsOnDeallocatedList(h)) 569 { 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; 580 } 581 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 582 583 #ifdef FORTIFY_NO_PERCENT_P 584 sprintf(st_Buffer, "\nFortify: Possible \"%s\" twice of (0x%08lx) was detected at %s.%lu\n", 585 #else 586 sprintf(st_Buffer, "\nFortify: Possible \"%s\" twice of (%p) was detected at %s.%lu\n", 587 #endif 588 st_DeallocatorName[deallocator], 589 uptr, file, line); 590 st_Output(st_Buffer); 591 st_OutputDeleteTrace(); 592 return; 593 } 594 #endif /* FORTIFY_PARANOID_DEALLOCATE */ 595 596 /* 597 * Make sure the block is okay before we free it. 598 * If it's not okay, don't free it - it might not 599 * be a real memory block. Or worse still, someone 600 * might still be writing to it 601 */ 602 if(!st_CheckBlock(h, file, line)) 603 { 604 st_OutputDeleteTrace(); 605 return; 606 } 607 608 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 609 /* 610 * Make sure the block hasn't been freed already 611 * (we can get to here if FORTIFY_PARANOID_DEALLOCATE 612 * is off, but FORTIFY_TRACK_DEALLOCATED_MEMORY 613 * is on). 614 */ 615 if(h->Deallocator != Fortify_Deallocator_nobody) 616 { 617 sprintf(st_Buffer, "\nFortify: \"%s\" twice of %s detected at %s.%lu\n", 618 st_DeallocatorName[deallocator], 619 st_MemoryBlockString(h), file, line); 620 st_Output(st_Buffer); 621 622 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 623 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 624 st_Output(st_Buffer); 625 st_OutputDeleteTrace(); 626 return; 627 } 628 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 629 630 /* 631 * Make sure the block is being freed with a valid 632 * deallocator. If not, complain. (but free it anyway) 633 */ 634 if((st_ValidDeallocator[h->Allocator] & (1<<deallocator)) == 0) 635 { 636 sprintf(st_Buffer, "\nFortify: Incorrect deallocator \"%s\" detected at %s.%lu\n", 637 st_DeallocatorName[deallocator], file, line); 638 st_Output(st_Buffer); 639 sprintf(st_Buffer, " %s was allocated with \"%s\"\n", 640 st_MemoryBlockString(h), st_AllocatorName[h->Allocator]); 641 st_Output(st_Buffer); 642 st_OutputDeleteTrace(); 643 } 644 645 /* 646 * Begin critical region 647 */ 648 FORTIFY_LOCK(); 649 650 /* 651 * Remove the block from the list 652 */ 653 if(h->Prev) 654 { 655 if(!st_CheckBlock(h->Prev, file, line)) 656 { 657 FORTIFY_UNLOCK(); 658 st_OutputDeleteTrace(); 659 return; 660 } 661 662 h->Prev->Next = h->Next; 663 st_MakeHeaderValid(h->Prev); 664 } 665 else 666 st_AllocatedHead = h->Next; 667 668 if(h->Next) 669 { 670 if(!st_CheckBlock(h->Next, file, line)) 671 { 672 FORTIFY_UNLOCK(); 673 st_OutputDeleteTrace(); 674 return; 675 } 676 677 h->Next->Prev = h->Prev; 678 st_MakeHeaderValid(h->Next); 679 } 680 681 /* 682 * End Critical Region 683 */ 684 FORTIFY_UNLOCK(); 685 686 /* 687 * update the statistics 688 */ 689 st_Frees++; 690 st_CurBlocks--; 691 st_CurAllocation -= h->Size; 692 693 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 694 #ifdef MT_SCOPES 695 ordinal = Get_TID_Ordinal(); 696 if (ordinal < st_cOrdinals && st_pScopes[ordinal] > 0) 697 #else 698 if(st_Scope > 0) 699 #endif 700 { 701 /* 702 * Don't _actually_ free the memory block, just yet. 703 * Place it onto the deallocated list, instead, so 704 * we can check later to see if it's been written to. 705 */ 706 #ifdef FORTIFY_FILL_ON_DEALLOCATE 707 /* 708 * Nuke out all user memory that is about to be freed 709 */ 710 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 711 FORTIFY_FILL_ON_DEALLOCATE_VALUE, 712 h->Size); 713 #endif /* FORTIFY_FILL_ON_DEALLOCATE */ 714 715 /* 716 * Begin critical region 717 */ 718 FORTIFY_LOCK(); 719 720 /* 721 * Place the block on the deallocated list 722 */ 723 if(st_DeallocatedHead) 724 { 725 st_DeallocatedHead->Prev = (struct Header *)ptr; 726 st_MakeHeaderValid(st_DeallocatedHead); 727 } 728 729 h = (struct Header *)ptr; 730 h->FreedFile = file; 731 h->FreedLine = line; 732 h->Deallocator = deallocator; 733 h->Next = st_DeallocatedHead; 734 h->Prev = 0; 735 st_MakeHeaderValid(h); 736 st_DeallocatedHead = h; 737 738 if(!st_DeallocatedTail) 739 st_DeallocatedTail = h; 740 741 st_TotalDeallocated += h->Size; 742 743 #ifdef FORTIFY_DEALLOCATED_MEMORY_LIMIT 744 /* 745 * If we've got too much on the deallocated list; free some 746 */ 747 if(st_TotalDeallocated > FORTIFY_DEALLOCATED_MEMORY_LIMIT) 748 { 749 st_PurgeDeallocatedBlocks(st_TotalDeallocated - FORTIFY_DEALLOCATED_MEMORY_LIMIT, file, line); 750 } 751 #endif 752 753 /* 754 * End critical region 755 */ 756 FORTIFY_UNLOCK(); 757 } 758 else 759 #endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 760 { 764 # endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 765 { 761 766 /* 762 767 * Free the User Label … … 767 772 } 768 773 769 # ifdef FORTIFY_FILL_ON_DEALLOCATE770 /*771 * Nuke out all memory that is about to be freed, including the header772 */773 st_SetFortification(ptr, FORTIFY_FILL_ON_DEALLOCATE_VALUE,774 775 # endif /* FORTIFY_FILL_ON_DEALLOCATE */776 777 /*778 * And do the actual free779 */780 free(ptr);781 774 # ifdef FORTIFY_FILL_ON_DEALLOCATE 775 /* 776 * Nuke out all memory that is about to be freed, including the header 777 */ 778 st_SetFortification(ptr, FORTIFY_FILL_ON_DEALLOCATE_VALUE, 779 FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size + FORTIFY_AFTER_SIZE); 780 # endif /* FORTIFY_FILL_ON_DEALLOCATE */ 781 782 /* 783 * And do the actual free 784 */ 785 free(ptr); 786 } 782 787 } 783 788 … … 787 792 * with a string provided by the user. This function 788 793 * takes a copy of the passed in string. 789 * The pointerMUST be one returned by a Fortify794 * The block MUST be one returned by a Fortify 790 795 * allocation function. 791 796 */ … … 796 801 { 797 802 unsigned char *ptr = (unsigned char *)uptr 798 803 - FORTIFY_HEADER_SIZE - FORTIFY_ALIGNED_BEFORE_SIZE; 799 804 struct Header *h = (struct Header *)ptr; 800 805 … … 830 835 Fortify_CheckPointer(void *uptr, const char *file, unsigned long line) 831 836 { 832 833 834 835 836 837 837 unsigned char *ptr = (unsigned char *)uptr 838 - FORTIFY_HEADER_SIZE - FORTIFY_ALIGNED_BEFORE_SIZE; 839 struct Header *h = (struct Header *)ptr; 840 int r; 841 842 if(st_Disabled) 838 843 return 1; 839 844 840 FORTIFY_LOCK(); 841 842 if(!st_IsOnAllocatedList(h)) 843 { 844 #ifdef FORTIFY_NO_PERCENT_P 845 sprintf(st_Buffer, "\nFortify: Invalid pointer (0x%08lx) detected at %s.%lu\n", 846 #else 847 sprintf(st_Buffer, "\nFortify: Invalid pointer (%p) detected at %s.%lu\n", 845 FORTIFY_LOCK(); 846 847 if(!st_IsOnAllocatedList(h)) 848 { 849 # ifdef FORTIFY_NO_PERCENT_P 850 sprintf(st_Buffer, "\nFortify: Invalid pointer (0x%08lx) detected at %s.%lu\n", 851 uptr, file, line); 852 # else 853 sprintf(st_Buffer, "\nFortify: Invalid pointer (%p) detected at %s.%lu\n", 854 uptr, file, line); 855 # endif 856 st_Output(st_Buffer); 857 FORTIFY_UNLOCK(); 858 return(0); 859 } 860 861 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 862 if(st_IsOnDeallocatedList(h)) 863 { 864 # ifdef FORTIFY_NO_PERCENT_P 865 sprintf(st_Buffer, "\nFortify: Deallocated pointer (0x%08lx) detected at %s.%lu\n", 866 uptr, file, line); 867 # else 868 sprintf(st_Buffer, "\nFortify: Deallocated pointer (%p) detected at %s.%lu\n", 869 uptr, file, line); 870 # endif 871 st_Output(st_Buffer); 872 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 873 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 874 st_Output(st_Buffer); 875 FORTIFY_UNLOCK(); 876 return(0); 877 } 848 878 #endif 849 uptr, file, line); 850 st_Output(st_Buffer);879 880 r = st_CheckBlock(h, file, line); 851 881 FORTIFY_UNLOCK(); 852 return(0); 853 } 854 855 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 856 if(st_IsOnDeallocatedList(h)) 857 { 858 #ifdef FORTIFY_NO_PERCENT_P 859 sprintf(st_Buffer, "\nFortify: Deallocated pointer (0x%08lx) detected at %s.%lu\n", 860 #else 861 sprintf(st_Buffer, "\nFortify: Deallocated pointer (%p) detected at %s.%lu\n", 862 #endif 863 uptr, file, line); 864 st_Output(st_Buffer); 865 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 866 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 867 st_Output(st_Buffer); 868 FORTIFY_UNLOCK(); 869 return(0); 870 } 871 #endif 872 873 r = st_CheckBlock(h, file, line); 874 FORTIFY_UNLOCK(); 875 return r; 882 return r; 876 883 } 877 884 … … 887 894 Fortify_SetOutputFunc(Fortify_OutputFuncPtr Output) 888 895 { 889 890 891 892 893 896 Fortify_OutputFuncPtr Old = st_Output; 897 898 st_Output = Output; 899 900 return(Old); 894 901 } 895 902 … … 905 912 Fortify_SetAllocateFailRate(int Percent) 906 913 { 907 908 909 910 911 914 int Old = st_AllocateFailRate; 915 916 st_AllocateFailRate = Percent; 917 918 return(Old); 912 919 } 913 920 … … 924 931 Fortify_CheckAllMemory(const char *file, unsigned long line) 925 932 { 926 927 928 929 930 return 0;931 932 933 934 935 936 937 938 939 if(!st_CheckBlock(curr, file, line))940 941 942 curr = curr->Next;943 944 945 946 947 948 # ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY949 950 951 952 if(!st_CheckDeallocatedBlock(curr, file, line))953 954 955 curr = curr->Next;956 957 # endif958 959 960 961 962 963 964 965 st_LastVerifiedFile = file;966 st_LastVerifiedLine = line;967 968 969 970 933 struct Header *curr = st_AllocatedHead; 934 unsigned long count = 0; 935 936 if(st_Disabled) 937 return 0; 938 939 FORTIFY_LOCK(); 940 941 /* 942 * Check the allocated memory 943 */ 944 while(curr) 945 { 946 if(!st_CheckBlock(curr, file, line)) 947 count++; 948 949 curr = curr->Next; 950 } 951 952 /* 953 * Check the deallocated memory while you're at it 954 */ 955 # ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 956 curr = st_DeallocatedHead; 957 while(curr) 958 { 959 if(!st_CheckDeallocatedBlock(curr, file, line)) 960 count++; 961 962 curr = curr->Next; 963 } 964 # endif 965 966 /* 967 * If we know where we are, and everything is cool, 968 * remember that. It might be important. 969 */ 970 if(file && count == 0) 971 { 972 st_LastVerifiedFile = file; 973 st_LastVerifiedLine = line; 974 } 975 976 FORTIFY_UNLOCK(); 977 return(count); 971 978 } 972 979 … … 980 987 { 981 988 #ifdef MT_SCOPES 982 983 984 985 986 987 // Expand arrays988 FORTIFY_LOCK();989 i = st_cOrdinals;990 c = ordinal + 1;991 st_pScopes = realloc((void*)st_pScopes, sizeof(*st_pScopes) * c);992 st_pOwners = realloc((void*)st_pOwners, sizeof(*st_pOwners) * c);993 for (; i <= ordinal; i++) {994 995 996 }997 st_cOrdinals = c;998 FORTIFY_UNLOCK();999 1000 989 unsigned ordinal = Get_TID_Ordinal(); 990 unsigned i; 991 unsigned c; 992 993 if (ordinal >= st_cOrdinals) { 994 // Expand arrays 995 FORTIFY_LOCK(); 996 i = st_cOrdinals; 997 c = ordinal + 1; 998 st_pScopes = realloc((void*)st_pScopes, sizeof(*st_pScopes) * c); 999 st_pOwners = realloc((void*)st_pOwners, sizeof(*st_pOwners) * c); 1000 for (; i <= ordinal; i++) { 1001 st_pScopes[i] = 0; // Default to scope level 0 1002 st_pOwners[i] = i; // Default block owner to self 1003 } 1004 st_cOrdinals = c; 1005 FORTIFY_UNLOCK(); 1006 } 1007 i = ++st_pScopes[ordinal]; 1001 1008 # ifdef FORTIFY_VERBOSE_SCOPE_ENTER_EXIT 1002 1003 1004 1005 1006 1009 sprintf(st_Buffer, 1010 "Fortify: Entering scope %u in TID %u at %s.%lu\n", 1011 i, ordinal, 1012 file, line); // 26 May 08 SHL 1013 st_Output(st_Buffer); 1007 1014 # endif 1008 1015 return(i); 1009 1016 #else 1010 1017 return(++st_Scope); 1011 1018 #endif 1012 1019 } … … 1020 1027 Fortify_LeaveScope(const char *file, unsigned long line) 1021 1028 { 1022 struct Header *curr = st_AllocatedHead; 1023 unsigned long size = 0, count = 0; 1024 #ifdef MT_SCOPES 1025 unsigned ordinal; 1029 struct Header *curr = st_AllocatedHead; 1030 unsigned long size = 0, count = 0; 1031 # ifdef MT_SCOPES 1032 unsigned ordinal; 1033 # endif 1034 1035 if(st_Disabled) 1036 return 0; 1037 1038 FORTIFY_LOCK(); 1039 1040 # ifdef MT_SCOPES 1041 // Complain on leave without enter 06 May 08 SHL 1042 ordinal = Get_TID_Ordinal(); 1043 if (ordinal < st_cOrdinals && st_pScopes[ordinal] > 0) { 1044 st_pScopes[ordinal]--; 1045 } 1046 else { 1047 sprintf(st_Buffer, 1048 "\nFortify: Attempting to leave scope before enter in TID %u at %s.%lu\n", 1049 ordinal, file, line); // 26 May 08 SHL 1050 st_Output(st_Buffer); 1051 } 1052 # else 1053 if (st_Scope > 0) 1054 st_Scope--; 1055 else { 1056 sprintf(st_Buffer, "\nFortify: Attempting to leave scope before enter at %s.%lu\n", file, line); 1057 st_Output(st_Buffer); 1058 } 1026 1059 #endif 1027 1028 if(st_Disabled) 1029 return 0; 1030 1031 FORTIFY_LOCK(); 1032 1033 #ifdef MT_SCOPES 1034 // Complain on leave without enter 06 May 08 SHL 1035 ordinal = Get_TID_Ordinal(); 1036 if (ordinal < st_cOrdinals && st_pScopes[ordinal] > 0) { 1037 st_pScopes[ordinal]--; 1038 } 1039 else { 1040 sprintf(st_Buffer, 1041 "\nFortify: Attempting to leave scope before enter in TID %u at %s.%lu\n", 1042 ordinal, file, line); // 26 May 08 SHL 1043 st_Output(st_Buffer); 1044 } 1045 #else 1046 if (st_Scope > 0) 1047 st_Scope--; 1048 else { 1049 sprintf(st_Buffer, "\nFortify: Attempting to leave scope before enter at %s.%lu\n", file, line); 1050 st_Output(st_Buffer); 1051 } 1052 #endif 1053 while(curr) 1054 { 1055 #ifdef MT_SCOPES 1056 if(curr->Owner == ordinal && ordinal < st_cOrdinals && curr->Scope > st_pScopes[ordinal]) 1057 #else 1058 if(curr->Scope > st_Scope) 1059 #endif 1060 { 1061 if(count == 0) 1062 { 1063 // Report just first occurrance 1064 #ifdef MT_SCOPES 1060 while(curr) 1061 { 1062 # ifdef MT_SCOPES 1063 if(curr->Owner == ordinal && ordinal < st_cOrdinals && curr->Scope > st_pScopes[ordinal]) 1064 # else 1065 if(curr->Scope > st_Scope) 1066 # endif 1067 { 1068 if(count == 0) 1069 { 1070 // Output leak report and header just once 1071 # ifdef MT_SCOPES 1072 sprintf(st_Buffer, 1073 "\nFortify: Memory leak detected leaving scope %d in TID %u at %s.%lu\n", 1074 ordinal < st_cOrdinals ? st_pScopes[ordinal] + 1 : 0, 1075 ordinal, 1076 file, line); 1077 # else // not MT_SCOPES 1078 sprintf(st_Buffer, "\nFortify: Memory leak detected leaving scope at %s.%lu\n", file, line); 1079 # endif 1080 st_Output(st_Buffer); 1081 sprintf(st_Buffer, "%10s %8s %s\n", "Address", "Size", "Allocator"); 1082 st_Output(st_Buffer); 1083 } 1084 1085 st_OutputHeader(curr); 1086 count++; 1087 size += curr->Size; 1088 } 1089 1090 curr = curr->Next; 1091 } // while 1092 1093 if(count) 1094 { 1095 sprintf(st_Buffer,"%10s %8lu bytes in %lu blocks with %lu bytes overhead\n", 1096 "total", size, count, count * FORTIFY_OVERHEAD); 1097 st_Output(st_Buffer); 1098 } 1099 # ifdef FORTIFY_VERBOSE_SCOPE_ENTER_EXIT 1100 else { 1065 1101 sprintf(st_Buffer, 1066 "\nFortify: Memory leak detected leaving scope %d in TID %u at %s.%lu\n", 1067 ordinal < st_cOrdinals ? st_pScopes[ordinal] + 1 : 0, 1068 ordinal, 1069 file, line); 1070 #else 1071 sprintf(st_Buffer, "\nFortify: Memory leak detected leaving scope at %s.%lu\n", file, line); 1072 #endif 1073 st_Output(st_Buffer); 1074 sprintf(st_Buffer, "%10s %8s %s\n", "Address", "Size", "Allocator"); 1075 st_Output(st_Buffer); 1076 } 1077 1078 st_OutputHeader(curr); 1079 count++; 1080 size += curr->Size; 1081 } 1082 1083 curr = curr->Next; 1084 } 1085 1086 if(count) 1087 { 1088 sprintf(st_Buffer,"%10s %8lu bytes in %lu blocks with %lu bytes overhead\n", 1089 "total", size, count, count * FORTIFY_OVERHEAD); 1090 st_Output(st_Buffer); 1091 } 1092 # ifdef FORTIFY_VERBOSE_SCOPE_ENTER_EXIT 1093 else { 1094 sprintf(st_Buffer, 1095 "Fortify: Leaving scope %u in TID %u at %s.%lu\n", 1096 ordinal < st_cOrdinals ? st_pScopes[ordinal] + 1 : 0, 1097 ordinal, 1098 file, line); // 26 May 08 SHL 1099 st_Output(st_Buffer); 1100 } 1102 "Fortify: Leaving scope %u in TID %u at %s.%lu\n", 1103 ordinal < st_cOrdinals ? st_pScopes[ordinal] + 1 : 0, 1104 ordinal, 1105 file, line); // 26 May 08 SHL 1106 st_Output(st_Buffer); 1107 } 1101 1108 # endif 1102 1109 1103 # ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY1104 1105 1106 1107 1108 1109 # ifdef MT_SCOPES1110 1111 1112 # else1113 1114 # endif1115 # endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */1116 1117 1118 # ifdef MT_SCOPES1119 1120 # else1121 1122 # endif1110 # ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 1111 /* 1112 * Quietly free all the deallocated memory 1113 * that was allocated in this scope that 1114 * we are still tracking 1115 */ 1116 # ifdef MT_SCOPES 1117 st_PurgeDeallocatedScope( ordinal < st_cOrdinals ? st_pScopes[ordinal] : 0, 1118 file, line ); 1119 # else 1120 st_PurgeDeallocatedScope( st_Scope, file, line ); 1121 # endif 1122 # endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 1123 1124 FORTIFY_UNLOCK(); 1125 # ifdef MT_SCOPES 1126 return(ordinal < st_cOrdinals ? st_pScopes[ordinal] : 0); 1127 # else 1128 return(st_Scope); 1129 # endif 1123 1130 } 1124 1131 … … 1139 1146 Fortify_ListAllMemory(const char *file, unsigned long line) 1140 1147 { 1141 1142 1143 1144 1145 return 0;1146 1147 1148 1149 1150 1151 1152 1153 sprintf(st_Buffer, "\nFortify: Memory List at %s.%lu\n", file, line);1154 st_Output(st_Buffer);1155 sprintf(st_Buffer, "%10s %8s %s\n", "Address", "Size", "Allocator");1156 st_Output(st_Buffer);1157 1158 while(curr)1159 {1160 1161 1162 1163 1164 }1165 1166 sprintf(st_Buffer, "%10s %8lu bytes in %lu blocks and %lu bytes overhead\n",1167 1168 st_Output(st_Buffer);1169 1170 1171 1172 1148 struct Header *curr = st_AllocatedHead; 1149 unsigned long size = 0, count = 0; 1150 1151 if(st_Disabled) 1152 return 0; 1153 1154 Fortify_CheckAllMemory(file, line); 1155 1156 FORTIFY_LOCK(); 1157 1158 if(curr) 1159 { 1160 sprintf(st_Buffer, "\nFortify: Memory List at %s.%lu\n", file, line); 1161 st_Output(st_Buffer); 1162 sprintf(st_Buffer, "%10s %8s %s\n", "Address", "Size", "Allocator"); 1163 st_Output(st_Buffer); 1164 1165 while(curr) 1166 { 1167 st_OutputHeader(curr); 1168 count++; 1169 size += curr->Size; 1170 curr = curr->Next; 1171 } 1172 1173 sprintf(st_Buffer, "%10s %8lu bytes in %lu blocks and %lu bytes overhead\n", 1174 "total", size, count, count * FORTIFY_OVERHEAD); 1175 st_Output(st_Buffer); 1176 } 1177 1178 FORTIFY_UNLOCK(); 1179 return(count); 1173 1180 } 1174 1181 … … 1185 1192 Fortify_DumpAllMemory(const char *file, unsigned long line) 1186 1193 { 1187 1188 1189 1190 1191 return 0;1192 1193 1194 1195 1196 1197 1198 1199 sprintf(st_Buffer, "\nFortify: Hex Dump of %s at %s.%lu\n",1200 st_MemoryBlockString(curr), file, line);1201 st_Output(st_Buffer);1202 st_OutputMemory(curr);1203 st_Output("\n");1204 count++;1205 1206 curr = curr->Next;1207 1208 1209 1210 1194 struct Header *curr = st_AllocatedHead; 1195 unsigned long count = 0; 1196 1197 if(st_Disabled) 1198 return 0; 1199 1200 Fortify_CheckAllMemory(file, line); 1201 1202 FORTIFY_LOCK(); 1203 1204 while(curr) 1205 { 1206 sprintf(st_Buffer, "\nFortify: Hex Dump of %s at %s.%lu\n", 1207 st_MemoryBlockString(curr), file, line); 1208 st_Output(st_Buffer); 1209 st_OutputMemory(curr); 1210 st_Output("\n"); 1211 count++; 1212 1213 curr = curr->Next; 1214 } 1215 1216 FORTIFY_UNLOCK(); 1217 return(count); 1211 1218 } 1212 1219 … … 1218 1225 Fortify_OutputStatistics(const char *file, unsigned long line) 1219 1226 { 1220 1221 return;1222 1223 1224 1225 1226 1227 if(st_Disabled) 1228 return; 1229 1230 sprintf(st_Buffer, "\nFortify: Statistics at %s.%lu\n", file, line); 1231 st_Output(st_Buffer); 1232 1233 sprintf(st_Buffer, " Memory currently allocated: %lu bytes in %lu blocks\n", 1227 1234 st_CurAllocation, st_CurBlocks); 1228 1229 1235 st_Output(st_Buffer); 1236 sprintf(st_Buffer, " Maximum memory allocated at one time: %lu bytes in %lu blocks\n", 1230 1237 st_MaxAllocation, st_MaxBlocks); 1231 1232 1238 st_Output(st_Buffer); 1239 sprintf(st_Buffer, " There have been %lu allocations and %lu deallocations\n", 1233 1240 st_Allocations, st_Frees); 1234 1235 1241 st_Output(st_Buffer); 1242 sprintf(st_Buffer, " There was a total of %lu bytes allocated\n", 1236 1243 st_TotalAllocation); 1237 st_Output(st_Buffer);1238 1239 if(st_Allocations > 0)1240 {1241 sprintf(st_Buffer, " The average allocation was %lu bytes\n",1242 st_TotalAllocation / st_Allocations);1243 1244 st_Output(st_Buffer); 1244 } 1245 1246 if(st_Allocations > 0) 1247 { 1248 sprintf(st_Buffer, " The average allocation was %lu bytes\n", 1249 st_TotalAllocation / st_Allocations); 1250 st_Output(st_Buffer); 1251 } 1245 1252 } 1246 1253 … … 1251 1258 Fortify_GetCurrentAllocation(const char *file, unsigned long line) 1252 1259 { 1253 1254 return 0;1255 1256 1260 if(st_Disabled) 1261 return 0; 1262 1263 return st_CurAllocation; 1257 1264 } 1258 1265 … … 1263 1270 Fortify_SetAllocationLimit(unsigned long NewLimit, const char *file, unsigned long line) 1264 1271 { 1265 1272 st_AllocationLimit = NewLimit; 1266 1273 } 1267 1274 … … 1281 1288 Fortify_Disable(const char *file, unsigned long line) 1282 1289 { 1283 # ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY1284 1285 1286 # endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */1287 1288 1290 # ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 1291 /* free all deallocated memory we might be tracking */ 1292 st_PurgeDeallocatedScope( 0, file, line ); 1293 # endif /* FORTIFY_TRACK_DEALLOCATED_MEMORY */ 1294 1295 st_Disabled = 1; 1289 1296 } 1290 1297 … … 1298 1305 st_CheckBlock(struct Header *h, const char *file, unsigned long line) 1299 1306 { 1300 unsigned char *ptr = (unsigned char *)h; 1301 int result = 1; 1302 1303 if(!st_IsHeaderValid(h)) 1304 { 1305 sprintf(st_Buffer, 1306 #ifdef FORTIFY_NO_PERCENT_P 1307 "\nFortify: Invalid pointer (0x%08lx) or corrupted header detected at %s.%lu\n", 1308 #else 1309 "\nFortify: Invalid pointer (%p) or corrupted header detected at %s.%lu\n", 1310 #endif 1311 ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, file, line); 1312 st_Output(st_Buffer); 1313 st_OutputLastVerifiedPoint(); 1314 return(0); 1315 } 1316 1317 if(!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE, 1307 unsigned char *ptr = (unsigned char *)h; 1308 int result = 1; 1309 1310 if(!st_IsHeaderValid(h)) 1311 { 1312 # ifdef FORTIFY_NO_PERCENT_P 1313 sprintf(st_Buffer, 1314 "\nFortify: Invalid pointer (0x%08lx) or corrupted header detected at %s.%lu\n", 1315 ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, file, line); 1316 # else 1317 sprintf(st_Buffer, 1318 "\nFortify: Invalid pointer (%p) or corrupted header detected at %s.%lu\n", 1319 ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, file, line); 1320 # endif 1321 st_Output(st_Buffer); 1322 st_OutputLastVerifiedPoint(); 1323 return(0); 1324 } 1325 1326 if(!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE, 1318 1327 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE)) 1319 1320 sprintf(st_Buffer, "\nFortify: Underwrite detected before block %s at %s.%lu\n",1321 1322 st_Output(st_Buffer);1323 1324 st_OutputLastVerifiedPoint();1325 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE,1326 1327 result = 0;1328 1329 # ifdef FORTIFY_FILL_ON_CORRUPTION1330 st_SetFortification(ptr + FORTIFY_HEADER_SIZE, FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE);1331 # endif1332 1333 1334 1328 { 1329 sprintf(st_Buffer, "\nFortify: Underwrite detected before block %s at %s.%lu\n", 1330 st_MemoryBlockString(h), file, line); 1331 st_Output(st_Buffer); 1332 1333 st_OutputLastVerifiedPoint(); 1334 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE, 1335 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE); 1336 result = 0; 1337 1338 # ifdef FORTIFY_FILL_ON_CORRUPTION 1339 st_SetFortification(ptr + FORTIFY_HEADER_SIZE, FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE); 1340 # endif 1341 } 1342 1343 if(!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size, 1335 1344 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE)) 1336 1337 sprintf(st_Buffer, "\nFortify: Overwrite detected after block %s at %s.%lu\n",1338 1339 st_Output(st_Buffer);1340 1341 st_OutputLastVerifiedPoint();1342 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,1343 1344 result = 0;1345 1346 # ifdef FORTIFY_FILL_ON_CORRUPTION1347 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,1348 1349 # endif1350 1351 1352 1345 { 1346 sprintf(st_Buffer, "\nFortify: Overwrite detected after block %s at %s.%lu\n", 1347 st_MemoryBlockString(h), file, line); 1348 st_Output(st_Buffer); 1349 1350 st_OutputLastVerifiedPoint(); 1351 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size, 1352 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE); 1353 result = 0; 1354 1355 # ifdef FORTIFY_FILL_ON_CORRUPTION 1356 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size, 1357 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE); 1358 # endif 1359 } 1360 1361 return(result); 1353 1362 } 1354 1363 … … 1362 1371 st_CheckDeallocatedBlock(struct Header *h, const char *file, unsigned long line) 1363 1372 { 1364 unsigned char *ptr = (unsigned char *)h; 1365 int result = 1; 1366 1367 if(!st_IsHeaderValid(h)) 1368 { 1369 sprintf(st_Buffer, 1373 unsigned char *ptr = (unsigned char *)h; 1374 int result = 1; 1375 1376 if(!st_IsHeaderValid(h)) 1377 { 1370 1378 #ifdef FORTIFY_NO_PERCENT_P 1371 "\nFortify: Invalid deallocated pointer (0x%08lx) or corrupted header detected at %s.%lu\n", 1379 sprintf(st_Buffer, 1380 "\nFortify: Invalid deallocated pointer (0x%08lx) or corrupted header detected at %s.%lu\n", 1381 ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, file, line); 1372 1382 #else 1373 "\nFortify: Invalid deallocated pointer (%p) or corrupted header detected at %s.%lu\n", 1383 sprintf(st_Buffer, 1384 "\nFortify: Invalid deallocated pointer (%p) or corrupted header detected at %s.%lu\n", 1385 ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, file, line); 1374 1386 #endif 1375 ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, file, line); 1376 st_Output(st_Buffer); 1377 st_OutputLastVerifiedPoint(); 1378 return(0); 1379 } 1380 1381 if(!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE, 1382 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE)) 1383 { 1384 sprintf(st_Buffer, "\nFortify: Underwrite detected before deallocated block %s at %s.%lu\n", 1385 st_MemoryBlockString(h), file, line); 1386 st_Output(st_Buffer); 1387 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 1388 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 1389 st_Output(st_Buffer); 1390 1391 st_OutputLastVerifiedPoint(); 1392 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE, 1393 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE); 1394 1395 #ifdef FORTIFY_FILL_ON_CORRUPTION 1396 st_SetFortification(ptr + FORTIFY_HEADER_SIZE, FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE); 1397 #endif 1398 result = 0; 1399 } 1400 1401 if(!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size, 1387 st_Output(st_Buffer); 1388 st_OutputLastVerifiedPoint(); 1389 return(0); 1390 } 1391 1392 if(!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE, 1393 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE)) 1394 { 1395 sprintf(st_Buffer, "\nFortify: Underwrite detected before deallocated block %s at %s.%lu\n", 1396 st_MemoryBlockString(h), file, line); 1397 st_Output(st_Buffer); 1398 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 1399 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 1400 st_Output(st_Buffer); 1401 1402 st_OutputLastVerifiedPoint(); 1403 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE, 1404 FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE); 1405 1406 # ifdef FORTIFY_FILL_ON_CORRUPTION 1407 st_SetFortification(ptr + FORTIFY_HEADER_SIZE, FORTIFY_BEFORE_VALUE, FORTIFY_ALIGNED_BEFORE_SIZE); 1408 # endif 1409 result = 0; 1410 } 1411 1412 if(!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size, 1402 1413 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE)) 1403 1404 sprintf(st_Buffer, "\nFortify: Overwrite detected after deallocated block %s at %s.%lu\n",1405 1406 st_Output(st_Buffer);1407 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n",1408 1409 st_Output(st_Buffer);1410 1411 st_OutputLastVerifiedPoint();1412 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,1413 1414 1415 # ifdef FORTIFY_FILL_ON_CORRUPTION1416 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size,1417 1418 # endif1419 result = 0;1420 1414 { 1415 sprintf(st_Buffer, "\nFortify: Overwrite detected after deallocated block %s at %s.%lu\n", 1416 st_MemoryBlockString(h), file, line); 1417 st_Output(st_Buffer); 1418 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 1419 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 1420 st_Output(st_Buffer); 1421 1422 st_OutputLastVerifiedPoint(); 1423 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size, 1424 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE); 1425 1426 # ifdef FORTIFY_FILL_ON_CORRUPTION 1427 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size, 1428 FORTIFY_AFTER_VALUE, FORTIFY_AFTER_SIZE); 1429 # endif 1430 result = 0; 1431 } 1421 1432 1422 1433 #ifdef FORTIFY_FILL_ON_DEALLOCATE 1423 1434 if(!st_CheckFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1424 1435 FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size)) 1425 1426 sprintf(st_Buffer, "\nFortify: Write to deallocated block %s detected at %s.%lu\n",1427 1428 st_Output(st_Buffer);1429 1430 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n",1431 1432 st_Output(st_Buffer);1433 st_OutputLastVerifiedPoint();1434 1435 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,1436 1437 1438 # ifdef FORTIFY_FILL_ON_CORRUPTION1439 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,1440 1441 # endif /* FORTIFY_FILL_ON_CORRUPTION */1442 result = 0;1443 1436 { 1437 sprintf(st_Buffer, "\nFortify: Write to deallocated block %s detected at %s.%lu\n", 1438 st_MemoryBlockString(h), file, line); 1439 st_Output(st_Buffer); 1440 1441 sprintf(st_Buffer, " Memory block was deallocated by \"%s\" at %s.%lu\n", 1442 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 1443 st_Output(st_Buffer); 1444 st_OutputLastVerifiedPoint(); 1445 1446 st_OutputFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1447 FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size); 1448 1449 # ifdef FORTIFY_FILL_ON_CORRUPTION 1450 st_SetFortification(ptr + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1451 FORTIFY_FILL_ON_DEALLOCATE_VALUE, h->Size); 1452 # endif /* FORTIFY_FILL_ON_CORRUPTION */ 1453 result = 0; 1454 } 1444 1455 #endif /* FORTIFY_FILL_ON_DEALLOCATE */ 1445 1456 return result; 1446 1457 } 1447 1458 … … 1457 1468 st_CheckFortification(unsigned char *ptr, unsigned char value, size_t size) 1458 1469 { 1459 1470 while(size--) 1460 1471 if(*ptr++ != value) 1461 1462 1463 1472 return(0); 1473 1474 return(1); 1464 1475 } 1465 1476 … … 1470 1481 st_SetFortification(unsigned char *ptr, unsigned char value, size_t size) 1471 1482 { 1472 1483 memset(ptr, value, size); 1473 1484 } 1474 1485 … … 1479 1490 st_OutputFortification(unsigned char *ptr, unsigned char value, size_t size) 1480 1491 { 1481 size_t offset, skipped, advance; 1482 offset = 0; 1483 1484 sprintf(st_Buffer, " Address Offset Data (%02x)", value); 1485 st_Output(st_Buffer); 1486 1487 while(offset < size) 1488 { 1489 /* 1490 * Skip 3 or more 'correct' lines 1491 */ 1492 if((size - offset) < 3 * 16) 1493 advance = size - offset; 1494 else 1495 advance = 3 * 16; 1496 if(advance > 0 && st_CheckFortification(ptr+offset, value, advance)) 1497 { 1498 offset += advance; 1499 skipped = advance; 1500 1501 if(size - offset < 16) 1502 advance = size - offset; 1503 else 1504 advance = 16; 1505 1506 while(advance > 0 && st_CheckFortification(ptr+offset, value, advance)) 1507 { 1508 offset += advance; 1509 skipped += advance; 1510 if(size - offset < 16) 1511 advance = size - offset; 1492 size_t offset, skipped, advance; 1493 offset = 0; 1494 1495 sprintf(st_Buffer, " Address Offset Data (%02x)", value); 1496 st_Output(st_Buffer); 1497 1498 while(offset < size) 1499 { 1500 /* 1501 * Skip 3 or more 'correct' lines 1502 */ 1503 if((size - offset) < 3 * 16) 1504 advance = size - offset; 1512 1505 else 1513 advance = 16; 1514 } 1515 sprintf(st_Buffer, "\n ...%lu bytes skipped...", (unsigned long)skipped); 1516 st_Output(st_Buffer); 1517 continue; 1518 } 1519 else 1520 { 1521 if(size - offset < 16) 1522 st_HexDump(ptr, offset, size-offset, 0); 1523 else 1524 st_HexDump(ptr, offset, 16, 0); 1525 1526 offset += 16; 1527 } 1528 } 1529 1530 st_Output("\n"); 1506 advance = 3 * 16; 1507 if(advance > 0 && st_CheckFortification(ptr+offset, value, advance)) 1508 { 1509 offset += advance; 1510 skipped = advance; 1511 1512 if(size - offset < 16) 1513 advance = size - offset; 1514 else 1515 advance = 16; 1516 1517 while(advance > 0 && st_CheckFortification(ptr+offset, value, advance)) 1518 { 1519 offset += advance; 1520 skipped += advance; 1521 if(size - offset < 16) 1522 advance = size - offset; 1523 else 1524 advance = 16; 1525 } 1526 sprintf(st_Buffer, "\n ...%lu bytes skipped...", (unsigned long)skipped); 1527 st_Output(st_Buffer); 1528 continue; 1529 } 1530 else 1531 { 1532 if(size - offset < 16) 1533 st_HexDump(ptr, offset, size-offset, 0); 1534 else 1535 st_HexDump(ptr, offset, 16, 0); 1536 1537 offset += 16; 1538 } 1539 } 1540 1541 st_Output("\n"); 1531 1542 } 1532 1543 … … 1537 1548 st_HexDump(unsigned char *ptr, size_t offset, size_t size, int title) 1538 1549 { 1539 1540 1541 1542 1543 1550 char ascii[17]; 1551 int column; 1552 int output; 1553 1554 if(title) 1544 1555 st_Output(" Address Offset Data"); 1545 1556 1546 1547 1548 1549 1550 1551 1552 if(column == 0)1553 {1554 # ifdef FORTIFY_NO_PERCENT_P1555 1556 # else1557 1558 # endif1559 1560 }1561 1562 sprintf(st_Buffer, "%02x%s", *ptr, ((column % 4) == 3) ? " " : "");1563 st_Output(st_Buffer);1564 1565 ascii[ column ] = isprint( *ptr ) ? (char)(*ptr) : (char)('.');1566 ascii[ column + 1 ] = '\0';1567 1568 ptr++;1569 offset++;1570 output++;1571 column++;1572 1573 if(column == 16)1574 {1575 1576 1577 1578 1579 }1580 1581 1582 1583 1584 while ( column < 16 )1585 {1586 1587 st_Output( " " );1588 1589 st_Output( " " );1590 1591 1592 }1593 st_Output( " \"" );1594 st_Output( ascii );1595 st_Output( "\"" );1596 1557 column = 0; 1558 ptr += offset; 1559 output = 0; 1560 1561 while(output < size) 1562 { 1563 if(column == 0) 1564 { 1565 # ifdef FORTIFY_NO_PERCENT_P 1566 sprintf(st_Buffer, "\n0x%08lx %8lu ", ptr, (unsigned long)offset); 1567 # else 1568 sprintf(st_Buffer, "\n%10p %8lu ", ptr, (unsigned long)offset); 1569 # endif 1570 st_Output(st_Buffer); 1571 } 1572 1573 sprintf(st_Buffer, "%02x%s", *ptr, ((column % 4) == 3) ? " " : ""); 1574 st_Output(st_Buffer); 1575 1576 ascii[ column ] = isprint( *ptr ) ? (char)(*ptr) : (char)('.'); 1577 ascii[ column + 1 ] = '\0'; 1578 1579 ptr++; 1580 offset++; 1581 output++; 1582 column++; 1583 1584 if(column == 16) 1585 { 1586 st_Output( " \"" ); 1587 st_Output( ascii ); 1588 st_Output( "\"" ); 1589 column = 0; 1590 } 1591 } 1592 1593 if ( column != 0 ) 1594 { 1595 while ( column < 16 ) 1596 { 1597 if( column % 4 == 3 ) 1598 st_Output( " " ); 1599 else 1600 st_Output( " " ); 1601 1602 column++; 1603 } 1604 st_Output( " \"" ); 1605 st_Output( ascii ); 1606 st_Output( "\"" ); 1607 } 1597 1608 } 1598 1609 … … 1605 1616 st_IsHeaderValid(struct Header *h) 1606 1617 { 1607 1618 return(st_ChecksumHeader(h) == FORTIFY_CHECKSUM_VALUE); 1608 1619 } 1609 1620 … … 1615 1626 st_MakeHeaderValid(struct Header *h) 1616 1627 { 1617 1618 1628 h->Checksum = 0; 1629 h->Checksum = (unsigned short)(FORTIFY_CHECKSUM_VALUE - st_ChecksumHeader(h)); 1619 1630 } 1620 1631 … … 1629 1640 st_ChecksumHeader(struct Header *h) 1630 1641 { 1631 1632 1633 1634 c < FORTIFY_HEADER_SIZE/sizeof(unsigned short); c++)1635 1636 checksum += *p++;1637 1638 1639 1642 unsigned short c, checksum, *p; 1643 1644 for(c = 0, checksum = 0, p = (unsigned short *)h; 1645 c < FORTIFY_HEADER_SIZE/sizeof(unsigned short); c++) 1646 { 1647 checksum += *p++; 1648 } 1649 1650 return(checksum); 1640 1651 } 1641 1652 … … 1647 1658 st_IsOnAllocatedList(struct Header *h) 1648 1659 { 1649 1650 1651 1652 1653 1654 if(curr == h)1655 1656 1657 curr = curr->Next;1658 1659 1660 1660 struct Header *curr; 1661 1662 curr = st_AllocatedHead; 1663 while(curr) 1664 { 1665 if(curr == h) 1666 return(1); 1667 1668 curr = curr->Next; 1669 } 1670 1671 return(0); 1661 1672 } 1662 1673 … … 1669 1680 st_IsOnDeallocatedList(struct Header *h) 1670 1681 { 1671 1672 1673 1674 1675 1676 if(curr == h)1677 1678 1679 curr = curr->Next;1680 1681 1682 1682 struct Header *curr; 1683 1684 curr = st_DeallocatedHead; 1685 while(curr) 1686 { 1687 if(curr == h) 1688 return(1); 1689 1690 curr = curr->Next; 1691 } 1692 1693 return(0); 1683 1694 } 1684 1695 … … 1692 1703 st_PurgeDeallocatedBlocks(unsigned long Bytes, const char *file, unsigned long line) 1693 1704 { 1694 unsigned long FreedBytes = 0; 1695 unsigned long FreedBlocks = 0; 1696 1697 #ifdef FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY 1698 sprintf(st_Buffer, "\nFortify: Warning - Discarding deallocated memory at %s.%lu\n", 1699 file, line); 1700 st_Output(st_Buffer); 1701 #endif /* FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */ 1702 1703 while(st_DeallocatedTail && FreedBytes < Bytes) 1704 { 1705 st_CheckDeallocatedBlock(st_DeallocatedTail, file, line); 1706 FreedBytes += st_DeallocatedTail->Size; 1707 FreedBlocks++; 1708 #ifdef FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY 1709 #ifdef FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY 1710 sprintf(st_Buffer, " %s\n", 1711 st_DeallocatedMemoryBlockString(st_DeallocatedTail)); 1705 unsigned long FreedBytes = 0; 1706 unsigned long FreedBlocks = 0; 1707 1708 # ifdef FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY 1709 sprintf(st_Buffer, "\nFortify: Warning - Discarding deallocated memory at %s.%lu\n", 1710 file, line); 1712 1711 st_Output(st_Buffer); 1713 #endif /* FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */ 1714 #endif /* FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */ 1715 st_FreeDeallocatedBlock(st_DeallocatedTail, file, line); 1716 } 1717 1718 return FreedBlocks != 0; 1712 # endif /* FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */ 1713 1714 while(st_DeallocatedTail && FreedBytes < Bytes) 1715 { 1716 st_CheckDeallocatedBlock(st_DeallocatedTail, file, line); 1717 FreedBytes += st_DeallocatedTail->Size; 1718 FreedBlocks++; 1719 # ifdef FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY 1720 # ifdef FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY 1721 sprintf(st_Buffer, " %s\n", 1722 st_DeallocatedMemoryBlockString(st_DeallocatedTail)); 1723 st_Output(st_Buffer); 1724 # endif /* FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */ 1725 # endif /* FORTIFY_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */ 1726 st_FreeDeallocatedBlock(st_DeallocatedTail, file, line); 1727 } 1728 1729 return FreedBlocks != 0; 1719 1730 } 1720 1731 … … 1726 1737 st_PurgeDeallocatedScope(unsigned char Scope, const char *file, unsigned long line) 1727 1738 { 1728 1729 1730 # ifdef MT_SCOPES1731 1732 # endif1733 1734 1735 1736 1737 next = curr->Next;1738 # ifdef MT_SCOPES1739 if(curr->Owner == ordinal && curr->Scope >= Scope)1740 # else1741 if(curr->Scope >= Scope)1742 # endif1743 {1744 1745 1746 }1747 1748 curr = next;1749 1750 1751 1739 struct Header *curr, *next; 1740 unsigned long FreedBlocks = 0; 1741 # ifdef MT_SCOPES 1742 unsigned ordinal = Get_TID_Ordinal(); 1743 # endif 1744 1745 curr = st_DeallocatedHead; 1746 while(curr) 1747 { 1748 next = curr->Next; 1749 # ifdef MT_SCOPES 1750 if(curr->Owner == ordinal && curr->Scope >= Scope) 1751 # else 1752 if(curr->Scope >= Scope) 1753 # endif 1754 { 1755 st_FreeDeallocatedBlock(curr, file, line); 1756 FreedBlocks++; 1757 } 1758 1759 curr = next; 1760 } 1761 1762 return FreedBlocks != 0; 1752 1763 } 1753 1764 … … 1760 1771 st_FreeDeallocatedBlock(struct Header *h, const char *file, unsigned long line) 1761 1772 { 1762 1773 st_CheckDeallocatedBlock( h, file, line ); 1763 1774 1764 1775 /* 1765 1766 1767 1768 1769 1770 1771 1772 1773 st_DeallocatedHead = h->Next;1774 1775 1776 1777 1778 st_DeallocatedTail = h->Prev;1779 1780 1781 1782 1783 st_CheckDeallocatedBlock(h->Prev, file, line);1784 h->Prev->Next = h->Next;1785 st_MakeHeaderValid(h->Prev);1786 1787 1788 1789 1790 st_CheckDeallocatedBlock(h->Next, file, line);1791 h->Next->Prev = h->Prev;1792 st_MakeHeaderValid(h->Next);1793 1776 * Begin Critical region 1777 */ 1778 FORTIFY_LOCK(); 1779 1780 st_TotalDeallocated -= h->Size; 1781 1782 if(st_DeallocatedHead == h) 1783 { 1784 st_DeallocatedHead = h->Next; 1785 } 1786 1787 if(st_DeallocatedTail == h) 1788 { 1789 st_DeallocatedTail = h->Prev; 1790 } 1791 1792 if(h->Prev) 1793 { 1794 st_CheckDeallocatedBlock(h->Prev, file, line); 1795 h->Prev->Next = h->Next; 1796 st_MakeHeaderValid(h->Prev); 1797 } 1798 1799 if(h->Next) 1800 { 1801 st_CheckDeallocatedBlock(h->Next, file, line); 1802 h->Next->Prev = h->Prev; 1803 st_MakeHeaderValid(h->Next); 1804 } 1794 1805 1795 1806 /* … … 1801 1812 } 1802 1813 1803 1804 1805 1806 1814 /* 1815 * Nuke out all memory that is about to be freed, including the header 1816 */ 1817 st_SetFortification((unsigned char*)h, FORTIFY_FILL_ON_DEALLOCATE_VALUE, 1807 1818 FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE + h->Size + FORTIFY_AFTER_SIZE); 1808 1819 1809 1810 1811 1812 1813 1814 1815 1816 1817 1820 /* 1821 * And do the actual free 1822 */ 1823 free(h); 1824 1825 /* 1826 * End critical region 1827 */ 1828 FORTIFY_UNLOCK(); 1818 1829 } 1819 1830 … … 1827 1838 st_OutputMemory(struct Header *h) 1828 1839 { 1829 1830 1840 st_HexDump((unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1841 0, h->Size, 1); 1831 1842 } 1832 1843 … … 1840 1851 if(h->Label == NULL) 1841 1852 { 1842 #ifdef FORTIFY_NO_PERCENT_P 1843 sprintf(st_Buffer, "0x%08lx %8lu %s.%lu\n", 1853 # ifdef MT_SCOPES 1854 # ifdef FORTIFY_NO_PERCENT_P 1855 sprintf(st_Buffer, "0x%08lx %8lu %s.%lu TID %u\n", 1856 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1857 (unsigned long)h->Size, 1858 h->File, h->Line, h->Owner); 1859 # else 1860 sprintf(st_Buffer, "%10p %8lu %s.%lu TID %u\n", 1861 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1862 (unsigned long)h->Size, 1863 h->File, h->Line, h->Owner); 1864 # endif 1865 # else 1866 # ifdef FORTIFY_NO_PERCENT_P 1867 sprintf(st_Buffer, "0x%08lx %8lu %s.%lu\n", 1868 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1869 (unsigned long)h->Size, 1870 h->File, h->Line); 1871 # else 1872 sprintf(st_Buffer, "%10p %8lu %s.%lu\n", 1873 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1874 (unsigned long)h->Size, 1875 h->File, h->Line); 1876 # endif 1877 # endif // MT_SCOPES 1878 } 1879 else 1880 { 1881 # ifdef MT_SCOPES 1882 # ifdef FORTIFY_NO_PERCENT_P 1883 sprintf(st_Buffer, "%10p %8lu %s.%lu TID %u %s\n", 1884 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1885 (unsigned long)h->Size, 1886 h->File, h->Line, h->Owner, h->Label); 1844 1887 #else 1845 sprintf(st_Buffer, "%10p %8lu %s.%lu\n", 1846 #endif 1847 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1848 (unsigned long)h->Size, 1849 h->File, h->Line); 1850 } 1851 else 1852 { 1853 #ifdef FORTIFY_NO_PERCENT_P 1854 sprintf(st_Buffer, "0x%08lx %8lu %s.%lu %s\n", 1855 #else 1856 sprintf(st_Buffer, "%10p %8lu %s.%lu %s\n", 1857 #endif 1858 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1859 (unsigned long)h->Size, 1860 h->File, h->Line, h->Label); 1861 } 1862 st_Output(st_Buffer); 1888 sprintf(st_Buffer, "0x%08lx %8lu %s.%lu TID %u %s\n", 1889 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1890 (unsigned long)h->Size, 1891 h->File, h->Line, h->Owner, h->Label); 1892 # endif 1893 # else // not MT_SCOPES 1894 # ifdef FORTIFY_NO_PERCENT_P 1895 sprintf(st_Buffer, "0x%08lx %8lu %s.%lu %s\n", 1896 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1897 (unsigned long)h->Size, 1898 h->File, h->Line, h->Label); 1899 # else 1900 sprintf(st_Buffer, "%10p %8lu %s.%lu %s\n", 1901 (unsigned char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1902 (unsigned long)h->Size, 1903 h->File, h->Line, h->Label); 1904 # endif 1905 # endif // MT_SCOPES 1906 } 1907 st_Output(st_Buffer); 1863 1908 } 1864 1909 … … 1870 1915 st_OutputLastVerifiedPoint() 1871 1916 { 1872 1873 1874 1875 1917 sprintf(st_Buffer, " Memory integrity was last verified at %s.%lu\n", 1918 st_LastVerifiedFile, 1919 st_LastVerifiedLine); 1920 st_Output(st_Buffer); 1876 1921 } 1877 1922 … … 1883 1928 st_MemoryBlockString(struct Header *h) 1884 1929 { 1885 static char st_BlockString[512]; 1886 1887 if(h->Label == 0) 1888 { 1889 #ifdef FORTIFY_NO_PERCENT_P 1890 sprintf(st_BlockString,"(0x%08lx,%lu,%s.%lu)", 1891 #else 1892 sprintf(st_BlockString,"(%p,%lu,%s.%lu)", 1893 #endif 1894 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1895 (unsigned long)h->Size, h->File, h->Line); 1930 static char st_BlockString[512]; 1931 1932 if(h->Label == 0) 1933 { 1934 # ifdef FORTIFY_NO_PERCENT_P 1935 sprintf(st_BlockString,"(0x%08lx,%lu,%s.%lu)", 1936 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1937 (unsigned long)h->Size, h->File, h->Line); 1938 # else 1939 sprintf(st_BlockString,"(%p,%lu,%s.%lu)", 1940 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1941 (unsigned long)h->Size, h->File, h->Line); 1942 # endif 1896 1943 } 1897 1944 else 1898 1945 { 1899 #ifdef FORTIFY_NO_PERCENT_P 1900 sprintf(st_BlockString,"(0x%08lx,%lu,%s.%lu,%s)", 1901 #else 1902 sprintf(st_BlockString,"(%p,%lu,%s.%lu,%s)", 1903 #endif 1904 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1905 (unsigned long)h->Size, h->File, h->Line, h->Label); 1906 } 1907 1908 return st_BlockString; 1946 # ifdef FORTIFY_NO_PERCENT_P 1947 sprintf(st_BlockString,"(0x%08lx,%lu,%s.%lu,%s)", 1948 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1949 (unsigned long)h->Size, h->File, h->Line, h->Label); 1950 # else 1951 sprintf(st_BlockString,"(%p,%lu,%s.%lu,%s)", 1952 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1953 (unsigned long)h->Size, h->File, h->Line, h->Label); 1954 # endif 1955 } 1956 1957 return st_BlockString; 1909 1958 } 1910 1959 … … 1921 1970 st_DeallocatedMemoryBlockString(struct Header *h) 1922 1971 { 1923 1972 static char st_BlockString[256]; 1924 1973 1925 1974 if(h->Label == 0) 1926 1975 { 1927 #ifdef FORTIFY_NO_PERCENT_P1928 1929 # else1930 1931 # endif1932 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,1933 1976 #ifdef FORTIFY_NO_PERCENT_P 1977 sprintf(st_BlockString,"(0x%08lx,%lu,%s.%lu,%s.%lu)", 1978 # else 1979 sprintf(st_BlockString,"(%p,%lu,%s.%lu,%s.%lu)", 1980 # endif 1981 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1982 (unsigned long)h->Size, h->File, h->Line, h->FreedFile, h->FreedLine); 1934 1983 } 1935 1984 else 1936 1985 { 1937 # ifdef FORTIFY_NO_PERCENT_P1938 1939 # else1940 1941 # endif1942 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE,1943 1944 } 1945 1946 1986 # ifdef FORTIFY_NO_PERCENT_P 1987 sprintf(st_BlockString,"(0x%08lx,%lu,%s.%lu,%s.%lu,%s)", 1988 # else 1989 sprintf(st_BlockString,"(%p,%lu,%s.%lu,%s.%lu,%s)", 1990 # endif 1991 (char*)h + FORTIFY_HEADER_SIZE + FORTIFY_ALIGNED_BEFORE_SIZE, 1992 (unsigned long)h->Size, h->File, h->Line, h->FreedFile, h->FreedLine, h->Label); 1993 } 1994 1995 return st_BlockString; 1947 1996 } 1948 1997 #endif /* FORTIFY_VERBOSE_WARN_WHEN_DISCARDING_DEALLOCATED_MEMORY */ … … 1957 2006 st_DefaultOutput(const char *String) 1958 2007 { 1959 1960 2008 fprintf(stdout, String); 2009 fflush(stdout); 1961 2010 } 1962 2011 … … 1967 2016 Fortify_malloc(size_t size, const char *file, unsigned long line) 1968 2017 { 1969 2018 return Fortify_Allocate(size, Fortify_Allocator_malloc, file, line); 1970 2019 } 1971 2020 … … 1976 2025 Fortify_realloc(void *uptr, size_t new_size, const char *file, unsigned long line) 1977 2026 { 1978 unsigned char *ptr = (unsigned char *)uptr - FORTIFY_HEADER_SIZE - FORTIFY_ALIGNED_BEFORE_SIZE; 1979 struct Header *h = (struct Header *)ptr; 1980 void *new_ptr; 1981 1982 /* 1983 * If Fortify is disabled, we gotta do this a little 1984 * differently. 1985 */ 1986 if(!st_Disabled) 1987 { 1988 if(!uptr) 1989 return(Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line)); 1990 1991 if(!st_IsOnAllocatedList(h)) 1992 { 1993 #ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 1994 if(st_IsOnDeallocatedList(h)) 1995 { 1996 sprintf(st_Buffer, "\nFortify: Deallocated memory block passed to \"%s\" at %s.%lu\n", 1997 st_AllocatorName[Fortify_Allocator_realloc], file, line); 1998 st_Output(st_Buffer); 1999 sprintf(st_Buffer, " Memory block %s was deallocated by \"%s\" at %s.%lu\n", 2000 st_MemoryBlockString(h), 2001 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 2002 st_Output(st_Buffer); 2003 return 0; 2004 } 2005 #endif 2006 2007 sprintf(st_Buffer, 2008 #ifdef FORTIFY_NO_PERCENT_P 2009 "\nFortify: Invalid pointer (0x%08lx) passed to realloc at %s.%lu\n", 2010 #else 2011 "\nFortify: Invalid pointer (%p) passed to realloc at %s.%lu\n", 2012 #endif 2013 ptr, file, line); 2014 st_Output(st_Buffer); 2015 return 0; 2016 } 2017 2018 if(!st_CheckBlock(h, file, line)) 2019 return 0; 2020 2021 new_ptr = Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line); 2022 if(!new_ptr) 2023 { 2024 return(0); 2025 } 2026 2027 if(h->Size < new_size) 2028 memcpy(new_ptr, uptr, h->Size); 2027 unsigned char *ptr = (unsigned char *)uptr - FORTIFY_HEADER_SIZE - FORTIFY_ALIGNED_BEFORE_SIZE; 2028 struct Header *h = (struct Header *)ptr; 2029 void *new_ptr; 2030 2031 /* 2032 * If Fortify is disabled, we gotta do this a little 2033 * differently. 2034 */ 2035 if(!st_Disabled) 2036 { 2037 if(!uptr) 2038 return(Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line)); 2039 2040 if(!st_IsOnAllocatedList(h)) 2041 { 2042 # ifdef FORTIFY_TRACK_DEALLOCATED_MEMORY 2043 if(st_IsOnDeallocatedList(h)) 2044 { 2045 sprintf(st_Buffer, "\nFortify: Deallocated memory block passed to \"%s\" at %s.%lu\n", 2046 st_AllocatorName[Fortify_Allocator_realloc], file, line); 2047 st_Output(st_Buffer); 2048 sprintf(st_Buffer, " Memory block %s was deallocated by \"%s\" at %s.%lu\n", 2049 st_MemoryBlockString(h), 2050 st_DeallocatorName[h->Deallocator], h->FreedFile, h->FreedLine); 2051 st_Output(st_Buffer); 2052 return 0; 2053 } 2054 # endif 2055 2056 sprintf(st_Buffer, 2057 # ifdef FORTIFY_NO_PERCENT_P 2058 "\nFortify: Invalid pointer (0x%08lx) passed to realloc at %s.%lu\n", 2059 # else 2060 "\nFortify: Invalid pointer (%p) passed to realloc at %s.%lu\n", 2061 # endif 2062 ptr, file, line); 2063 st_Output(st_Buffer); 2064 return 0; 2065 } 2066 2067 if(!st_CheckBlock(h, file, line)) 2068 return 0; 2069 2070 new_ptr = Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line); 2071 if(!new_ptr) 2072 { 2073 return(0); 2074 } 2075 2076 if(h->Size < new_size) 2077 memcpy(new_ptr, uptr, h->Size); 2078 else 2079 memcpy(new_ptr, uptr, new_size); 2080 2081 Fortify_Deallocate(uptr, Fortify_Deallocator_realloc, file, line); 2082 return(new_ptr); 2083 } 2029 2084 else 2030 memcpy(new_ptr, uptr, new_size); 2031 2032 Fortify_Deallocate(uptr, Fortify_Deallocator_realloc, file, line); 2033 return(new_ptr); 2034 } 2035 else 2036 { 2037 /* 2038 * If the old block was fortified, we can't use normal realloc. 2039 */ 2040 if(st_IsOnAllocatedList(h)) 2041 { 2042 new_ptr = Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line); 2043 if(!new_ptr) 2044 return(0); 2045 2046 if(h->Size < new_size) 2047 memcpy(new_ptr, uptr, h->Size); 2048 else 2049 memcpy(new_ptr, uptr, new_size); 2050 2051 Fortify_Deallocate(uptr, Fortify_Deallocator_realloc, file, line); 2052 return(new_ptr); 2053 } 2054 else /* easy */ 2055 { 2056 return realloc(uptr, new_size); 2057 } 2058 } 2085 { 2086 /* 2087 * If the old block was fortified, we can't use normal realloc. 2088 */ 2089 if(st_IsOnAllocatedList(h)) 2090 { 2091 new_ptr = Fortify_Allocate(new_size, Fortify_Allocator_realloc, file, line); 2092 if(!new_ptr) 2093 return(0); 2094 2095 if(h->Size < new_size) 2096 memcpy(new_ptr, uptr, h->Size); 2097 else 2098 memcpy(new_ptr, uptr, new_size); 2099 2100 Fortify_Deallocate(uptr, Fortify_Deallocator_realloc, file, line); 2101 return(new_ptr); 2102 } 2103 else /* easy */ 2104 { 2105 return realloc(uptr, new_size); 2106 } 2107 } 2059 2108 } 2060 2109 … … 2065 2114 Fortify_calloc(size_t num, size_t size, const char *file, unsigned long line) 2066 2115 { 2067 2068 2069 void *ptr = Fortify_Allocate(size * num, Fortify_Allocator_calloc, file, line);2070 if(ptr)2071 {2072 2073 }2074 return ptr;2075 2076 2077 2078 return calloc(num, size);2079 2116 if(!st_Disabled) 2117 { 2118 void *ptr = Fortify_Allocate(size * num, Fortify_Allocator_calloc, file, line); 2119 if(ptr) 2120 { 2121 memset(ptr, 0, size*num); 2122 } 2123 return ptr; 2124 } 2125 else 2126 { 2127 return calloc(num, size); 2128 } 2080 2129 } 2081 2130 … … 2088 2137 /* it is defined to be safe to free(0) */ 2089 2138 if(uptr == 0) 2090 return;2091 2092 2139 return; 2140 2141 Fortify_Deallocate(uptr, Fortify_Deallocator_free, file, line); 2093 2142 } 2094 2143 … … 2101 2150 Fortify_strdup(const char *oldStr, const char *file, unsigned long line) 2102 2151 { 2103 2104 2105 char *newStr = (char *)Fortify_Allocate(strlen(oldStr)+1, Fortify_Allocator_strdup, file, line);2106 if(newStr)2107 {2108 2109 }2110 2111 return newStr;2112 2113 2114 2115 return strdup(oldStr);2116 2152 if(!st_Disabled) 2153 { 2154 char *newStr = (char *)Fortify_Allocate(strlen(oldStr)+1, Fortify_Allocator_strdup, file, line); 2155 if(newStr) 2156 { 2157 strcpy(newStr, oldStr); 2158 } 2159 2160 return newStr; 2161 } 2162 else 2163 { 2164 return strdup(oldStr); 2165 } 2117 2166 } 2118 2167 #endif /* FORTIFY_STRDUP */ … … 2121 2170 st_OutputDeleteTrace() 2122 2171 { 2123 # ifdef __cplusplus2124 2125 2126 sprintf(st_Buffer, "Delete Trace: %s.%lu\n", st_DeleteFile[st_DeleteStackTop-1],2127 2128 st_Output(st_Buffer);2129 for(int c = st_DeleteStackTop-2; c >= 0; c--)2130 {2131 2132 2133 2134 }2135 2136 # endif2172 # ifdef __cplusplus 2173 if(st_DeleteStackTop > 1) 2174 { 2175 sprintf(st_Buffer, "Delete Trace: %s.%lu\n", st_DeleteFile[st_DeleteStackTop-1], 2176 st_DeleteLine[st_DeleteStackTop-1]); 2177 st_Output(st_Buffer); 2178 for(int c = st_DeleteStackTop-2; c >= 0; c--) 2179 { 2180 sprintf(st_Buffer, " %s.%lu\n", st_DeleteFile[c], 2181 st_DeleteLine[c]); 2182 st_Output(st_Buffer); 2183 } 2184 } 2185 # endif 2137 2186 } 2138 2187 … … 2149 2198 st_NewHandler() 2150 2199 { 2151 2152 2153 2154 2155 2156 2157 2158 2159 2200 /* get the current handler */ 2201 Fortify_NewHandlerFunc handler = set_new_handler(0); 2202 2203 /* and set it back (since we cant 2204 * get it without changing it) 2205 */ 2206 set_new_handler(handler); 2207 2208 return handler; 2160 2209 } 2161 2210 … … 2167 2216 operator new(size_t size) 2168 2217 { 2169 2170 2171 2218 void *p; 2219 2220 while((p = Fortify_Allocate(size, Fortify_Allocator_new, 2172 2221 st_AllocatorName[Fortify_Allocator_new], 0)) == 0) 2173 2174 if(st_NewHandler())2175 2176 else2177 2178 2179 2180 2222 { 2223 if(st_NewHandler()) 2224 (*st_NewHandler())(); 2225 else 2226 return 0; 2227 } 2228 2229 return p; 2181 2230 } 2182 2231 … … 2188 2237 operator new(size_t size, const char *file, int line) 2189 2238 { 2190 2191 2192 2193 2194 if(st_NewHandler())2195 2239 void *p; 2240 2241 while((p = Fortify_Allocate(size, Fortify_Allocator_new, file, line)) == 0) 2242 { 2243 if(st_NewHandler()) 2244 (*st_NewHandler())(); 2196 2245 else 2197 2198 2199 2200 2246 return 0; 2247 } 2248 2249 return p; 2201 2250 } 2202 2251 … … 2209 2258 operator new[](size_t size) 2210 2259 { 2211 2212 2213 2260 void *p; 2261 2262 while((p = Fortify_Allocate(size, Fortify_Allocator_array_new, 2214 2263 st_AllocatorName[Fortify_Allocator_array_new], 0)) == 0) 2215 2216 if(st_NewHandler())2217 2218 else2219 2220 2221 2222 2264 { 2265 if(st_NewHandler()) 2266 (*st_NewHandler())(); 2267 else 2268 return 0; 2269 } 2270 2271 return p; 2223 2272 } 2224 2273 … … 2229 2278 operator new[](size_t size, const char *file, unsigned long line) 2230 2279 { 2231 2232 2233 2234 2235 if(st_NewHandler())2236 2237 else2238 2239 2240 2241 2280 void *p; 2281 2282 while((p = Fortify_Allocate(size, Fortify_Allocator_array_new, file, line)) == 0) 2283 { 2284 if(st_NewHandler()) 2285 (*st_NewHandler())(); 2286 else 2287 return 0; 2288 } 2289 2290 return p; 2242 2291 } 2243 2292 … … 2252 2301 Fortify_PreDelete(const char *file, int line) 2253 2302 { 2254 2255 2256 2257 2258 2259 2260 2261 2262 st_DeleteFile[st_DeleteStackTop] = file;2263 st_DeleteLine[st_DeleteStackTop] = line;2264 2265 2266 2303 FORTIFY_LOCK(); 2304 2305 /* 2306 * Push the source code info for the delete onto the delete stack 2307 * (if we have enough room, of course) 2308 */ 2309 if(st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE) 2310 { 2311 st_DeleteFile[st_DeleteStackTop] = file; 2312 st_DeleteLine[st_DeleteStackTop] = line; 2313 } 2314 2315 st_DeleteStackTop++; 2267 2316 } 2268 2317 … … 2274 2323 Fortify_PostDelete() 2275 2324 { 2276 2277 2278 2325 st_DeleteStackTop--; 2326 2327 FORTIFY_UNLOCK(); 2279 2328 } 2280 2329 … … 2285 2334 operator delete(void *uptr) 2286 2335 { 2287 const char *file; 2288 unsigned long line; 2289 2290 /* 2291 * It is defined to be harmless to delete 0 2292 */ 2293 if(uptr == 0) 2294 return; 2295 2296 /* 2297 * find the source-code info 2298 */ 2299 if(st_DeleteStackTop) 2300 { 2301 if(st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE) 2302 { 2303 file = st_DeleteFile[st_DeleteStackTop-1]; 2304 line = st_DeleteLine[st_DeleteStackTop-1]; 2336 const char *file; 2337 unsigned long line; 2338 2339 /* 2340 * It is defined to be harmless to delete 0 2341 */ 2342 if(uptr == 0) 2343 return; 2344 2345 /* 2346 * find the source-code info 2347 */ 2348 if(st_DeleteStackTop) 2349 { 2350 if(st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE) 2351 { 2352 file = st_DeleteFile[st_DeleteStackTop-1]; 2353 line = st_DeleteLine[st_DeleteStackTop-1]; 2354 } 2355 else 2356 { 2357 file = st_DeleteFile[FORTIFY_DELETE_STACK_SIZE-1]; 2358 line = st_DeleteLine[FORTIFY_DELETE_STACK_SIZE-1]; 2359 } 2305 2360 } 2306 2361 else 2307 2362 { 2308 file = st_DeleteFile[FORTIFY_DELETE_STACK_SIZE-1]; 2309 line = st_DeleteLine[FORTIFY_DELETE_STACK_SIZE-1]; 2310 } 2311 } 2312 else 2313 { 2314 file = st_DeallocatorName[Fortify_Deallocator_delete]; 2315 line = 0; 2316 } 2317 2318 Fortify_Deallocate(uptr, Fortify_Deallocator_delete, file, line); 2363 file = st_DeallocatorName[Fortify_Deallocator_delete]; 2364 line = 0; 2365 } 2366 2367 Fortify_Deallocate(uptr, Fortify_Deallocator_delete, file, line); 2319 2368 } 2320 2369 … … 2327 2376 operator delete[](void *uptr) 2328 2377 { 2329 const char *file; 2330 unsigned long line; 2331 2332 /* 2333 * It is defined to be harmless to delete 0 2334 */ 2335 if(uptr == 0) 2336 return; 2337 2338 /* 2339 * find the source-code info 2340 */ 2341 if(st_DeleteStackTop) 2342 { 2343 if(st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE) 2344 { 2345 file = st_DeleteFile[st_DeleteStackTop-1]; 2346 line = st_DeleteLine[st_DeleteStackTop-1]; 2378 const char *file; 2379 unsigned long line; 2380 2381 /* 2382 * It is defined to be harmless to delete 0 2383 */ 2384 if(uptr == 0) 2385 return; 2386 2387 /* 2388 * find the source-code info 2389 */ 2390 if(st_DeleteStackTop) 2391 { 2392 if(st_DeleteStackTop < FORTIFY_DELETE_STACK_SIZE) 2393 { 2394 file = st_DeleteFile[st_DeleteStackTop-1]; 2395 line = st_DeleteLine[st_DeleteStackTop-1]; 2396 } 2397 else 2398 { 2399 file = st_DeleteFile[FORTIFY_DELETE_STACK_SIZE-1]; 2400 line = st_DeleteLine[FORTIFY_DELETE_STACK_SIZE-1]; 2401 } 2347 2402 } 2348 2403 else 2349 2404 { 2350 file = st_DeleteFile[FORTIFY_DELETE_STACK_SIZE-1]; 2351 line = st_DeleteLine[FORTIFY_DELETE_STACK_SIZE-1]; 2352 } 2353 } 2354 else 2355 { 2356 file = st_DeallocatorName[Fortify_Deallocator_array_delete]; 2357 line = 0; 2358 } 2359 2360 Fortify_Deallocate(uptr, Fortify_Deallocator_array_delete, file, line); 2405 file = st_DeallocatorName[Fortify_Deallocator_array_delete]; 2406 line = 0; 2407 } 2408 2409 Fortify_Deallocate(uptr, Fortify_Deallocator_array_delete, file, line); 2361 2410 } 2362 2411 … … 2376 2425 class Fortify_AutoLogFile 2377 2426 { 2378 2379 2380 2427 static FILE *fp; 2428 static int written_something; 2429 static char *init_string, *term_string; 2381 2430 2382 2431 public: 2383 2384 2385 written_something = 0;2386 Fortify_SetOutputFunc(Fortify_AutoLogFile::Output);2387 Fortify_EnterScope(init_string, 0);2388 2389 2390 2391 2432 Fortify_AutoLogFile() 2433 { 2434 written_something = 0; 2435 Fortify_SetOutputFunc(Fortify_AutoLogFile::Output); 2436 Fortify_EnterScope(init_string, 0); 2437 } 2438 2439 static void Output(const char *s) 2440 { 2392 2441 if(written_something == 0) 2393 2442 { 2394 2395 2396 2397 2398 time_t t;2399 time(&t);2400 fprintf(fp, "Fortify log started at %s\n", ctime(&t));2401 written_something = 1;2402 2443 FORTIFY_FIRST_ERROR_FUNCTION; 2444 fp = fopen(FORTIFY_LOG_FILENAME, "w"); 2445 if(fp) 2446 { 2447 time_t t; 2448 time(&t); 2449 fprintf(fp, "Fortify log started at %s\n", ctime(&t)); 2450 written_something = 1; 2451 } 2403 2452 } 2404 2453 2405 2454 if(fp) 2406 2455 { 2407 2408 2409 } 2410 2411 2412 2413 2456 fputs(s, fp); 2457 fflush(fp); 2458 } 2459 } 2460 2461 ~Fortify_AutoLogFile() 2462 { 2414 2463 Fortify_LeaveScope(term_string, 0); 2415 2464 Fortify_CheckAllMemory(term_string, 0); 2416 2465 if(fp) 2417 2466 { 2418 2419 2420 2421 2422 2423 } 2424 2467 time_t t; 2468 time(&t); 2469 fprintf(fp, "\nFortify log closed at %s\n", ctime(&t)); 2470 fclose(fp); 2471 fp = 0; 2472 } 2473 } 2425 2474 }; 2426 2475 … … 2438 2487 #ifdef MT_SCOPES 2439 2488 2489 #if 0 // 18 Jul 08 SHL fixme to be gone 2490 2440 2491 /** 2441 2492 * Set/reset owner of blocks allocated by this thread 2442 2493 * Use when worker thread will allocate blocks for another thread 2443 2494 * and other thread is known 2444 * More efficient than Fortify_ChangeOwner2495 * Slightly more efficient than Fortify_BecomeOwner 2445 2496 * @param lOwnerTID is new owner TID, -1 requests reset of self 2446 2497 */ 2447 2498 2448 void Fortify_SetOwner(long lOwnerTID) 2449 { 2450 unsigned ordinal = Get_TID_Ordinal(); 2451 2452 if (ordinal >= st_cOrdinals) { 2453 // Expand arrays 2454 unsigned i; 2455 unsigned c; 2456 FORTIFY_LOCK(); 2457 i = st_cOrdinals; 2458 c = ordinal + 1; 2459 st_pScopes = realloc((void*)st_pScopes, sizeof(*st_pScopes) * c); 2460 st_pOwners = realloc((void*)st_pOwners, sizeof(*st_pOwners) * c); 2461 for (; i <= ordinal; i++) { 2462 st_pScopes[i] = 0; 2463 st_pOwners[i] = i; // Block owner is self 2464 } 2465 st_cOrdinals = c; 2466 FORTIFY_UNLOCK(); 2467 } 2468 // Set owner for blocks allocated by this thread 2469 st_pOwners[ordinal] = lOwnerTID != -1 ? lOwnerTID : ordinal; 2470 } 2499 void Fortify_PresetOwner(long lOwnerTID) 2500 { 2501 unsigned ordinal = Get_TID_Ordinal(); 2502 2503 if (ordinal >= st_cOrdinals) { 2504 // Expand arrays 2505 unsigned i; 2506 unsigned c; 2507 FORTIFY_LOCK(); 2508 i = st_cOrdinals; 2509 c = ordinal + 1; 2510 st_pScopes = realloc((void*)st_pScopes, sizeof(*st_pScopes) * c); 2511 st_pOwners = realloc((void*)st_pOwners, sizeof(*st_pOwners) * c); 2512 for (; i <= ordinal; i++) { 2513 st_pScopes[i] = 0; 2514 st_pOwners[i] = i; // Block owner is self 2515 } 2516 st_cOrdinals = c; 2517 FORTIFY_UNLOCK(); 2518 } 2519 // Set owner for blocks allocated by this thread 2520 st_pOwners[ordinal] = lOwnerTID != -1 ? lOwnerTID : ordinal; 2521 } 2522 #endif // 18 Jul 08 SHL fixme to be gone 2471 2523 2472 2524 /** … … 2477 2529 */ 2478 2530 2479 void Fortify_ChangeOwner(void *pBlock) 2480 { 2481 unsigned char *ptr = (unsigned char *)pBlock - 2482 FORTIFY_HEADER_SIZE - 2483 FORTIFY_ALIGNED_BEFORE_SIZE; 2484 struct Header *h = (struct Header *)ptr; 2485 2486 unsigned ordinal = Get_TID_Ordinal(); 2487 2488 h->Scope = ordinal < st_cOrdinals ? st_pScopes[ordinal] : 0; 2489 h->Owner = ordinal; // Take ownership 2490 st_MakeHeaderValid(h); 2531 void Fortify_BecomeOwner(void *pBlock) 2532 { 2533 unsigned char *ptr = (unsigned char *)pBlock - 2534 FORTIFY_HEADER_SIZE - 2535 FORTIFY_ALIGNED_BEFORE_SIZE; 2536 struct Header *h = (struct Header *)ptr; 2537 2538 unsigned ordinal = Get_TID_Ordinal(); 2539 2540 h->Owner = ordinal; // Take ownership 2541 h->Scope = ordinal < st_cOrdinals ? st_pScopes[ordinal] : 0; 2542 st_MakeHeaderValid(h); 2543 } 2544 2545 /** 2546 * Take ownership of block allocated by some other thread 2547 * Allows scope enter/exit logic to correctly report leaks in 2548 * cross thread allocations 2549 * @param pBlock points to block allocated by Fortify 2550 */ 2551 2552 void Fortify_SetOwner(void *pBlock, unsigned ordinal) 2553 { 2554 unsigned char *ptr = (unsigned char *)pBlock - 2555 FORTIFY_HEADER_SIZE - 2556 FORTIFY_ALIGNED_BEFORE_SIZE; 2557 struct Header *h = (struct Header *)ptr; 2558 2559 h->Owner = (unsigned short)ordinal; // Take ownership 2560 h->Scope = ordinal < st_cOrdinals ? st_pScopes[ordinal] : 0; 2561 st_MakeHeaderValid(h); 2491 2562 } 2492 2563 … … 2500 2571 void Fortify_ChangeScope(void *pBlock, int delta) 2501 2572 { 2502 unsigned char *ptr = (unsigned char *)pBlock - 2503 FORTIFY_HEADER_SIZE - 2504 FORTIFY_ALIGNED_BEFORE_SIZE; 2505 struct Header *h = (struct Header *)ptr; 2506 h->Scope += delta; 2507 st_MakeHeaderValid(h); 2573 unsigned char *ptr = (unsigned char *)pBlock - 2574 FORTIFY_HEADER_SIZE - 2575 FORTIFY_ALIGNED_BEFORE_SIZE; 2576 struct Header *h = (struct Header *)ptr; 2577 h->Scope += delta; 2578 st_MakeHeaderValid(h); 2579 } 2580 2581 /** 2582 * Force scope level of allocated block 2583 * Allows scope enter/exit logic to correctly report leaks in 2584 * window procedure related allocations 2585 * @param pBlock points to block allocated by Fortify 2586 */ 2587 2588 void Fortify_SetScope(void *pBlock, unsigned char scope) 2589 { 2590 unsigned char *ptr = (unsigned char *)pBlock - 2591 FORTIFY_HEADER_SIZE - 2592 FORTIFY_ALIGNED_BEFORE_SIZE; 2593 struct Header *h = (struct Header *)ptr; 2594 h->Scope = scope; 2595 st_MakeHeaderValid(h); 2508 2596 } 2509 2597
Note:
See TracChangeset
for help on using the changeset viewer.