1  /* Test for posix_memalign.
       2     Copyright (C) 2013-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 <errno.h>
      20  #include <stdlib.h>
      21  #include <stdio.h>
      22  #include <string.h>
      23  #include <unistd.h>
      24  #include <libc-diag.h>
      25  
      26  static int errors = 0;
      27  
      28  static void
      29  merror (const char *msg)
      30  {
      31    ++errors;
      32    printf ("Error: %s\n", msg);
      33  }
      34  
      35  static int
      36  do_test (void)
      37  {
      38    void *p;
      39    int ret;
      40    unsigned long pagesize = getpagesize ();
      41    unsigned long ptrval;
      42  
      43    p = NULL;
      44  
      45    DIAG_PUSH_NEEDS_COMMENT;
      46  #if __GNUC_PREREQ (7, 0)
      47    /* GCC 7 warns about too-large allocations; here we want to test
      48       that they fail.  */
      49    DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
      50  #endif
      51    /* An attempt to allocate a huge value should return ENOMEM and
      52       p should remain NULL.  */
      53    ret = posix_memalign (&p, sizeof (void *), -1);
      54  #if __GNUC_PREREQ (7, 0)
      55    DIAG_POP_NEEDS_COMMENT;
      56  #endif
      57  
      58    if (ret != ENOMEM)
      59      merror ("posix_memalign (&p, sizeof (void *), -1) succeeded.");
      60  
      61    if (ret == ENOMEM && p != NULL)
      62      merror ("returned an error but pointer was modified");
      63  
      64    free (p);
      65  
      66    p = NULL;
      67  
      68    /* Test to expose integer overflow in malloc internals from BZ #15857.  */
      69    ret = posix_memalign (&p, pagesize, -pagesize);
      70  
      71    if (ret != ENOMEM)
      72      merror ("posix_memalign (&p, pagesize, -pagesize) succeeded.");
      73  
      74    free (p);
      75  
      76    p = NULL;
      77  
      78    /* Test to expose integer overflow in malloc internals from BZ #16038.  */
      79    ret = posix_memalign (&p, -1, pagesize);
      80  
      81    if (ret != EINVAL)
      82      merror ("posix_memalign (&p, -1, pagesize) succeeded.");
      83  
      84    free (p);
      85  
      86    p = NULL;
      87  
      88    /* A zero-sized allocation should succeed with glibc, returning zero
      89       and setting p to a non-NULL value.  */
      90    ret = posix_memalign (&p, sizeof (void *), 0);
      91  
      92    if (ret != 0 || p == NULL)
      93      merror ("posix_memalign (&p, sizeof (void *), 0) failed.");
      94  
      95    free (p);
      96  
      97    ret = posix_memalign (&p, 0x300, 10);
      98  
      99    if (ret != EINVAL)
     100      merror ("posix_memalign (&p, 0x300, 10) succeeded.");
     101  
     102    ret = posix_memalign (&p, 0, 10);
     103  
     104    if (ret != EINVAL)
     105      merror ("posix_memalign (&p, 0, 10) succeeded.");
     106  
     107    p = NULL;
     108  
     109    ret = posix_memalign (&p, 0x100, 10);
     110  
     111    if (ret != 0)
     112      merror ("posix_memalign (&p, 0x100, 10) failed.");
     113  
     114    if (ret == 0 && p == NULL)
     115      merror ("returned success but pointer is NULL");
     116  
     117    ptrval = (unsigned long) p;
     118  
     119    if (ret == 0 && (ptrval & 0xff) != 0)
     120      merror ("pointer is not aligned to 0x100");
     121  
     122    free (p);
     123  
     124    return errors != 0;
     125  }
     126  
     127  #define TEST_FUNCTION do_test ()
     128  #include "../test-skeleton.c"