Hi Vincent, > Date: 2026-11-12 12:40:33+0100 > From: Vincent Lefevre > > On 2026-11-12 11:28:20 +0100, Alejandro Colomar wrote: > > Yeah, I think it'd be okay to document that this is an extension to > > POSIX. Perhaps, we could add this: > > > > @@ -111,6 +111,9 @@ .SH ATTRIBUTES > > .BR crypt_r () > > T} Thread safety MT-Safe > > .TE > > +.SH VERSIONS > > +While POSIX only specifies the DES algorithms for these functions, > > +all systems implement several other algorithms. > > No, POSIX just says: "The algorithm is implementation-defined." > No mention of DES algorithms at all. Oh right. > And note that only ENOSYS is specified as a case of failure, > which could explain why some applications do not check whether > the returned value is a null pointer (i.e. they assume that if > crypt() succeeds in usual cases, then an ENOSYS error is not > possible and crypt() never fails). > > But my point was that POSIX disallows the "$" character in salt: > > [...] The salt argument shall be a string of at least two bytes > in length not including the null character chosen from the set: > > a b c d e f g h i j k l m n o p q r s t u v w x y z > A B C D E F G H I J K L M N O P Q R S T U V W X Y Z > 0 1 2 3 4 5 6 7 8 9 . / Isn't that salt specification used exclusively by DES? So, while POSIX doesn't specify the algorithm, it is consensus that a call that is strictly conforming to POSIX will result in DES being used. > This means that when "$" is supported by some implementation, > the interpretation of the return value may be different from > what POSIX specifies. Kind of. They better don't deviate from it in non-confirming ways; one could argue that musl's "x" return value is indeed such a non-conforming return value, and a NULL return value would be better (both more conforming and safer). > Various people said that the choice of returning "*" in case of > failure as done by musl was a violation of POSIX. But this is > not true for 2 reasons: > * the use of the "$" character in salt by the application; > * the fact that POSIX does not give any requirement on the > hash (so the use of a hash that could be interpreted as > being invalid on the system for unsupported passwords is > a valid behavior). I think that's a stretch of the undefined behavior. Yes, in theory one has passed an invalid salt, and then anything may happen. But given that POSIX specifies the return value in a way that doesn't seem incompatible with this extension, I think it would be more appropriate to behave in a way that conforms to this specification. Upon successful completion, crypt() shall return a pointer to the hashed password; the first two bytes of the returned value shall be those of the salt argument. Otherwise, it shall return a null pointer and set errno to indicate the error. Given that there's no successfully hashed password, I think it'd be most appropriate to return a null pointer. Have a lovely day! Alex --