Linux Manual Pages development
 help / color / mirror / Atom feed
* RFC: how to document musl-crypt failure ?
@ 2026-11-09  8:59 Walter Harms
  2026-11-09 10:10 ` Alejandro Colomar
  0 siblings, 1 reply; 9+ messages in thread
From: Walter Harms @ 2026-11-09  8:59 UTC (permalink / raw)
  To: linux-man@vger.kernel.org

Hello list,
in case someone missed it: musl crypt() had an documented but unexpected behavier that caused
a lot of trouble. See: https://news.ycombinator.com/item?id=50377221   SSHHole.com  CVE-2026-123158

Normaly i would step over it but in this special case ... it would like to start a discussion if we should mention
that in a note to crypt(). Perhaps recommending an additional check for '*' ? I am not sure but this is a very special case ...

CU 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: RFC: how to document musl-crypt failure ?
  2026-11-09  8:59 RFC: how to document musl-crypt failure ? Walter Harms
@ 2026-11-09 10:10 ` Alejandro Colomar
  2026-11-09 10:23   ` Andreas Schwab
  2026-11-09 13:56   ` [musl] " Rich Felker
  0 siblings, 2 replies; 9+ messages in thread
From: Alejandro Colomar @ 2026-11-09 10:10 UTC (permalink / raw)
  To: Walter Harms
  Cc: linux-man@vger.kernel.org, Rich Felker, libc-alpha, musl,
	~hallyn/shadow

