-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 OpenAFS Security Advisory 2024-001 Topic: Theft of credentials in Unix client PAGs (CVE-2024-10394) Issued: 12 November, 2024 Affected: Unix OpenAFS clients using PAGs running versions 1.0 through 1.6.24, 1.8.0 through 1.8.12.2, and 1.9.0 through 1.9.1 A local user can bypass the OpenAFS PAG (Process Authentication Group) throttling mechanism in Unix clients, allowing the user to create a PAG using an existing id number, effectively joining the PAG and letting the user steal the credentials in that PAG. SUMMARY ======= The pioctls PSetTokens and PSetTokens2 (also known as ktc_SetToken and ktc_SetTokenEx) allow the caller to create a PAG in addition to setting tokens, but they do not limit the rate of PAG creation. A malicious user can call this pioctl in a loop to overflow the PAG id counter, and thus create a PAG of any id. This lets the user effectively join any existing PAG, which lets them use, extract, or set the credentials in that PAG. IMPACT ====== A local, unprivileged user can impersonate another user to AFS, if the other user is authenticated to AFS on the same machine in a PAG. Performing an attack requires creating a large number of PAGs, which takes some time to do. Usually this takes over an hour, but the amount of time depends greatly on the usage pattern of PAGs on the machine, and so may take much less time. CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N Score: 8.4 / High While a malicious user is performing such an attack, normal PAG creation by unprivileged users will be stalled due to the normal throttling mechanism, and so it may be very noticeable that an attack is happening. PAGs created by the local superuser (root) are not throttled, and so this attack may not be noticeable if only root creates PAGs on a particular machine. However, if PAGs can be created by root at the request of an unprivileged user (such as a privileged helper service that changes to the requesting user identity to run a command), the vulnerability could still be exploited. Applications creating PAGs using such privileged helpers will need to assess whether additional application-level rate-limiting is needed to mitigate the attack. If a user is not using a PAG, then this attack cannot happen, as default per-UID credentials are not accessible via a PAG id. On some systems, the default behavior is for user credentials to be in a PAG (such as when an administrator has configured the use of pam_afs_session.so), but on other systems the user must explicitly opt in to PAG usage for a given credential in order for that credential to be vulnerable. Note that PAGs are not implemented on macOS clients, so credentials used on macOS clients are not vulnerable to this attack. Note that the fix for this vulnerability causes rate-limiting to be imposed on operations that were not previously subject to such limiting. If an application is performing these operations in a performance-sensitive context, the vulnerability mitigation may cause delays or apparent performance degradation for the application. However, such scenarios are expected to be rare, as the primary reason to be using the operations in question is to set the PAG for the parent process (e.g., `aklog -setpag`) but that functionality can fail for a number of reasons (as described in DETAILS) and thus is unlikely to be used in an application's critical path. AFFECTED SOFTWARE ================= All releases of OpenAFS up to and including 1.6.24. All releases of OpenAFS 1.8.0 to 1.8.12.2. All releases of OpenAFS 1.9.0 to 1.9.1. Only non-macOS Unix kernel cache managers are affected, since those are the only platforms where PAGs are implemented. The userspace FUSE client is not affected. FIXES ===== The OpenAFS project recommends that administrators upgrade all affected clients to OpenAFS version 1.6.25 or 1.8.13. For those sites unable or unwilling to upgrade, patches to resolve this issue are available via: https://www.openafs.org/pages/security/openafs-sa-2024-001-stable16.patch https://www.openafs.org/pages/security/openafs-sa-2024-001-stable18.patch https://www.openafs.org/pages/security/openafs-sa-2024-001-master.patch The issue can be worked around by not using PAGs at all. PAGs are normally created by running pagsh, or during login via PAM plugins such as pam_afs_session.so. Without a PAG, AFS credentials are associated with the local Unix UID. DETAILS ======= OpenAFS Unix clients can associate a user's AFS credentials (their "tokens") with either the user's local Unix UID, or a PAG (process authentication group). PAGs are used to tie user credentials to a user-controlled session. This allows the same user to have different AFS credentials in different sessions, while still running under the same Unix UID. Internally, the OpenAFS cache manager tracks PAGs by assigning an id number to each PAG. The mechanism to track a process's PAG membership is in general platform-specific, but on most architectures the cache manager tracks what PAG a process is in by adding fake group numbers to the process' group list (Linux and AIX use platform-specific mechanisms that still rely on encoding the PAG's id number in storage associated with the process in question). The OpenAFS cache manager assigns each PAG an id number when it is created; the user cannot control what number is used. To prevent users from creating PAGs that collide with existing PAG ids, PAG creation is throttled to one PAG per second on average (the calling process sleeps if this rate is exceeded). Collisions are still possible with this in place, but they take a very long time to occur. It is difficult to ensure that collisions do not happen, because it is difficult for the cache manager to know for sure that a PAG is no longer in use (the PAG could be referenced only in the group list of a process). Traditionally, the primary way to create a PAG is by calling the "setpag" syscall, and this syscalls throttles the creation of PAGs as discussed. That syscall affects the current process, and so cannot be used by a command to change the PAG of the parent process. To allow users to change the PAG of the current process via a new command, a different mechanism is needed to affect the PAG of the parent process. And so, the pioctls PSetTokens (and PSetTokens2 introduced in OpenAFS 1.7.25) allow the caller to pass a flag to indicate that the PAG of the parent process should be changed, while also setting tokens. This is the mechanism used by 'aklog - -setpag', for example. Setting the PAG of the parent process may fail for a few reasons. The feature just doesn't work at all on some platforms, and on Linux setting a PAG may also fail due to a user exceeding per-user keyring quotas. But even when the feature doesn't work, a new PAG id is still generated. This slightly different code path does not go through the PAG-throttling mechanism of the "setpag" syscall, and so bypasses the throttling mechanism. With this in mind, a user can call the PSetTokens/PSetTokens2 pioctl repeatedly to create new PAGs until the internal PAG id counter rolls over, and starts to create PAGs that collide with existing PAG id numbers. If the user has created a PAG that collides with an existing PAG, the current process has effectively joined that PAG, and can extract credentials from the PAG using the PGetTokens or PGetTokens2 pioctl, or can just access AFS like normal and they will use the credentials of the joined PAG. Setting new credentials in that PAG would cause the other processes in the existing PAG to start using the new credentials as well. The joined PAG could be one that was created by any other user, including root. PAGs do not have any access-control, since they may be legitimately used with different Unix UIDs (for example, a process may authenticate to AFS while running as root, and then switch to an unprivileged UID in the same PAG to access AFS). ACKNOWLEDGMENTS =============== Issue reported by and fix provided by Andrew Deason. -----BEGIN PGP SIGNATURE----- iQG3BAEBCgAdFiEE2WGV4E2ARf9BYP0XKNmm82TrdRIFAmczuFgACgkQKNmm82Tr dRLgQQwgo9d6xWAHKasgTAROePRlOFB65koCvfKeB0/aQNsfl2GyeEdqvmEGmjD5 H09U0+RUx0Y63Kwio4iHxx3/UfvGMm7oPM+2o+zVCahp7XG3er6XR4XnJhKJHZ5Q cLJSHzJoZrWFzg0pD7+5w8xltN+iNO8GRhd5N0ZqMNaMo0hmOLVBQjaL7i7iMcg5 nnc2ozgN5yOtfERQLzSvEq1PhOuaSoXk9JmZh/AVowBBYnRNM/nyiGDRnZJuCA3w 7SMxFyS6DF+/m+OQ5my6WNNpmRMES6IE7HP9M3FSVq9sXxIgKXFnt7evPqDPekw8 i08wxO8Uzn26W3WjOl+N+3TzJcs0XAbEtxTXxAL5fl9sWAQgb1JNnOx9Flr2QHsk 6tI66xUmuvOfRHlUdKp8mmDNOrv4WIv5OfEXPzgydQLIgNTJLt44t6rsbbSXrJrE 73YolDDozjkDN1ZAdnlv0749cTkcBzyvuhrAWTmLbOS2lLzUaHxhhCXdrTbLcNcd j3p/mENT3FNvmg== =53rb -----END PGP SIGNATURE-----