Changeset dd50aa19 in mainline


Ignore:
Timestamp:
2024-09-12T12:35:23Z (2 months ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master
Children:
899bdfd
Parents:
2ee6351
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2024-09-11 13:51:11)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2024-09-12 12:35:23)
Message:

Allocation function tweaks

  • Add reallocarray() from POSIX 2024 for overflow-safe reallocations.
  • Make realloc(x, 0) act as realloc(x, 1), and print an error message because it's unspecified behavior. Previous handling of realloc(x, 0) as free(x) is problematic, because proper realloc use will mistake it for failure if the case isn't specifically checked for, leading to double-free.
  • Make malloc(0) act as malloc(1), since it "just works" when code forgets to specifically check for zero in cases where zero length is meaningful.
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • common/include/stdlib.h

    r2ee6351 rdd50aa19  
    122122    __attribute__((malloc));
    123123
     124extern void *reallocarray(void *ptr, size_t nelem, size_t elsize)
     125    __attribute__((warn_unused_result));
     126
    124127__HELENOS_DECLS_END;
    125128#endif
  • kernel/generic/src/mm/malloc.c

    r2ee6351 rdd50aa19  
    211211void *realloc(void *old_obj, size_t new_size)
    212212{
     213        if (new_size == 0)
     214                new_size = 1;
     215
    213216        if (!old_obj)
    214217                return malloc(new_size);
  • uspace/lib/c/generic/malloc.c

    r2ee6351 rdd50aa19  
    3838#include <stdbool.h>
    3939#include <stddef.h>
     40#include <stdio.h>
    4041#include <as.h>
    4142#include <align.h>
     
    725726 *
    726727 */
    727 static void *malloc_internal(const size_t size, const size_t align)
     728static void *malloc_internal(size_t size, size_t align)
    728729{
    729730        malloc_assert(first_heap_area != NULL);
    730731
     732        if (size == 0)
     733                size = 1;
     734
    731735        if (align == 0)
    732                 return NULL;
     736                align = BASE_ALIGN;
    733737
    734738        size_t falign = lcm(align, BASE_ALIGN);
     
    821825 *
    822826 */
    823 void *realloc(void *const addr, const size_t size)
     827void *realloc(void *const addr, size_t size)
    824828{
    825829        if (size == 0) {
    826                 free(addr);
    827                 return NULL;
     830                fprintf(stderr, "realloc() called with size 0\n");
     831                size = 1;
    828832        }
    829833
     
    930934}
    931935
     936/** Reallocate memory for an array
     937 *
     938 * Same as realloc(ptr, nelem * elsize), except the multiplication is checked
     939 * for numerical overflow. Borrowed from POSIX 2024.
     940 *
     941 * @param ptr
     942 * @param nelem
     943 * @param elsize
     944 *
     945 * @return Reallocated memory or NULL.
     946 */
     947void *reallocarray(void *ptr, size_t nelem, size_t elsize)
     948{
     949        if (nelem > SIZE_MAX / elsize)
     950                return NULL;
     951
     952        return realloc(ptr, nelem * elsize);
     953}
     954
    932955/** Free a memory block
    933956 *
Note: See TracChangeset for help on using the changeset viewer.