(root)/
glibc-2.38/
posix/
tst-glob-tilde.c
       1  /* Check for GLOB_TIDLE heap allocation issues (bugs 22320, 22325, 22332).
       2     Copyright (C) 2017-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 <glob.h>
      20  #include <mcheck.h>
      21  #include <nss.h>
      22  #include <pwd.h>
      23  #include <stdlib.h>
      24  #include <string.h>
      25  #include <support/check.h>
      26  #include <support/support.h>
      27  
      28  /* Flag which indicates whether to pass the GLOB_ONLYDIR flag.  */
      29  static int do_onlydir;
      30  
      31  /* Flag which indicates whether to pass the GLOB_NOCHECK flag.  */
      32  static int do_nocheck;
      33  
      34  /* Flag which indicates whether to pass the GLOB_MARK flag.  */
      35  static int do_mark;
      36  
      37  /* Flag which indicates whether to pass the GLOB_NOESCAPE flag.  */
      38  static int do_noescape;
      39  
      40  static void
      41  one_test (const char *prefix, const char *middle, const char *suffix)
      42  {
      43    char *pattern = xasprintf ("%s%s%s", prefix, middle, suffix);
      44    int flags = GLOB_TILDE;
      45    if (do_onlydir)
      46      flags |= GLOB_ONLYDIR;
      47    if (do_nocheck)
      48      flags |= GLOB_NOCHECK;
      49    if (do_mark)
      50      flags |= GLOB_MARK;
      51    if (do_noescape)
      52      flags |= GLOB_NOESCAPE;
      53    glob_t gl;
      54    /* This glob call might result in crashes or memory leaks.  */
      55    if (glob (pattern, flags, NULL, &gl) == 0)
      56      globfree (&gl);
      57    free (pattern);
      58  }
      59  
      60  enum
      61    {
      62      /* The largest base being tested.  */
      63      largest_base_size = 500000,
      64  
      65      /* The actual size is the base size plus a variable whose absolute
      66         value is not greater than this.  This helps malloc to trigger
      67         overflows.  */
      68      max_size_skew = 16,
      69  
      70      /* The maximum string length supported by repeating_string
      71         below.  */
      72      repeat_size = largest_base_size + max_size_skew,
      73    };
      74  
      75  /* Used to construct strings which repeat a single character 'x'.  */
      76  static char *repeat;
      77  
      78  /* Return a string of SIZE characters.  */
      79  const char *
      80  repeating_string (int size)
      81  {
      82    TEST_VERIFY (size >= 0);
      83    TEST_VERIFY (size <= repeat_size);
      84    const char *repeated_shifted = repeat + repeat_size - size;
      85    TEST_VERIFY (strlen (repeated_shifted) == size);
      86    return repeated_shifted;
      87  }
      88  
      89  static int
      90  do_test (void)
      91  {
      92    /* Avoid network-based NSS modules and initialize nss_files with a
      93       dummy lookup.  This has to come before mtrace because NSS does
      94       not free all memory.  */
      95    __nss_configure_lookup ("passwd", "files");
      96    (void) getpwnam ("root");
      97  
      98    mtrace ();
      99  
     100    repeat = xmalloc (repeat_size + 1);
     101    memset (repeat, 'x', repeat_size);
     102    repeat[repeat_size] = '\0';
     103  
     104    /* These numbers control the size of the user name.  The values
     105       cover the minimum (0), a typical size (8), a large
     106       stack-allocated size (100000), and a somewhat large
     107       heap-allocated size (largest_base_size).  */
     108    static const int base_sizes[] = { 0, 8, 100, 100000, largest_base_size, -1 };
     109  
     110    for (do_onlydir = 0; do_onlydir < 2; ++do_onlydir)
     111      for (do_nocheck = 0; do_nocheck < 2; ++do_nocheck)
     112        for (do_mark = 0; do_mark < 2; ++do_mark)
     113  	for (do_noescape = 0; do_noescape < 2; ++do_noescape)
     114  	  for (int base_idx = 0; base_sizes[base_idx] >= 0; ++base_idx)
     115  	    {
     116  	      for (int size_skew = -max_size_skew; size_skew <= max_size_skew;
     117  		   ++size_skew)
     118  		{
     119  		  int size = base_sizes[base_idx] + size_skew;
     120  		  if (size < 0)
     121  		    continue;
     122  
     123  		  const char *user_name = repeating_string (size);
     124  		  one_test ("~", user_name, "/a/b");
     125  		  one_test ("~", user_name, "x\\x\\x////x\\a");
     126  		}
     127  
     128  	      const char *user_name = repeating_string (base_sizes[base_idx]);
     129  	      one_test ("~", user_name, "");
     130  	      one_test ("~", user_name, "/");
     131  	      one_test ("~", user_name, "/a");
     132  	      one_test ("~", user_name, "/*/*");
     133  	      one_test ("~", user_name, "\\/");
     134  	      one_test ("/~", user_name, "");
     135  	      one_test ("*/~", user_name, "/a/b");
     136  	    }
     137  
     138    free (repeat);
     139  
     140    return 0;
     141  }
     142  
     143  #define TIMEOUT 200
     144  #include <support/test-driver.c>