(root)/
glibc-2.38/
stdio-common/
bug-vfprintf-nargs.c
       1  /* Test for vfprintf nargs allocation overflow (BZ #13656).
       2     Copyright (C) 2012-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <stdio.h>
      20  #include <stdlib.h>
      21  #include <stdint.h>
      22  #include <unistd.h>
      23  #include <inttypes.h>
      24  #include <string.h>
      25  #include <signal.h>
      26  
      27  static int
      28  format_failed (const char *fmt, const char *expected)
      29  {
      30    char output[80];
      31  
      32    printf ("%s : ", fmt);
      33  
      34    memset (output, 0, sizeof output);
      35    /* Having sprintf itself detect a failure is good.  */
      36    if (sprintf (output, fmt, 1, 2, 3, "test") > 0
      37        && strcmp (output, expected) != 0)
      38      {
      39        printf ("FAIL (output '%s' != expected '%s')\n", output, expected);
      40        return 1;
      41      }
      42    puts ("ok");
      43    return 0;
      44  }
      45  
      46  static int
      47  do_test (void)
      48  {
      49    int rc = 0;
      50    char buf[64];
      51  
      52    /* Regular positionals work.  */
      53    if (format_failed ("%1$d", "1") != 0)
      54      rc = 1;
      55  
      56    /* Regular width positionals work.  */
      57    if (format_failed ("%1$*2$d", " 1") != 0)
      58      rc = 1;
      59  
      60    /* Positional arguments are constructed via read_int, so nargs can only
      61       overflow on 32-bit systems.  On 64-bit systems, it will attempt to
      62       allocate a giant amount of memory and possibly crash, which is the
      63       expected situation.  Since the 64-bit behavior is arch-specific, only
      64       test this on 32-bit systems.  */
      65    if (sizeof (long int) == 4)
      66      {
      67        sprintf (buf, "%%1$d %%%" PRIdPTR "$d",
      68  	       (intptr_t) (UINT32_MAX / sizeof (int)));
      69        if (format_failed (buf, "1 %$d") != 0)
      70          rc = 1;
      71      }
      72  
      73    return rc;
      74  }
      75  
      76  #define TEST_FUNCTION do_test ()
      77  #include "../test-skeleton.c"