Comment by creata

2 days ago

I don't think that's the problem. The man page for crypt clearly says that erroring is a possibility and that it's not standardized how it errors:

> The behavior of crypt on errors isn't well standardized. Some implementations simply can't fail (except by crashing the program), others return a null pointer or a fixed string. Most implementations don't set errno, but some do. POSIX specifies returning a null pointer and setting errno, but it defines only one possible error, ENOSYS, in the case where crypt is not supported at all.

In my opinion the problem is that the behavior of crypt is underspecified - it isn't even specified how it signals failure, which is shocking.

Another disturbing decision that crypt's signature takes in the hash its output is supposed to be compared against - if it weren't for that, this half-baked "on error the output won't compare equal to the input" measure that crypt and crypt_* use wouldn't have been possible.

You can't check errno to see if there was a failure because, as the man page says, the value of errno is unspecified when crypt succeeds.

    > You can't check errno to see if there was a failure because, as the man page says, the value of errno is unspecified when crypt succeeds.

You can set errno to zero before the call. If the value is non-zero after the call, that is a good heuristic for failure.

  • ...unless crypt() is one of the many, many functions which themselves internally call functions that set errno. In which case you can't be sure.