[-- Attachment #1: Type: text/plain, Size: 1178 bytes --]

Hi Walter,

> Date: 2026-11-09 08:59:19+0000
> From: Walter Harms <wharms@bfs.de>
>
> Hello list,
> in case someone missed it: musl crypt() had an documented but
> unexpected behavier that caused a lot of trouble.  See:
> <https://news.ycombinator.com/item?id=50377221>   SSHHole.com  CVE-2026-123158

Indeed, I also wondered if we should change something in the
documentation after it happened.  Unfortunately, the bug has been
treated with some secrecy in the first days (reasonable), so I couldn't
really understand what went wrong.

I've CCed Rich and also musl and glibc, since they probably want to
comment.  I've also CCd shadow-utils.

> Normaly i would step over it but in this special case ... it would
> like to start a discussion if we should mention that in a note to
> crypt().

Thanks!

> Perhaps recommending an additional check for '*' ?  I am not sure but
> this is a very special case ...

Rich, now that some time has passed and I guess everyone has a patched
SSH, would you mind clarifying what happened, and what should be
documented about it?


Have a lovely day!
Alex

> CU 

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: RFC: how to document musl-crypt failure ?
  2026-11-09 10:10 ` Alejandro Colomar
@ 2026-11-09 10:23   ` Andreas Schwab
  2026-11-09 11:24     ` Sam James
  2026-11-09 13:56   ` [musl] " Rich Felker
  1 sibling, 1 reply; 9+ messages in thread
From: Andreas Schwab @ 2026-11-09 10:23 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: Walter Harms, linux-man@vger.kernel.org, Rich Felker, libc-alpha,
	musl, ~hallyn/shadow

On Nov 09 2026, Alejandro Colomar wrote:

> I've CCed Rich and also musl and glibc, since they probably want to
> comment.  I've also CCd shadow-utils.

libcrypt is no longer part of glibc, it is now provided by libxcrypt.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: RFC: how to document musl-crypt failure ?
  2026-11-09 10:23   ` Andreas Schwab
@ 2026-11-09 11:24     ` Sam James
  0 siblings, 0 replies; 9+ messages in thread
From: Sam James @ 2026-11-09 11:24 UTC (permalink / raw)
  To: Andreas Schwab
  Cc: Alejandro Colomar, Walter Harms, linux-man@vger.kernel.org,
	Rich Felker, libc-alpha, musl, ~hallyn/shadow

[-- Attachment #1: Type: text/plain, Size: 781 bytes --]

Andreas Schwab <schwab@suse.de> writes:

> On Nov 09 2026, Alejandro Colomar wrote:
>
>> I've CCed Rich and also musl and glibc, since they probably want to
>> comment.  I've also CCd shadow-utils.
>
> libcrypt is no longer part of glibc, it is now provided by libxcrypt.

Indeed. But while we're here..

For libxcypt, it's determined by the configure option:
--disable-error-tokens. By default, error tokens are enabled.

I've switched Gentoo to use --disable-*. Fedora already did many years
ago so package failures should be smoked out by now:
* https://src.fedoraproject.org/rpms/libxcrypt/c/853ed305cd53c67bb2827dce78b889c8d187e1e0?branch=rawhide
* https://bugzilla.redhat.com/show_bug.cgi?id=1611784

Debian uses the libxcrypt default. I didn't check other distros yet.

sam

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 418 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [musl] Re: RFC: how to document musl-crypt failure ?
  2026-11-09 10:10 ` Alejandro Colomar
  2026-11-09 10:23   ` Andreas Schwab
@ 2026-11-09 13:56   ` Rich Felker
  2026-11-09 15:50     ` Alejandro Colomar
  1 sibling, 1 reply; 9+ messages in thread
From: Rich Felker @ 2026-11-09 13:56 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: Walter Harms, linux-man@vger.kernel.org, libc-alpha, musl,
	~hallyn/shadow

On Mon, Nov 09, 2026 at 11:10:56AM +0100, Alejandro Colomar wrote:
> Hi Walter,
> 
> > Date: 2026-11-09 08:59:19+0000
> > From: Walter Harms <wharms@bfs.de>
> >
> > Hello list,
> > in case someone missed it: musl crypt() had an documented but
> > unexpected behavier that caused a lot of trouble.  See:
> > <https://news.ycombinator.com/item?id=50377221>   SSHHole.com  CVE-2026-123158
> 
> Indeed, I also wondered if we should change something in the
> documentation after it happened.  Unfortunately, the bug has been
> treated with some secrecy in the first days (reasonable), so I couldn't
> really understand what went wrong.
> 
> I've CCed Rich and also musl and glibc, since they probably want to
> comment.  I've also CCd shadow-utils.
> 
> > Normaly i would step over it but in this special case ... it would
> > like to start a discussion if we should mention that in a note to
> > crypt().
> 
> Thanks!
> 
> > Perhaps recommending an additional check for '*' ?  I am not sure but
> > this is a very special case ...
> 
> Rich, now that some time has passed and I guess everyone has a patched
> SSH, would you mind clarifying what happened, and what should be
> documented about it?

Have you seen my full analysis on the musl list?

https://www.openwall.com/lists/musl/2026/11/06/7

The correct usage of crypt for password authentication is asserting
that, if P is the candidate password and H is the account password
"hash", strcmp(crypt(P,H),H)==0. Allowing the user in without checking
that is potentially a password-authentication-bypass bug.

I put "hash" in quotation marks because it might not be an actual
hash; it can be a string chosen by the tooling or a user manually
editing the passwd/shadow files to produce something unmatchable. So
an application should not be making assumptions about its form.

Through at least 1.2.6, musl uses failure tokens "*" and "x" for cases
where the password should never match. These include unsupported
password length (for hash types that need to restrict it) and
unsupported or invalid setting/salt strings.

It isn't decided yet, but 1.2.7 will probably switch to using failure
tokens matching libxcrypt's ("*0" and "*1") which are slightly safer
against some forms of misuse by the caller. Future versions may drop
failure tokens entirely and switch to treating these conditions as
errors (returning null).

I would not document future behavior, and would document existing
behavior only as an implementation detail, not an application-facing
contract. The only contract with the application is that crypt(P,H)
will never return a string identical to H except on valid password (in
the absence of theoretical hash collisions) regardless of the validity
of P and H.

Rich

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [musl] Re: RFC: how to document musl-crypt failure ?
  2026-11-09 13:56   ` [musl] " Rich Felker
@ 2026-11-09 15:50     ` Alejandro Colomar
  2026-11-12 14:37       ` Alejandro Colomar
  0 siblings, 1 reply; 9+ messages in thread
From: Alejandro Colomar @ 2026-11-09 15:50 UTC (permalink / raw)
  To: Rich Felker
  Cc: Walter Harms, linux-man@vger.kernel.org, libc-alpha, musl,
	~hallyn/shadow

[-- Attachment #1: Type: text/plain, Size: 3458 bytes --]

Hi Rich,

> Date: 2026-11-09 08:56:50-0500
> From: Rich Felker <dalias@libc.org>
>
> On Mon, Nov 09, 2026 at 11:10:56AM +0100, Alejandro Colomar wrote:
> > Hi Walter,
> > 
> > > Date: 2026-11-09 08:59:19+0000
> > > From: Walter Harms <wharms@bfs.de>
> > >
> > > Hello list,
> > > in case someone missed it: musl crypt() had an documented but
> > > unexpected behavier that caused a lot of trouble.  See:
> > > <https://news.ycombinator.com/item?id=50377221>   SSHHole.com  CVE-2026-123158
> > 
> > Indeed, I also wondered if we should change something in the
> > documentation after it happened.  Unfortunately, the bug has been
> > treated with some secrecy in the first days (reasonable), so I couldn't
> > really understand what went wrong.
> > 
> > I've CCed Rich and also musl and glibc, since they probably want to
> > comment.  I've also CCd shadow-utils.
> > 
> > > Normaly i would step over it but in this special case ... it would
> > > like to start a discussion if we should mention that in a note to
> > > crypt().
> > 
> > Thanks!
> > 
> > > Perhaps recommending an additional check for '*' ?  I am not sure but
> > > this is a very special case ...
> > 
> > Rich, now that some time has passed and I guess everyone has a patched
> > SSH, would you mind clarifying what happened, and what should be
> > documented about it?
> 
> Have you seen my full analysis on the musl list?
> 
> https://www.openwall.com/lists/musl/2026/11/06/7

Not before, but thanks!  Now I have read it.

I agree with the suggestion of using null+errno in the future, BTW.
FWIW, shadow-utils already handles well a null pointer.

> The correct usage of crypt for password authentication is asserting
> that, if P is the candidate password and H is the account password
> "hash", strcmp(crypt(P,H),H)==0. Allowing the user in without checking
> that is potentially a password-authentication-bypass bug.
> 
> I put "hash" in quotation marks because it might not be an actual
> hash; it can be a string chosen by the tooling or a user manually
> editing the passwd/shadow files to produce something unmatchable. So
> an application should not be making assumptions about its form.
> 
> Through at least 1.2.6, musl uses failure tokens "*" and "x" for cases
> where the password should never match. These include unsupported
> password length (for hash types that need to restrict it) and
> unsupported or invalid setting/salt strings.
> 
> It isn't decided yet, but 1.2.7 will probably switch to using failure
> tokens matching libxcrypt's ("*0" and "*1") which are slightly safer
> against some forms of misuse by the caller.

Ok.  Please CC linux-man@ when that happens.

> Future versions may drop
> failure tokens entirely and switch to treating these conditions as
> errors (returning null).

+1.  Again, please CC linux-man@ when that happens.

> I would not document future behavior, and would document existing
> behavior only as an implementation detail, not an application-facing
> contract. The only contract with the application is that crypt(P,H)
> will never return a string identical to H except on valid password (in
> the absence of theoretical hash collisions) regardless of the validity
> of P and H.

Okay.  Thank you very much!  I'll work on a patch, and CC you when it's
ready.


Have a lovely day!
Alex

> 
> Rich
> 

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [musl] Re: RFC: how to document musl-crypt failure ?
  2026-11-09 15:50     ` Alejandro Colomar
@ 2026-11-12 14:37       ` Alejandro Colomar
  2026-11-12 14:45         ` Rich Felker
  0 siblings, 1 reply; 9+ messages in thread
From: Alejandro Colomar @ 2026-11-12 14:37 UTC (permalink / raw)
  To: Rich Felker
  Cc: Walter Harms, linux-man@vger.kernel.org, libc-alpha, musl,
	~hallyn/shadow

[-- Attachment #1: Type: text/plain, Size: 2110 bytes --]

Hi Rich,

> Date: 2026-11-09 16:51:02+0100
> From: Alejandro Colomar <alx+linux-man@kernel.org>
>
[...]
> > I would not document future behavior, and would document existing
> > behavior only as an implementation detail, not an application-facing
> > contract. The only contract with the application is that crypt(P,H)
> > will never return a string identical to H except on valid password (in
> > the absence of theoretical hash collisions) regardless of the validity
> > of P and H.
> 
> Okay.  Thank you very much!  I'll work on a patch, and CC you when it's
> ready.

What do you think of this?

	diff --git i/man/man3/crypt.3 w/man/man3/crypt.3
	index e0a74b955b3e..4a75fac2f627 100644
	--- i/man/man3/crypt.3
	+++ w/man/man3/crypt.3
	@@ -259,6 +259,28 @@ .SS salt
	 is equal to
	 .I xxx
	 otherwise.
	+.SH EXAMPLES
	+When comparing a password against an existing hash,
	+that hash (and no other) must be passed as
	+.IR salt .
	+If and only if
	+.I salt
	+compares equal
	+(see
	+.BR streq (3))
	+to the returned string,
	+the password matches the existing hash specified by
	+.IR salt .
	+.P
	+.in +4n
	+.EX
	+if (streq(H, crypt(P, H))) {
	+       // good password
	+} else {
	+       // bad password
	+}
	+.EE
	+.in
	 .SH SEE ALSO
	 .BR login (1),
	 .BR passwd (1),

which reads as:

	--- HEAD:man/man3/crypt.3
	+++ ./man/man3/crypt.3
	@@ -152,6 +152,19 @@ NOTES
	      than 1000, 999999999 if xxx is greater than 999999999, and
	      is equal to xxx otherwise.
	 
	+EXAMPLES
	+     When comparing a password against an existing hash, that
	+     hash (and no other) must be passed as salt.  If and only
	+     if salt compares equal (see streq(3)) to the returned
	+     string, the password matches the existing hash specified
	+     by salt.
	+
	+         if (streq(H, crypt(P, H))) {
	+              // good password
	+         } else {
	+              // bad password
	+         }
	+
	 SEE ALSO
	      login(1), passwd(1), encrypt(3), getpass(3), passwd(5)
	 

Cheers,
Alex

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [musl] Re: RFC: how to document musl-crypt failure ?
  2026-11-12 14:37       ` Alejandro Colomar
@ 2026-11-12 14:45         ` Rich Felker
  2026-11-12 15:01           ` Alejandro Colomar
  0 siblings, 1 reply; 9+ messages in thread
From: Rich Felker @ 2026-11-12 14:45 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: Walter Harms, linux-man@vger.kernel.org, libc-alpha, musl,
	~hallyn/shadow

On Thu, Nov 12, 2026 at 03:37:11PM +0100, Alejandro Colomar wrote:
> Hi Rich,
> 
> > Date: 2026-11-09 16:51:02+0100
> > From: Alejandro Colomar <alx+linux-man@kernel.org>
> >
> [...]
> > > I would not document future behavior, and would document existing
> > > behavior only as an implementation detail, not an application-facing
> > > contract. The only contract with the application is that crypt(P,H)
> > > will never return a string identical to H except on valid password (in
> > > the absence of theoretical hash collisions) regardless of the validity
> > > of P and H.
> > 
> > Okay.  Thank you very much!  I'll work on a patch, and CC you when it's
> > ready.
> 
> What do you think of this?
> 
> 	diff --git i/man/man3/crypt.3 w/man/man3/crypt.3
> 	index e0a74b955b3e..4a75fac2f627 100644
> 	--- i/man/man3/crypt.3
> 	+++ w/man/man3/crypt.3
> 	@@ -259,6 +259,28 @@ .SS salt
> 	 is equal to
> 	 .I xxx
> 	 otherwise.
> 	+.SH EXAMPLES
> 	+When comparing a password against an existing hash,
> 	+that hash (and no other) must be passed as
> 	+.IR salt .
> 	+If and only if
> 	+.I salt
> 	+compares equal
> 	+(see
> 	+.BR streq (3))
> 	+to the returned string,
> 	+the password matches the existing hash specified by
> 	+.IR salt .
> 	+.P
> 	+.in +4n
> 	+.EX
> 	+if (streq(H, crypt(P, H))) {
> 	+       // good password
> 	+} else {
> 	+       // bad password
> 	+}
> 	+.EE
> 	+.in
> 	 .SH SEE ALSO
> 	 .BR login (1),
> 	 .BR passwd (1),
> 
> which reads as:
> 
> 	--- HEAD:man/man3/crypt.3
> 	+++ ./man/man3/crypt.3
> 	@@ -152,6 +152,19 @@ NOTES
> 	      than 1000, 999999999 if xxx is greater than 999999999, and
> 	      is equal to xxx otherwise.
> 	 
> 	+EXAMPLES
> 	+     When comparing a password against an existing hash, that
> 	+     hash (and no other) must be passed as salt.  If and only
> 	+     if salt compares equal (see streq(3)) to the returned
> 	+     string, the password matches the existing hash specified
> 	+     by salt.
> 	+
> 	+         if (streq(H, crypt(P, H))) {
> 	+              // good password
> 	+         } else {
> 	+              // bad password
> 	+         }
> 	+
> 	 SEE ALSO
> 	      login(1), passwd(1), encrypt(3), getpass(3), passwd(5)

Missing null return check.

Rich

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [musl] Re: RFC: how to document musl-crypt failure ?
  2026-11-12 14:45         ` Rich Felker
@ 2026-11-12 15:01           ` Alejandro Colomar
  0 siblings, 0 replies; 9+ messages in thread
From: Alejandro Colomar @ 2026-11-12 15:01 UTC (permalink / raw)
  To: Rich Felker
  Cc: Walter Harms, linux-man@vger.kernel.org, libc-alpha, musl,
	~hallyn/shadow

[-- Attachment #1: Type: text/plain, Size: 1739 bytes --]

Hi Rich,

> Date: 2026-11-12 09:45:53-0500
> From: Rich Felker <dalias@libc.org>
>
[...]
> > 	--- HEAD:man/man3/crypt.3
> > 	+++ ./man/man3/crypt.3
> > 	@@ -152,6 +152,19 @@ NOTES
> > 	      than 1000, 999999999 if xxx is greater than 999999999, and
> > 	      is equal to xxx otherwise.
> > 	 
> > 	+EXAMPLES
> > 	+     When comparing a password against an existing hash, that
> > 	+     hash (and no other) must be passed as salt.  If and only
> > 	+     if salt compares equal (see streq(3)) to the returned
> > 	+     string, the password matches the existing hash specified
> > 	+     by salt.
> > 	+
> > 	+         if (streq(H, crypt(P, H))) {
> > 	+              // good password
> > 	+         } else {
> > 	+              // bad password
> > 	+         }
> > 	+
> > 	 SEE ALSO
> > 	      login(1), passwd(1), encrypt(3), getpass(3), passwd(5)
> 
> Missing null return check.

Ouch!  Thanks!

	--- HEAD:man/man3/crypt.3
	+++ ./man/man3/crypt.3
	@@ -152,6 +152,20 @@ NOTES
	      than 1000, 999999999 if xxx is greater than 999999999, and
	      is equal to xxx otherwise.
	 
	+EXAMPLES
	+     When comparing a password against an existing hash, that
	+     hash (and no other) must be passed as salt.  If and only
	+     if salt compares equal (see streq(3)) to the returned
	+     string, the password matches the existing hash specified
	+     by salt.
	+
	+         const char  *h = crypt(P, H);
	+         if (h != NULL && streq(h, H)) {
	+              // good password
	+         } else {
	+              // bad password
	+         }
	+
	 SEE ALSO
	      login(1), passwd(1), encrypt(3), getpass(3), passwd(5)
 
Cheers,
Alex

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-11-12 15:01 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-09  8:59 RFC: how to document musl-crypt failure ? Walter Harms
2026-11-09 10:10 ` Alejandro Colomar
2026-11-09 10:23   ` Andreas Schwab
2026-11-09 11:24     ` Sam James
2026-11-09 13:56   ` [musl] " Rich Felker
2026-11-09 15:50     ` Alejandro Colomar
2026-11-12 14:37       ` Alejandro Colomar
2026-11-12 14:45         ` Rich Felker
2026-11-12 15:01           ` Alejandro Colomar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox