1/* Copyright (C) 2004, 2005 Free Software Foundation. 2 3 Ensure builtin __memset_chk performs correctly. */ 4 5extern void abort (void); 6typedef __SIZE_TYPE__ size_t; 7extern size_t strlen(const char *); 8extern void *memcpy (void *, const void *, size_t); 9extern void *memset (void *, int, size_t); 10extern int memcmp (const void *, const void *, size_t); 11 12#include "chk.h" 13 14char buffer[32]; 15int argc = 1; 16size_t l1 = 1; 17char *s3 = "FGH"; 18char *s4; 19 20void 21__attribute__((noinline)) 22test1 (void) 23{ 24 memset_disallowed = 1; 25 chk_calls = 0; 26 memset (buffer, argc, 0); 27 memset (buffer, argc, 1); 28 memset (buffer, argc, 2); 29 memset (buffer, argc, 3); 30 memset (buffer, argc, 4); 31 memset (buffer, argc, 5); 32 memset (buffer, argc, 6); 33 memset (buffer, argc, 7); 34 memset (buffer, argc, 8); 35 memset (buffer, argc, 9); 36 memset (buffer, argc, 10); 37 memset (buffer, argc, 11); 38 memset (buffer, argc, 12); 39 memset (buffer, argc, 13); 40 memset (buffer, argc, 14); 41 memset (buffer, argc, 15); 42 memset (buffer, argc, 16); 43 memset (buffer, argc, 17); 44 memset_disallowed = 0; 45 if (chk_calls) 46 abort (); 47} 48 49/* Test whether compile time checking is done where it should 50 and so is runtime object size checking. */ 51void 52__attribute__((noinline)) 53test2 (void) 54{ 55 struct A { char buf1[10]; char buf2[10]; } a; 56 char *r = l1 == 1 ? &a.buf1[5] : &a.buf2[4]; 57 char buf3[20]; 58 int i; 59 size_t l; 60 61 /* The following calls should do runtime checking 62 - length is not known, but destination is. */ 63 chk_calls = 0; 64 memset (a.buf1 + 2, 'a', l1); 65 memset (r, '\0', l1 + 1); 66 r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7]; 67 memset (r, argc, l1 + 2); 68 memset (r + 2, 'Q', l1); 69 r = buf3; 70 for (i = 0; i < 4; ++i) 71 { 72 if (i == l1 - 1) 73 r = &a.buf1[1]; 74 else if (i == l1) 75 r = &a.buf2[7]; 76 else if (i == l1 + 1) 77 r = &buf3[5]; 78 else if (i == l1 + 2) 79 r = &a.buf1[9]; 80 } 81 memset (r, '\0', l1); 82 if (chk_calls != 5) 83 abort (); 84 85 /* Following have known destination and known length, 86 so if optimizing certainly shouldn't result in the checking 87 variants. */ 88 chk_calls = 0; 89 memset (a.buf1 + 2, '\0', 1); 90 memset (r, argc, 2); 91 r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7]; 92 memset (r, 'N', 3); 93 r = buf3; 94 l = 4; 95 for (i = 0; i < 4; ++i) 96 { 97 if (i == l1 - 1) 98 r = &a.buf1[1], l = 2; 99 else if (i == l1) 100 r = &a.buf2[7], l = 3; 101 else if (i == l1 + 1) 102 r = &buf3[5], l = 4; 103 else if (i == l1 + 2) 104 r = &a.buf1[9], l = 1; 105 } 106 memset (r, 'H', 1); 107 /* Here, l is known to be at most 4 and __builtin_object_size (&buf3[16], 0) 108 is 4, so this doesn't need runtime checking. */ 109 memset (&buf3[16], 'd', l); 110 /* Neither length nor destination known. Doesn't need runtime checking. */ 111 memset (s4, 'a', l1); 112 memset (s4 + 2, '\0', l1 + 2); 113 /* Destination unknown. */ 114 memset (s4 + 4, 'b', 2); 115 memset (s4 + 6, '\0', 4); 116 if (chk_calls) 117 abort (); 118 chk_calls = 0; 119} 120 121/* Test whether runtime and/or compile time checking catches 122 buffer overflows. */ 123void 124__attribute__((noinline)) 125test3 (void) 126{ 127 struct A { char buf1[10]; char buf2[10]; } a; 128 char buf3[20]; 129 130 chk_fail_allowed = 1; 131 /* Runtime checks. */ 132 if (__builtin_setjmp (chk_fail_buf) == 0) 133 { 134 memset (&a.buf2[9], '\0', l1 + 1); 135 abort (); 136 } 137 if (__builtin_setjmp (chk_fail_buf) == 0) 138 { 139 memset (&a.buf2[7], 'T', strlen (s3) + 1); 140 abort (); 141 } 142 /* This should be detectable at compile time already. */ 143 if (__builtin_setjmp (chk_fail_buf) == 0) 144 { 145 memset (&buf3[19], 'b', 2); 146 abort (); 147 } 148 chk_fail_allowed = 0; 149} 150 151#ifndef MAX_OFFSET 152#define MAX_OFFSET (sizeof (long long)) 153#endif 154 155#ifndef MAX_COPY 156#define MAX_COPY (10 * sizeof (long long)) 157#define MAX_COPY2 15 158#else 159#define MAX_COPY2 MAX_COPY 160#endif 161 162#ifndef MAX_EXTRA 163#define MAX_EXTRA (sizeof (long long)) 164#endif 165 166#define MAX_LENGTH (MAX_OFFSET + MAX_COPY + MAX_EXTRA) 167#define MAX_LENGTH2 (MAX_OFFSET + MAX_COPY2 + MAX_EXTRA) 168 169static union { 170 char buf[MAX_LENGTH]; 171 long long align_int; 172 long double align_fp; 173} u; 174 175char A = 'A'; 176 177void 178__attribute__((noinline)) 179test4 (void) 180{ 181 int off, len, i; 182 char *p, *q; 183 184 for (off = 0; off < MAX_OFFSET; off++) 185 for (len = 1; len < MAX_COPY; len++) 186 { 187 for (i = 0; i < MAX_LENGTH; i++) 188 u.buf[i] = 'a'; 189 190 p = memset (u.buf + off, '\0', len); 191 if (p != u.buf + off) 192 abort (); 193 194 q = u.buf; 195 for (i = 0; i < off; i++, q++) 196 if (*q != 'a') 197 abort (); 198 199 for (i = 0; i < len; i++, q++) 200 if (*q != '\0') 201 abort (); 202 203 for (i = 0; i < MAX_EXTRA; i++, q++) 204 if (*q != 'a') 205 abort (); 206 207 p = memset (u.buf + off, A, len); 208 if (p != u.buf + off) 209 abort (); 210 211 q = u.buf; 212 for (i = 0; i < off; i++, q++) 213 if (*q != 'a') 214 abort (); 215 216 for (i = 0; i < len; i++, q++) 217 if (*q != 'A') 218 abort (); 219 220 for (i = 0; i < MAX_EXTRA; i++, q++) 221 if (*q != 'a') 222 abort (); 223 224 p = memset (u.buf + off, 'B', len); 225 if (p != u.buf + off) 226 abort (); 227 228 q = u.buf; 229 for (i = 0; i < off; i++, q++) 230 if (*q != 'a') 231 abort (); 232 233 for (i = 0; i < len; i++, q++) 234 if (*q != 'B') 235 abort (); 236 237 for (i = 0; i < MAX_EXTRA; i++, q++) 238 if (*q != 'a') 239 abort (); 240 } 241} 242 243static union { 244 char buf[MAX_LENGTH2]; 245 long long align_int; 246 long double align_fp; 247} u2; 248 249void reset () 250{ 251 int i; 252 253 for (i = 0; i < MAX_LENGTH2; i++) 254 u2.buf[i] = 'a'; 255} 256 257void check (int off, int len, int ch) 258{ 259 char *q; 260 int i; 261 262 q = u2.buf; 263 for (i = 0; i < off; i++, q++) 264 if (*q != 'a') 265 abort (); 266 267 for (i = 0; i < len; i++, q++) 268 if (*q != ch) 269 abort (); 270 271 for (i = 0; i < MAX_EXTRA; i++, q++) 272 if (*q != 'a') 273 abort (); 274} 275 276void 277__attribute__((noinline)) 278test5 (void) 279{ 280 int off; 281 char *p; 282 283 /* len == 1 */ 284 for (off = 0; off < MAX_OFFSET; off++) 285 { 286 reset (); 287 288 p = memset (u2.buf + off, '\0', 1); 289 if (p != u2.buf + off) abort (); 290 check (off, 1, '\0'); 291 292 p = memset (u2.buf + off, A, 1); 293 if (p != u2.buf + off) abort (); 294 check (off, 1, 'A'); 295 296 p = memset (u2.buf + off, 'B', 1); 297 if (p != u2.buf + off) abort (); 298 check (off, 1, 'B'); 299 } 300 301 /* len == 2 */ 302 for (off = 0; off < MAX_OFFSET; off++) 303 { 304 reset (); 305 306 p = memset (u2.buf + off, '\0', 2); 307 if (p != u2.buf + off) abort (); 308 check (off, 2, '\0'); 309 310 p = memset (u2.buf + off, A, 2); 311 if (p != u2.buf + off) abort (); 312 check (off, 2, 'A'); 313 314 p = memset (u2.buf + off, 'B', 2); 315 if (p != u2.buf + off) abort (); 316 check (off, 2, 'B'); 317 } 318 319 /* len == 3 */ 320 for (off = 0; off < MAX_OFFSET; off++) 321 { 322 reset (); 323 324 p = memset (u2.buf + off, '\0', 3); 325 if (p != u2.buf + off) abort (); 326 check (off, 3, '\0'); 327 328 p = memset (u2.buf + off, A, 3); 329 if (p != u2.buf + off) abort (); 330 check (off, 3, 'A'); 331 332 p = memset (u2.buf + off, 'B', 3); 333 if (p != u2.buf + off) abort (); 334 check (off, 3, 'B'); 335 } 336 337 /* len == 4 */ 338 for (off = 0; off < MAX_OFFSET; off++) 339 { 340 reset (); 341 342 p = memset (u2.buf + off, '\0', 4); 343 if (p != u2.buf + off) abort (); 344 check (off, 4, '\0'); 345 346 p = memset (u2.buf + off, A, 4); 347 if (p != u2.buf + off) abort (); 348 check (off, 4, 'A'); 349 350 p = memset (u2.buf + off, 'B', 4); 351 if (p != u2.buf + off) abort (); 352 check (off, 4, 'B'); 353 } 354 355 /* len == 5 */ 356 for (off = 0; off < MAX_OFFSET; off++) 357 { 358 reset (); 359 360 p = memset (u2.buf + off, '\0', 5); 361 if (p != u2.buf + off) abort (); 362 check (off, 5, '\0'); 363 364 p = memset (u2.buf + off, A, 5); 365 if (p != u2.buf + off) abort (); 366 check (off, 5, 'A'); 367 368 p = memset (u2.buf + off, 'B', 5); 369 if (p != u2.buf + off) abort (); 370 check (off, 5, 'B'); 371 } 372 373 /* len == 6 */ 374 for (off = 0; off < MAX_OFFSET; off++) 375 { 376 reset (); 377 378 p = memset (u2.buf + off, '\0', 6); 379 if (p != u2.buf + off) abort (); 380 check (off, 6, '\0'); 381 382 p = memset (u2.buf + off, A, 6); 383 if (p != u2.buf + off) abort (); 384 check (off, 6, 'A'); 385 386 p = memset (u2.buf + off, 'B', 6); 387 if (p != u2.buf + off) abort (); 388 check (off, 6, 'B'); 389 } 390 391 /* len == 7 */ 392 for (off = 0; off < MAX_OFFSET; off++) 393 { 394 reset (); 395 396 p = memset (u2.buf + off, '\0', 7); 397 if (p != u2.buf + off) abort (); 398 check (off, 7, '\0'); 399 400 p = memset (u2.buf + off, A, 7); 401 if (p != u2.buf + off) abort (); 402 check (off, 7, 'A'); 403 404 p = memset (u2.buf + off, 'B', 7); 405 if (p != u2.buf + off) abort (); 406 check (off, 7, 'B'); 407 } 408 409 /* len == 8 */ 410 for (off = 0; off < MAX_OFFSET; off++) 411 { 412 reset (); 413 414 p = memset (u2.buf + off, '\0', 8); 415 if (p != u2.buf + off) abort (); 416 check (off, 8, '\0'); 417 418 p = memset (u2.buf + off, A, 8); 419 if (p != u2.buf + off) abort (); 420 check (off, 8, 'A'); 421 422 p = memset (u2.buf + off, 'B', 8); 423 if (p != u2.buf + off) abort (); 424 check (off, 8, 'B'); 425 } 426 427 /* len == 9 */ 428 for (off = 0; off < MAX_OFFSET; off++) 429 { 430 reset (); 431 432 p = memset (u2.buf + off, '\0', 9); 433 if (p != u2.buf + off) abort (); 434 check (off, 9, '\0'); 435 436 p = memset (u2.buf + off, A, 9); 437 if (p != u2.buf + off) abort (); 438 check (off, 9, 'A'); 439 440 p = memset (u2.buf + off, 'B', 9); 441 if (p != u2.buf + off) abort (); 442 check (off, 9, 'B'); 443 } 444 445 /* len == 10 */ 446 for (off = 0; off < MAX_OFFSET; off++) 447 { 448 reset (); 449 450 p = memset (u2.buf + off, '\0', 10); 451 if (p != u2.buf + off) abort (); 452 check (off, 10, '\0'); 453 454 p = memset (u2.buf + off, A, 10); 455 if (p != u2.buf + off) abort (); 456 check (off, 10, 'A'); 457 458 p = memset (u2.buf + off, 'B', 10); 459 if (p != u2.buf + off) abort (); 460 check (off, 10, 'B'); 461 } 462 463 /* len == 11 */ 464 for (off = 0; off < MAX_OFFSET; off++) 465 { 466 reset (); 467 468 p = memset (u2.buf + off, '\0', 11); 469 if (p != u2.buf + off) abort (); 470 check (off, 11, '\0'); 471 472 p = memset (u2.buf + off, A, 11); 473 if (p != u2.buf + off) abort (); 474 check (off, 11, 'A'); 475 476 p = memset (u2.buf + off, 'B', 11); 477 if (p != u2.buf + off) abort (); 478 check (off, 11, 'B'); 479 } 480 481 /* len == 12 */ 482 for (off = 0; off < MAX_OFFSET; off++) 483 { 484 reset (); 485 486 p = memset (u2.buf + off, '\0', 12); 487 if (p != u2.buf + off) abort (); 488 check (off, 12, '\0'); 489 490 p = memset (u2.buf + off, A, 12); 491 if (p != u2.buf + off) abort (); 492 check (off, 12, 'A'); 493 494 p = memset (u2.buf + off, 'B', 12); 495 if (p != u2.buf + off) abort (); 496 check (off, 12, 'B'); 497 } 498 499 /* len == 13 */ 500 for (off = 0; off < MAX_OFFSET; off++) 501 { 502 reset (); 503 504 p = memset (u2.buf + off, '\0', 13); 505 if (p != u2.buf + off) abort (); 506 check (off, 13, '\0'); 507 508 p = memset (u2.buf + off, A, 13); 509 if (p != u2.buf + off) abort (); 510 check (off, 13, 'A'); 511 512 p = memset (u2.buf + off, 'B', 13); 513 if (p != u2.buf + off) abort (); 514 check (off, 13, 'B'); 515 } 516 517 /* len == 14 */ 518 for (off = 0; off < MAX_OFFSET; off++) 519 { 520 reset (); 521 522 p = memset (u2.buf + off, '\0', 14); 523 if (p != u2.buf + off) abort (); 524 check (off, 14, '\0'); 525 526 p = memset (u2.buf + off, A, 14); 527 if (p != u2.buf + off) abort (); 528 check (off, 14, 'A'); 529 530 p = memset (u2.buf + off, 'B', 14); 531 if (p != u2.buf + off) abort (); 532 check (off, 14, 'B'); 533 } 534 535 /* len == 15 */ 536 for (off = 0; off < MAX_OFFSET; off++) 537 { 538 reset (); 539 540 p = memset (u2.buf + off, '\0', 15); 541 if (p != u2.buf + off) abort (); 542 check (off, 15, '\0'); 543 544 p = memset (u2.buf + off, A, 15); 545 if (p != u2.buf + off) abort (); 546 check (off, 15, 'A'); 547 548 p = memset (u2.buf + off, 'B', 15); 549 if (p != u2.buf + off) abort (); 550 check (off, 15, 'B'); 551 } 552} 553 554void 555__attribute__((noinline)) 556test6 (void) 557{ 558 int len; 559 char *p; 560 561 /* off == 0 */ 562 for (len = 0; len < MAX_COPY2; len++) 563 { 564 reset (); 565 566 p = memset (u2.buf, '\0', len); 567 if (p != u2.buf) abort (); 568 check (0, len, '\0'); 569 570 p = memset (u2.buf, A, len); 571 if (p != u2.buf) abort (); 572 check (0, len, 'A'); 573 574 p = memset (u2.buf, 'B', len); 575 if (p != u2.buf) abort (); 576 check (0, len, 'B'); 577 } 578 579 /* off == 1 */ 580 for (len = 0; len < MAX_COPY2; len++) 581 { 582 reset (); 583 584 p = memset (u2.buf+1, '\0', len); 585 if (p != u2.buf+1) abort (); 586 check (1, len, '\0'); 587 588 p = memset (u2.buf+1, A, len); 589 if (p != u2.buf+1) abort (); 590 check (1, len, 'A'); 591 592 p = memset (u2.buf+1, 'B', len); 593 if (p != u2.buf+1) abort (); 594 check (1, len, 'B'); 595 } 596 597 /* off == 2 */ 598 for (len = 0; len < MAX_COPY2; len++) 599 { 600 reset (); 601 602 p = memset (u2.buf+2, '\0', len); 603 if (p != u2.buf+2) abort (); 604 check (2, len, '\0'); 605 606 p = memset (u2.buf+2, A, len); 607 if (p != u2.buf+2) abort (); 608 check (2, len, 'A'); 609 610 p = memset (u2.buf+2, 'B', len); 611 if (p != u2.buf+2) abort (); 612 check (2, len, 'B'); 613 } 614 615 /* off == 3 */ 616 for (len = 0; len < MAX_COPY2; len++) 617 { 618 reset (); 619 620 p = memset (u2.buf+3, '\0', len); 621 if (p != u2.buf+3) abort (); 622 check (3, len, '\0'); 623 624 p = memset (u2.buf+3, A, len); 625 if (p != u2.buf+3) abort (); 626 check (3, len, 'A'); 627 628 p = memset (u2.buf+3, 'B', len); 629 if (p != u2.buf+3) abort (); 630 check (3, len, 'B'); 631 } 632 633 /* off == 4 */ 634 for (len = 0; len < MAX_COPY2; len++) 635 { 636 reset (); 637 638 p = memset (u2.buf+4, '\0', len); 639 if (p != u2.buf+4) abort (); 640 check (4, len, '\0'); 641 642 p = memset (u2.buf+4, A, len); 643 if (p != u2.buf+4) abort (); 644 check (4, len, 'A'); 645 646 p = memset (u2.buf+4, 'B', len); 647 if (p != u2.buf+4) abort (); 648 check (4, len, 'B'); 649 } 650 651 /* off == 5 */ 652 for (len = 0; len < MAX_COPY2; len++) 653 { 654 reset (); 655 656 p = memset (u2.buf+5, '\0', len); 657 if (p != u2.buf+5) abort (); 658 check (5, len, '\0'); 659 660 p = memset (u2.buf+5, A, len); 661 if (p != u2.buf+5) abort (); 662 check (5, len, 'A'); 663 664 p = memset (u2.buf+5, 'B', len); 665 if (p != u2.buf+5) abort (); 666 check (5, len, 'B'); 667 } 668 669 /* off == 6 */ 670 for (len = 0; len < MAX_COPY2; len++) 671 { 672 reset (); 673 674 p = memset (u2.buf+6, '\0', len); 675 if (p != u2.buf+6) abort (); 676 check (6, len, '\0'); 677 678 p = memset (u2.buf+6, A, len); 679 if (p != u2.buf+6) abort (); 680 check (6, len, 'A'); 681 682 p = memset (u2.buf+6, 'B', len); 683 if (p != u2.buf+6) abort (); 684 check (6, len, 'B'); 685 } 686 687 /* off == 7 */ 688 for (len = 0; len < MAX_COPY2; len++) 689 { 690 reset (); 691 692 p = memset (u2.buf+7, '\0', len); 693 if (p != u2.buf+7) abort (); 694 check (7, len, '\0'); 695 696 p = memset (u2.buf+7, A, len); 697 if (p != u2.buf+7) abort (); 698 check (7, len, 'A'); 699 700 p = memset (u2.buf+7, 'B', len); 701 if (p != u2.buf+7) abort (); 702 check (7, len, 'B'); 703 } 704} 705 706void 707main_test (void) 708{ 709#ifndef __OPTIMIZE__ 710 /* Object size checking is only intended for -O[s123]. */ 711 return; 712#endif 713 __asm ("" : "=r" (l1) : "0" (l1)); 714 s4 = buffer; 715 test1 (); 716 test2 (); 717 test3 (); 718 test4 (); 719 test5 (); 720 test6 (); 721} 722