← Back to context

Comment by cube00

2 days ago

> except a lot of programs never check for NULL. they just compare whatever crypt() gives back with the stored field, hit the NULL, and crash

> so musl (the libc under alpine) goes ok fine, crypt() just won't return NULL anymore. if it fails, it returns a single character instead.

Considering it's been accepted that crashing if malloc returns a NULL is your fault, did musl really feel the need to accommodate bad implementations like this or is this just AI speculation?

"unfortunately, a large portion of programs which call crypt are not prepared for its failure and do not check that the return value is non-null before using it. thus, always "succeeding" but giving an unmatchable hash is reportedly a better behavior than failing on error." [1]

[1] https://git.musl-libc.org/cgit/musl/commit/?id=b3c4cc121f70f...

  • Such a questionable decision! "Rather than let a bug in a caller (not handling the valid null output and thus crashing) surface, let's just silence it and pretend that the caller is correct! A potential clash in some situations (resulting in this vulnerability) is better than a crash!"

    Maybe I should update my plea to fail loudly (https://alejo.ch/3gk) to list this as an example.

    • An interesting thing about C is that there is no guarantee that NULL dereferencing will "surface". It's undefined behavior.

      NetBSD and libxcrypt both have similar workarounds. NetBSD has a paragraph on the reasoning.

         The behavior of crypt() on errors isn't well standardized.  Some imple-
         mentations simply can't fail (unless the process dies, in which case they
         obviously can't return), others return NULL or a fixed string.  Most
         implementations don't set errno, but some do.  Version 2 of the Single
         UNIX Specification (``SUSv2'') specifies only returning NULL and setting
         errno as a valid behavior, and defines only one possible error (ENOSYS,
         ``The functionality is not supported on this implementation.'') Unfortu-
         nately, most existing applications aren't prepared to handle NULL returns
         from crypt().  The description below corresponds to this implementation
         of crypt() only.  The behavior may change to match standards, other
         implementations or existing applications.
      

      OpenBSD and glibc both have similar simple, stupid-free return value implementations. OpenBSD:

          The function crypt() returns a pointer to the encrypted value on success, and NULL on failure.
      

      GNU:

          On success, a pointer to the hashed password is returned.  On
          error, NULL is returned.
      

      The distro I use on the desktop uses libxcrypt, though. Probably more distros are. Its, NetBSD's and musl's workarounds probably make sense in some way if you have no clue what goes into your userland and are willing to write stupid software to accommodate for that.

    • It's always a people problem. Doing a bad patch on my side is easier than bothering anyone else to fix their code

> did musl really feel the need to accommodate bad implementations like this

I don't know about this specific case but in general? Yes, totally. No one is going to fix all existing software that depends on libs behaving exactly as glibc, you have to accept some trade-offs. Either your new implementation stops being perfectly simple and clean, or no one uses it.