(linenum→info "unix/slp.c:2238")

glibc/2.7/debug/test-strcpy_chk.c

    1: /* Test and measure __strcpy_chk functions.
    2:    Copyright (C) 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
    3:    This file is part of the GNU C Library.
    4:    Written by Jakub Jelinek <jakub@redhat.com>, 1999.
    5: 
    6:    The GNU C Library is free software; you can redistribute it and/or
    7:    modify it under the terms of the GNU Lesser General Public
    8:    License as published by the Free Software Foundation; either
    9:    version 2.1 of the License, or (at your option) any later version.
   10: 
   11:    The GNU C Library is distributed in the hope that it will be useful,
   12:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   13:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:    Lesser General Public License for more details.
   15: 
   16:    You should have received a copy of the GNU Lesser General Public
   17:    License along with the GNU C Library; if not, write to the Free
   18:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   19:    02111-1307 USA.  */
   20: 
   21: #ifndef STRCPY_RESULT
   22: # define STRCPY_RESULT(dst, len) dst
   23: # define TEST_MAIN
   24: # include "../string/test-string.h"
   25: 
   26: extern void __attribute__ ((noreturn)) __chk_fail (void);
   27: char *simple_strcpy_chk (char *, const char *, size_t);
   28: extern char *normal_strcpy (char *, const char *, size_t)
   29:   __asm ("strcpy");
   30: extern char *__strcpy_chk (char *, const char *, size_t);
   31: 
   32: IMPL (simple_strcpy_chk, 0)
   33: IMPL (normal_strcpy, 1)
   34: IMPL (__strcpy_chk, 2)
   35: 
   36: char *
   37: simple_strcpy_chk (char *dst, const char *src, size_t len)
   38: {
   39:   char *ret = dst;
   40:   if (! len)
   41:     __chk_fail ();
   42:   while ((*dst++ = *src++) != '\0')
   43:     if (--len == 0)
   44:       __chk_fail ();
   45:   return ret;
   46: }
   47: #endif
   48: 
   49: #include <fcntl.h>
   50: #include <paths.h>
   51: #include <setjmp.h>
   52: #include <signal.h>
   53: 
   54: volatile int chk_fail_ok;
   55: jmp_buf chk_fail_buf;
   56: 
   57: static void
   58: handler (int sig)
   59: {
   60:   if (chk_fail_ok)
   61:     {
   62:       chk_fail_ok = 0;
   63:       longjmp (chk_fail_buf, 1);
   64:     }
   65:   else
   66:     _exit (127);
   67: }
   68: 
   69: typedef char *(*proto_t) (char *, const char *, size_t);
   70: 
   71: static void
   72: do_one_test (impl_t *impl, char *dst, const char *src,
   73:              size_t len, size_t dlen)
   74: {
   75:   char *res;
   76:   if (dlen <= len)
   77:     {
   78:       if (impl->test == 1)
   79:         return;
   80: 
   81:       chk_fail_ok = 1;
   82:       if (setjmp (chk_fail_buf) == 0)
   83:         {
   84:           res = CALL (impl, dst, src, dlen);
   85:           printf ("*** Function %s (%zd; %zd) did not __chk_fail\n",
   86:                   impl->name, len, dlen);
   87:           chk_fail_ok = 0;
   88:           ret = 1;
   89:         }
   90:       return;
   91:     }
   92:   else
   93:     res = CALL (impl, dst, src, dlen);
   94: 
   95:   if (res != STRCPY_RESULT (dst, len))
   96:     {
   97:       printf ("Wrong result in function %s %p %p\n", impl->name,
   98:               res, STRCPY_RESULT (dst, len));
   99:       ret = 1;
  100:       return;
  101:     }
  102: 
  103:   if (strcmp (dst, src) != 0)
  104:     {
  105:       printf ("Wrong result in function %s dst \"%s\" src \"%s\"\n",
  106:               impl->name, dst, src);
  107:       ret = 1;
  108:       return;
  109:     }
  110: 
  111:   if (HP_TIMING_AVAIL)
  112:     {
  113:       hp_timing_t start __attribute ((unused));
  114:       hp_timing_t stop __attribute ((unused));;
  115:       hp_timing_t best_time = ~ (hp_timing_t) 0;
  116:       size_t i;
  117: 
  118:       for (i = 0; i < 32; ++i)
  119:         {
  120:           HP_TIMING_NOW (start);
  121:           CALL (impl, dst, src, dlen);
  122:           HP_TIMING_NOW (stop);
  123:           HP_TIMING_BEST (best_time, start, stop);
  124:         }
  125: 
  126:       printf ("\t%zd", (size_t) best_time);
  127:     }
  128: }
  129: 
  130: static void
  131: do_test (size_t align1, size_t align2, size_t len, size_t dlen, int max_char)
  132: {
  133:   size_t i;
  134:   char *s1, *s2;
  135: 
  136:   align1 &= 7;
  137:   if (align1 + len >= page_size)
  138:     return;
  139: 
  140:   align2 &= 7;
  141:   if (align2 + len >= page_size)
  142:     return;
  143: 
  144:   s1 = (char *) buf1 + align1;
  145:   s2 = (char *) buf2 + align2;
  146: 
  147:   for (i = 0; i < len; i++)
  148:     s1[i] = 32 + 23 * i % (max_char - 32);
  149:   s1[len] = 0;
  150: 
  151:   if (HP_TIMING_AVAIL && dlen > len)
  152:     printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
  153: 
  154:   FOR_EACH_IMPL (impl, 0)
  155:     do_one_test (impl, s2, s1, len, dlen);
  156: 
  157:   if (HP_TIMING_AVAIL && dlen > len)
  158:     putchar ('\n');
  159: }
  160: 
  161: static void
  162: do_random_tests (void)
  163: {
  164:   size_t i, j, n, align1, align2, len, dlen;
  165:   unsigned char *p1 = buf1 + page_size - 512;
  166:   unsigned char *p2 = buf2 + page_size - 512;
  167:   unsigned char *res;
  168: 
  169:   for (n = 0; n < ITERATIONS; n++)
  170:     {
  171:       align1 = random () & 31;
  172:       if (random () & 1)
  173:         align2 = random () & 31;
  174:       else
  175:         align2 = align1 + (random () & 24);
  176:       len = random () & 511;
  177:       j = align1;
  178:       if (align2 > j)
  179:         j = align2;
  180:       if (len + j >= 511)
  181:         len = 510 - j - (random () & 7);
  182:       j = len + align1 + 64;
  183:       if (j > 512)
  184:         j = 512;
  185:       for (i = 0; i < j; i++)
  186:         {
  187:           if (i == len + align1)
  188:             p1[i] = 0;
  189:           else
  190:             {
  191:               p1[i] = random () & 255;
  192:               if (i >= align1 && i < len + align1 && !p1[i])
  193:                 p1[i] = (random () & 127) + 3;
  194:             }
  195:         }
  196: 
  197:       switch (random () & 7)
  198:         {
  199:         case 0:
  200:           dlen = len - (random () & 31);
  201:           if (dlen > len)
  202:             dlen = len;
  203:           break;
  204:         case 1:
  205:           dlen = (size_t) -1;
  206:           break;
  207:         case 2:
  208:           dlen = len + 1 + (random () & 65535);
  209:           break;
  210:         case 3:
  211:           dlen = len + 1 + (random () & 255);
  212:           break;
  213:         case 4:
  214:           dlen = len + 1 + (random () & 31);
  215:           break;
  216:         case 5:
  217:           dlen = len + 1 + (random () & 7);
  218:           break;
  219:         case 6:
  220:           dlen = len + 1 + (random () & 3);
  221:           break;
  222:         default:
  223:           dlen = len + 1;
  224:           break;
  225:         }
  226: 
  227:       FOR_EACH_IMPL (impl, 1)
  228:         {
  229:           if (dlen <= len)
  230:             {
  231:               if (impl->test != 1)
  232:                 {
  233:                   chk_fail_ok = 1;
  234:                   if (setjmp (chk_fail_buf) == 0)
  235:                     {
  236:                       res = (unsigned char *)
  237:                             CALL (impl, (char *) p2 + align2,
  238:                                   (char *) p1 + align1, dlen);
  239:                       printf ("Iteration %zd - did not __chk_fail\n", n);
  240:                       chk_fail_ok = 0;
  241:                       ret = 1;
  242:                     }
  243:                 }
  244:               continue;
  245:             }
  246:           memset (p2 - 64, '\1', 512 + 64);
  247:           res = (unsigned char *)
  248:                 CALL (impl, (char *) p2 + align2, (char *) p1 + align1, dlen);
  249:           if (res != STRCPY_RESULT (p2 + align2, len))
  250:             {
  251:               printf ("\
  252: Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p\n",
  253:                       n, impl->name, align1, align2, len, res,
  254:                       STRCPY_RESULT (p2 + align2, len));
  255:               ret = 1;
  256:             }
  257:           for (j = 0; j < align2 + 64; ++j)
  258:             {
  259:               if (p2[j - 64] != '\1')
  260:                 {
  261:                   printf ("\
  262: Iteration %zd - garbage before, %s (%zd, %zd, %zd)\n",
  263:                           n, impl->name, align1, align2, len);
  264:                   ret = 1;
  265:                   break;
  266:                 }
  267:             }
  268:           for (j = align2 + len + 1; j < 512; ++j)
  269:             {
  270:               if (p2[j] != '\1')
  271:                 {
  272:                   printf ("\
  273: Iteration %zd - garbage after, %s (%zd, %zd, %zd)\n",
  274:                           n, impl->name, align1, align2, len);
  275:                   ret = 1;
  276:                   break;
  277:                 }
  278:             }
  279:           if (memcmp (p1 + align1, p2 + align2, len + 1))
  280:             {
  281:               printf ("\
  282: Iteration %zd - different strings, %s (%zd, %zd, %zd)\n",
  283:                       n, impl->name, align1, align2, len);
  284:               ret = 1;
  285:             }
  286:         }
  287:     }
  288: }
  289: 
  290: int
  291: test_main (void)
  292: {
  293:   size_t i;
  294: 
  295:   struct sigaction sa;
  296:   sa.sa_handler = handler;
  297:   sa.sa_flags = 0;
  298:   sigemptyset (&sa.sa_mask);
  299: 
  300:   sigaction (SIGABRT, &sa, NULL);
  301: 
  302:   /* Avoid all the buffer overflow messages on stderr.  */
  303:   int fd = open (_PATH_DEVNULL, O_WRONLY);
  304:   if (fd == -1)
  305:     close (STDERR_FILENO);
  306:   else
  307:     {
  308:       dup2 (fd, STDERR_FILENO);
  309:       close (fd);
  310:     }
  311:   setenv ("LIBC_FATAL_STDERR_", "1", 1);
  312: 
  313:   test_init ();
  314: 
  315:   printf ("%23s", "");
  316:   FOR_EACH_IMPL (impl, 0)
  317:     printf ("\t%s", impl->name);
  318:   putchar ('\n');
  319: 
  320:   for (i = 0; i < 16; ++i)
  321:     {
  322:       do_test (0, 0, i, i + 1, 127);
  323:       do_test (0, 0, i, i + 1, 255);
  324:       do_test (0, i, i, i + 1, 127);
  325:       do_test (i, 0, i, i + 1, 255);
  326:     }
  327: 
  328:   for (i = 1; i < 8; ++i)
  329:     {
  330:       do_test (0, 0, 8 << i, (8 << i) + 1, 127);
  331:       do_test (8 - i, 2 * i, (8 << i), (8 << i) + 1, 127);
  332:     }
  333: 
  334:   for (i = 1; i < 8; ++i)
  335:     {
  336:       do_test (i, 2 * i, (8 << i), (8 << i) + 1, 127);
  337:       do_test (2 * i, i, (8 << i), (8 << i) + 1, 255);
  338:       do_test (i, i, (8 << i), (8 << i) + 1, 127);
  339:       do_test (i, i, (8 << i), (8 << i) + 1, 255);
  340:     }
  341: 
  342:   for (i = 0; i < 16; ++i)
  343:     {
  344:       do_test (0, 0, i, i + 256, 127);
  345:       do_test (0, 0, i, i + 256, 255);
  346:       do_test (0, i, i, i + 256, 127);
  347:       do_test (i, 0, i, i + 256, 255);
  348:     }
  349: 
  350:   for (i = 1; i < 8; ++i)
  351:     {
  352:       do_test (0, 0, 8 << i, (8 << i) + 256, 127);
  353:       do_test (8 - i, 2 * i, (8 << i), (8 << i) + 256, 127);
  354:     }
  355: 
  356:   for (i = 1; i < 8; ++i)
  357:     {
  358:       do_test (i, 2 * i, (8 << i), (8 << i) + 256, 127);
  359:       do_test (2 * i, i, (8 << i), (8 << i) + 256, 255);
  360:       do_test (i, i, (8 << i), (8 << i) + 256, 127);
  361:       do_test (i, i, (8 << i), (8 << i) + 256, 255);
  362:     }
  363: 
  364:   for (i = 0; i < 16; ++i)
  365:     {
  366:       do_test (0, 0, i, i, 127);
  367:       do_test (0, 0, i, i + 2, 255);
  368:       do_test (0, i, i, i + 3, 127);
  369:       do_test (i, 0, i, i + 4, 255);
  370:     }
  371: 
  372:   for (i = 1; i < 8; ++i)
  373:     {
  374:       do_test (0, 0, 8 << i, (8 << i) - 15, 127);
  375:       do_test (8 - i, 2 * i, (8 << i), (8 << i) + 5, 127);
  376:     }
  377: 
  378:   for (i = 1; i < 8; ++i)
  379:     {
  380:       do_test (i, 2 * i, (8 << i), (8 << i) + i, 127);
  381:       do_test (2 * i, i, (8 << i), (8 << i) + (i - 1), 255);
  382:       do_test (i, i, (8 << i), (8 << i) + i + 2, 127);
  383:       do_test (i, i, (8 << i), (8 << i) + i + 3, 255);
  384:     }
  385: 
  386:   do_random_tests ();
  387:   return ret;
  388: }
  389: 
  390: #include "../test-skeleton.c"
Syntax (Markdown)