Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <avWo_yv5znRjCPvO@devuan>
Date: Thu, 12 Nov 2026 13:08:12 +0100
From: Alejandro Colomar <alx+linux-man@...nel.org>
To: Vincent Lefevre <vincent@...c17.net>, 
	Alejandro Colomar <alx@...nel.org>, Rich Felker <dalias@...c.org>, linux-man@...r.kernel.org, 
	libc-alpha@...rceware.org, Walter Harms <wharms@....de>, ~hallyn/shadow@...ts.sr.ht, 
	musl@...ts.openwall.com
Subject: Re: Re: [PATCH v1] man/man3/crypt.3: These functions accept
 many algorithms, not only DES

Hi Vincent,

> Date: 2026-11-12 12:40:33+0100
> From: Vincent Lefevre <vincent@...c17.net>
>
> 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

-- 
<https://www.alejandro-colomar.es>

Download attachment "signature.asc" of type "application/pgp-signature" (834 bytes)

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.