Hacker News new | past | comments | ask | show | jobs | submit login

> Plus, if we wanted to, we could certainly write our own wrapper for malloc that took two arguments and multiplied them together with overflow checking. And in fact if we want an overflow-safe version of realloc, or if we don't want the memory to be zero-initialized, then... we still have to do that.

Like reallocarray(3) does?

    buf = malloc(x * y);
    // becomes
    buf = reallocarray(NULL, x, y);
    
    newbuf = realloc(buf, (x * y));
    // becomes
    newbuf = reallocarray(buf, x, y);



reallocarray(3) looks nifty, but until it's available on a wider, ideally more standard-driven basis than just OpenBSD and FreeBSD, it's likely to not see wide uptake.


It's already gaining adoption outside of the BSDs. OS X/iOS seem to have it as part of their libmalloc. Android Bionic libc has it as part of the code they sync from upstream OpenBSD.

Many open source projects include their own, or simply bundle the OpenBSD implementation:

  * mandoc
  * flex
  * unbound and nsd
  * tor
  * tmux
  * libbsd
  * libressl
  * xorg-xserver
  * ...
The list only continues to grow, several more examples to be found on GitHub.


Darwin (macOS / iOS) is often counted as "one of the BSDs", just a fairly weird one. Big chunks of the standard library are copied from FreeBSD with changes to work on top of Mach.


There's code for it in Darwin's libmalloc, but it's not exposed as API.

reallocarray() has some difficulties as an interface, mostly inherited from realloc(). I'm a bigger fan of reallocarr(), but that's NetBSD only. We (the operating systems community) need to find a consensus here, but I'm not convinced that reallocarray() is that consensus yet.


reallocarray is a very thin layer around realloc. No surprises there. Simple find and replace to bring overflow checking into your code.

reallocarr changes the semantics. Equally easy in new pieces of code and a little harder when converting existing code.


reallocarray(3) is part of the portable OpenBSD compat layer[0], and clocks up at under 10 lines on top of realloc(3):

    #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
    void *reallocarray(void *optr, size_t nmemb, size_t size) {
        if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
             nmemb > 0 && SIZE_MAX / nmemb < size) {
            errno = ENOMEM;
            return NULL;
        }
        return realloc(optr, size * nmemb);
    }
[0] https://github.com/openssh/openssh-portable/blob/master/open...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: