Hello pam_pkcs11 maintainers,
I am reporting to you a likely security issue in pam_pkcs11 introduced
in version 0.6.12. The details about the issue follow further below.
By now I have the impression that there is no active pam_pkcs11
maintainer. To prevent further loss of time please reply by
Thursday Nov 14 to confirm the report and to state the further
process. If there is no process established by then, then I will
share the information with the linux-distros mailing list and grant a
7 day embargo until all information will be published.
Coordinated Disclosure
We offer coordinated disclosure for security findings based on our disclosure
policy 1. For the coordinated disclosure process please answer the
following questions for us:
-
Do you want to perform coordinated disclosure? If yes, then please
communicate your desired coordinated release date (CRD) for publishing the
security issues and any patches/updates. We offer to keep the issue
private for up to 90 days (resulting in publication latest on 2025-02-09),
but prefer to maintain shorter time frames of about two weeks, if
possible.
If you don't want to perform coordinated disclosure then we will immediately
publish all information we have on the oss-security mailing list 2 and in
our bug tracker. For this issue we suggest to have at least a 7 day embargo
on the linux-distros mailing list, though, since other distributors might be
affected.
-
Do you acknowledge the individual findings? If so, will you assign CVE
identifiers for the security issues? If yes, then please share the CVEs with
us once they are assigned. Otherwise we can offer to request CVEs for you
from the Mitre corporation.
Context of the Finding
Fellow SUSE engineer Marcus Rückert uses a YubiKey for login at his Linux
desktop. He recently noticed a change in behaviour in his GDM login setup. By
digging a bit deeper he noticed that in some situations login is possible
without entering a password or using the YubiKey at all.
There is a bug (or a feature?) in GDM 3 that causes YubiKeys to be treated
as smart cards, so this is one ingredient that seems to have come into play
here. It still didn't explain why login without a password has become
possible.
A number of Linux distributions use a dedicated gdm-smartcard
PAM stack
configuration file for smartcard login in GDM. On openSUSE we rely on
pam_pkcs11
as the sole (proper) authentication module in this gdm-smartcard
configuration 4. It took me a long time to understand where exactly this
gdm-smartcard
PAM stack is used in GDM. The logic to select this PAM stack
is found in a wholly different Gnome component, in gnome-shell 5. There some
JavaScript is responsible for detecting smart cards via the D-Bus interface of
the gnome-settings-daemon and to change the authentication mode of GDM.
I reproduced the situation by using smartcard emulation in a QEMU Virtual
machine, to be able to achieve proper smartcard detection in both GDM
and pam_pkcs11
. As soon as the smartcard is properly setup in the system,
GDM switches into smartcard authentication mode (support for this is enabled
by default). A user list is no longer shown, but the username has to be
entered manually. After entering the username, the gdm-smartcard
PAM stack is
executed, and with it pam_pkcs11
. No password is asked for and login
succeeds.
In my setup, as well as in the real life setup using a YubiKey, pam_pkcs11
stops execution after logging "Failed to initialize crypto". After this, the
login succeeds. As I see it, the reason for this lies in pam_pkcs11
, as
described in the next section.
I did not investigate why exactly this error condition occurs in the test setup or when
using a YubiKey, as I don't believe it matters (for security). Even when errors occur, the
outcome of the PAM stack execution shouldn't allow authentication without providing
credentials.
PAM_IGNORE
Return Paths in pam_sm_authenticate()
The login without proper authentication seems to stem from a change that found
its way into pam_pkcs11
version 0.6.12. The following statements are based
on the Git tag pam_pkcs11-0.6.12
. The code in pam_pkcs11.c
has not seen
many changes since that tag, mostly in the area of fixing memory leaks, so
most of what follows should still apply to the master branch of the
repository.
I believe the issue has been introduced with commit bac6cf8 (note that
there seems to be some artifact in the Git repository: there exists a
seemingly identical commit 88a87d5 in the commit log on master).
The code in pam_pkcs11.c
line 284 means that, if there is no login token name
(i.e. no login happened yet), the default return code on error
conditions will be PAM_IGNORE
:
if (!configuration->card_only || !login_token_name) {
/* Allow to pass to the next module if the auth isn't
restricted to card only. */
pkcs11_pam_fail = PAM_IGNORE;
} else {
pkcs11_pam_fail = PAM_CRED_INSUFFICIENT;
}
Before this change the default return code was always PAM_CRED_INSUFFICIENT
.
When a PAM module returns PAM_IGNORE
, though, then this means that its
outcome should not be used to determine the result of the PAM stack execution.
As we use the required
control setting for pam_pkcs11
in our
gdm-smartcard
configuration, this is exactly what happens. In extended PAM
syntax required
is expressed like this:
required
[success=ok new_authtok_reqd=ok ignore=ignore default=bad]
The required
control setting here no longer does what it should when
the authentication using pam_pkcs11
fails in a lot of situations. Actually
only two return paths of pam_sm_authenticate()
return anything else than
PAM_IGNORE
at this point:
- if
pkcs11_login()
fails
- if
verify_signature()
fails
Both return paths will reset pkcs11_pam_fail
to a safe PAM_AUTH_ERR
value.
The following is a list of all the other return paths which will return
PAM_IGNORE
:
- line 305: if a user is logging in from remote, or can control the DISPLAY variable
(e.g. in sudo context).
- line 316: if the
crypto_init()
call fails.
- line 328: if a screen saver context is detected and no login token is
recorded, then an explicit jump to a PAM_IGNORE
return is performed.
- lines 343, 357: if loading or initializing the PKCS#11 module fails.
- line 374: if the configured token is not found and
card_only
is not set.
This might be okay in light of the semantics of card_only
, but I still
find it strange. If a system administrator wants to make pam_pkcs11
authentication optional then he can do so by using the PAM stack configuration
already. Changing the module result semantics this drastically through a PAM
module parameter is unusual.
- line 416: if no smart card is found even after potentially waiting for it.
- if a smart card is found, but one of various PKCS11 functions or certificate
checks fail, then further PAM_IGNORE
returns can happen in:
- line 432
open_pkcs11_session()
- line 443
get_slot_login_required()
- line 471 (when reading in a password fails)
- line 486 (empty password was read without
nullok
set)
- line 522
get_certificate_list()
- line 597
pam_set_item(..., PAM_USER, ...)
- line 613
match_user()
- line 634 (no matching certificate found)
- line 663
get_random_value()
- line 677
sign_value()
- line 776
close_pkcs11_session()
As a quick workaround to avoid the login without authentication I suggest to
use the following PAM configuration line instead:
auth [success=ok default=bad] pam_pkcs11.so wait_for_card card_only
This way any other outcome than PAM_SUCCESS
will mark the PAM stack
execution as bad and authentication will fail.
In the end I believe this needs to be fixed on source code level, though. The
PAM module should indicate a failure condition if errors occur, so that the
typical required
control setting makes authentication fail. If
administrators want to ignore pam_pkcs11
instead, they can switch the
control field to optional
or sufficient
in the configuration, which will
similar effects.
Since there exist other distributions that ship similar gdm-smartcard
PAM
configuration files as we do, I suggest to establish an embargo period of some
time (about two weeks) and prepare a bugfix release on your end. We can
involve the Linux distros mailing list to inform other Linux distributions
about the issue, before it becomes public, so they can prepare as well.
Situation on other Distributions
On current Fedora Linux pam_pkcs11
isn't used anymore for smart card
authentication, but pam_sss
instead. So it's not affected, but maybe older
versions that are still in use.
The gdm-smartcard
PAM stack relying on pam_pkcs11
is furthermore found in the
GDM repository for:
- Linux from Scratch
- Exherbo Linux
- Arch Linux
LfS and Exherbo are pretty exotic. I tried reproducing the issue on Arch Linux.
While on Arch the gdm-smartcard stack is installed, there is no pam_pkcs11
package in the standard repositories. It can be installed from AUR, however.
When doing so and also installing the gdm
and ccid
packages, then the
basic security issue becomes possible as well. I only tested this in a crafted
sudo PAM stack, though, since I did not manage to get gdm
into smart
card authentication mode on Arch Linux. It seems some ingredient was still
missing to trigger that.
On Arch Linux I also noticed that the AUR pam_pkcs11
package does not
place any default pam_pkcs11.conf
file into /etc. This also avoids the
security problem, because when slot_num == -1
then pam_sm_authenticate()
will return early with PAM_CRED_UNAVAIL
. On OpenSUSE we do ship
a default configuration with slot_num = 0
, however.
Generally any setup where pam_pkcs11
is the only decisive auth
module and where a basic pam_pkcs11.conf
is around it will likely be
possible to insert a faulty / invalid smart card and gain access without proper
authorization.
Hello pam_pkcs11 maintainers,
I am reporting to you a likely security issue in pam_pkcs11 introduced
in version 0.6.12. The details about the issue follow further below.
By now I have the impression that there is no active
pam_pkcs11
maintainer. To prevent further loss of time please reply by
Thursday Nov 14 to confirm the report and to state the further
process. If there is no process established by then, then I will
share the information with the linux-distros mailing list and grant a
7 day embargo until all information will be published.
Coordinated Disclosure
We offer coordinated disclosure for security findings based on our disclosure
policy 1. For the coordinated disclosure process please answer the
following questions for us:
Do you want to perform coordinated disclosure? If yes, then please
communicate your desired coordinated release date (CRD) for publishing the
security issues and any patches/updates. We offer to keep the issue
private for up to 90 days (resulting in publication latest on 2025-02-09),
but prefer to maintain shorter time frames of about two weeks, if
possible.
If you don't want to perform coordinated disclosure then we will immediately
publish all information we have on the oss-security mailing list 2 and in
our bug tracker. For this issue we suggest to have at least a 7 day embargo
on the linux-distros mailing list, though, since other distributors might be
affected.
Do you acknowledge the individual findings? If so, will you assign CVE
identifiers for the security issues? If yes, then please share the CVEs with
us once they are assigned. Otherwise we can offer to request CVEs for you
from the Mitre corporation.
Context of the Finding
Fellow SUSE engineer Marcus Rückert uses a YubiKey for login at his Linux
desktop. He recently noticed a change in behaviour in his GDM login setup. By
digging a bit deeper he noticed that in some situations login is possible
without entering a password or using the YubiKey at all.
There is a bug (or a feature?) in GDM 3 that causes YubiKeys to be treated
as smart cards, so this is one ingredient that seems to have come into play
here. It still didn't explain why login without a password has become
possible.
A number of Linux distributions use a dedicated
gdm-smartcard
PAM stackconfiguration file for smartcard login in GDM. On openSUSE we rely on
pam_pkcs11
as the sole (proper) authentication module in thisgdm-smartcard
configuration 4. It took me a long time to understand where exactly this
gdm-smartcard
PAM stack is used in GDM. The logic to select this PAM stackis found in a wholly different Gnome component, in gnome-shell 5. There some
JavaScript is responsible for detecting smart cards via the D-Bus interface of
the gnome-settings-daemon and to change the authentication mode of GDM.
I reproduced the situation by using smartcard emulation in a QEMU Virtual
machine, to be able to achieve proper smartcard detection in both GDM
and
pam_pkcs11
. As soon as the smartcard is properly setup in the system,GDM switches into smartcard authentication mode (support for this is enabled
by default). A user list is no longer shown, but the username has to be
entered manually. After entering the username, the
gdm-smartcard
PAM stack isexecuted, and with it
pam_pkcs11
. No password is asked for and loginsucceeds.
In my setup, as well as in the real life setup using a YubiKey,
pam_pkcs11
stops execution after logging "Failed to initialize crypto". After this, the
login succeeds. As I see it, the reason for this lies in
pam_pkcs11
, asdescribed in the next section.
I did not investigate why exactly this error condition occurs in the test setup or when
using a YubiKey, as I don't believe it matters (for security). Even when errors occur, the
outcome of the PAM stack execution shouldn't allow authentication without providing
credentials.
PAM_IGNORE
Return Paths inpam_sm_authenticate()
The login without proper authentication seems to stem from a change that found
its way into
pam_pkcs11
version 0.6.12. The following statements are basedon the Git tag
pam_pkcs11-0.6.12
. The code inpam_pkcs11.c
has not seenmany changes since that tag, mostly in the area of fixing memory leaks, so
most of what follows should still apply to the master branch of the
repository.
I believe the issue has been introduced with commit bac6cf8 (note that
there seems to be some artifact in the Git repository: there exists a
seemingly identical commit 88a87d5 in the commit log on master).
The code in
pam_pkcs11.c
line 284 means that, if there is no login token name(i.e. no login happened yet), the default return code on error
conditions will be
PAM_IGNORE
:Before this change the default return code was always
PAM_CRED_INSUFFICIENT
.When a PAM module returns
PAM_IGNORE
, though, then this means that itsoutcome should not be used to determine the result of the PAM stack execution.
As we use the
required
control setting forpam_pkcs11
in ourgdm-smartcard
configuration, this is exactly what happens. In extended PAMsyntax
required
is expressed like this:The
required
control setting here no longer does what it should whenthe authentication using
pam_pkcs11
fails in a lot of situations. Actuallyonly two return paths of
pam_sm_authenticate()
return anything else thanPAM_IGNORE
at this point:pkcs11_login()
failsverify_signature()
failsBoth return paths will reset
pkcs11_pam_fail
to a safePAM_AUTH_ERR
value.The following is a list of all the other return paths which will return
PAM_IGNORE
:(e.g. in sudo context).
crypto_init()
call fails.recorded, then an explicit jump to a
PAM_IGNORE
return is performed.card_only
is not set.This might be okay in light of the semantics of
card_only
, but I stillfind it strange. If a system administrator wants to make
pam_pkcs11
authentication optional then he can do so by using the PAM stack configuration
already. Changing the module result semantics this drastically through a PAM
module parameter is unusual.
checks fail, then further
PAM_IGNORE
returns can happen in:open_pkcs11_session()
get_slot_login_required()
nullok
set)get_certificate_list()
pam_set_item(..., PAM_USER, ...)
match_user()
get_random_value()
sign_value()
close_pkcs11_session()
As a quick workaround to avoid the login without authentication I suggest to
use the following PAM configuration line instead:
This way any other outcome than
PAM_SUCCESS
will mark the PAM stackexecution as bad and authentication will fail.
In the end I believe this needs to be fixed on source code level, though. The
PAM module should indicate a failure condition if errors occur, so that the
typical
required
control setting makes authentication fail. Ifadministrators want to ignore
pam_pkcs11
instead, they can switch thecontrol field to
optional
orsufficient
in the configuration, which willsimilar effects.
Since there exist other distributions that ship similar
gdm-smartcard
PAMconfiguration files as we do, I suggest to establish an embargo period of some
time (about two weeks) and prepare a bugfix release on your end. We can
involve the Linux distros mailing list to inform other Linux distributions
about the issue, before it becomes public, so they can prepare as well.
Situation on other Distributions
On current Fedora Linux
pam_pkcs11
isn't used anymore for smart cardauthentication, but
pam_sss
instead. So it's not affected, but maybe olderversions that are still in use.
The
gdm-smartcard
PAM stack relying onpam_pkcs11
is furthermore found in theGDM repository for:
LfS and Exherbo are pretty exotic. I tried reproducing the issue on Arch Linux.
While on Arch the gdm-smartcard stack is installed, there is no
pam_pkcs11
package in the standard repositories. It can be installed from AUR, however.
When doing so and also installing the
gdm
andccid
packages, then thebasic security issue becomes possible as well. I only tested this in a crafted
sudo PAM stack, though, since I did not manage to get
gdm
into smartcard authentication mode on Arch Linux. It seems some ingredient was still
missing to trigger that.
On Arch Linux I also noticed that the AUR
pam_pkcs11
package does notplace any default
pam_pkcs11.conf
file into /etc. This also avoids thesecurity problem, because when
slot_num == -1
thenpam_sm_authenticate()
will return early with
PAM_CRED_UNAVAIL
. On OpenSUSE we do shipa default configuration with
slot_num = 0
, however.Generally any setup where
pam_pkcs11
is the only decisiveauth
module and where a basic
pam_pkcs11.conf
is around it will likely bepossible to insert a faulty / invalid smart card and gain access without proper
authorization.