1. 26
  1.  

  2. 12

    jemalloc, ptmalloc, nedmalloc, … are all using per thread memory pools, while musl uses a global lock

    Most high-end general-purpose memory allocators use a per-thread cache, object allocated from which can later be migrated to the global heap. (This was the primary innovation of jemalloc; finding a good compromise between the resistance to fragmentation provided by a single global allocator and the speed of a full per-thread heap. It was built upon by tcmalloc—lit. ‘thread caching malloc’—and others, and I expect recent versions of ptmalloc2 have similar optimizations as well.)

    Development practises

    musl’s development is pretty old school: a mailing list for bug tracker, a cgit repository, no continuous builds nor integrations with static analysers like coverity or LGTM, … meh

    And this matters why?

    Generally better than glibc

    I’m not sure how they arrived at this conclusion. From the feature lists they quoted, it sounds to me like glibc wins. Particularly because of the atexit/longjmp hardening.

    Nowadays, the only reasonable usage of the %n specifier in printf and its friends is to mount format-string attacks. But since musl aims at being as compliant as possible, this specifier is unfortunately implemented and available.

    A good compromise would be to have an run- or build-time toggle to enable it, and default to leaving it off.

    1. 7

      Is there any good reason not to run a few static analysers regularly these days? I would be surprised if they produce too many false positives to no the useful.

      On %n, I would expect most compilers to warn about its usage these days, in the little C I’ve written lately the compiler was very keen to correct my format strings.

      1. 4

        I can’t find any evidence that the musl project is fuzzing, either. That’s concerning from a security perspective.

      2. 1

        Most high-end general-purpose memory allocators use a per-thread cache

        Yes, however they also use multiple arenas rather than a single global heap. Even glibc malloc does so.

        So “per thread memory pools” still isn’t 100% correct, but multiple memory pools are used in addition to per-thread and/or per-CPU caches.

      3. 7

        Support for %n Nowadays, the only reasonable usage of the %n specifier in printf and its friends is to mount format-string attacks. But since musl aims at being as compliant as possible, this specifier is unfortunately implemented and available.

        Another answer is to not support %n by default like Visual Studio.

        Because the %n format is inherently insecure, it is disabled by default. If %n is encountered in a format string, the invalid parameter handler is invoked, as described in Parameter Validation. To enable %n support, see _set_printf_count_output.

        A few applications that require %n add an #ifdef and everyone else has one fewer vulnerability to worry about.

        Edited to fix link per child post post.

        1. 3

          I have actually used %n in real code 20+ years ago. It was used in a tokenizer for a little language and inside sscanf we used it to track how far into the input we’d been able to tokenize.

          I didn’t say it was good code…

        2. 2

          also known as memset_explicit() or memset_s() in other libc

          Note that memset_s isn’t just an “other libc” thing, it’s part of the C11 standard.

          1. 1

            To be clear, it is part of the optional Annex K, which has a number of problems and MSVC is the only major implementation to support it: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm#impementations

            So I think it’s fair to call it an “other libc” thing.

            1. 2

              MSVC doesn’t even support it; they implement a pre-specification version of it, and they refuse to update their implementation due to backwards compatibility.

              That said, however, though annex K is maligned, memset_s has seen wider adoption and interest. There have been talks in WG14 to standardize (but not the rest of annex k); or to standardize another function with equivalent behaviour. FreeBSD implements memset_s, but none of the other annex K functions.

              1. 1

                There have been talks in WG14 to standardize the function itself; or to standardize another function with equivalent behaviour.

                I’d be very happy to see that. For anyone interested, it looks like the most recent document is http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2599.htm