diff --git a/pam-1.5.1-pam-faillock-skip.patch b/pam-1.5.1-pam-faillock-skip.patch
new file mode 100644
index 0000000..c54364f
--- /dev/null
+++ b/pam-1.5.1-pam-faillock-skip.patch
@@ -0,0 +1,62 @@
+diff -up Linux-PAM-1.5.1/modules/pam_faillock/pam_faillock.8.xml.pam-faillock-skip Linux-PAM-1.5.1/modules/pam_faillock/pam_faillock.8.xml
+--- Linux-PAM-1.5.1/modules/pam_faillock/pam_faillock.8.xml.pam-faillock-skip 2025-12-10 16:12:22.912937203 +0100
++++ Linux-PAM-1.5.1/modules/pam_faillock/pam_faillock.8.xml 2025-12-10 16:12:48.429569598 +0100
+@@ -240,6 +240,14 @@
+ user accounts allowing the adversary to infer that a particular account
+ is not existing on a system.
+
++
++ If the stack has not been run prior to the
++ stack, the logic to reset the failed login counter is intentionally skipped. This prevents
++ automated services, such as crond or systemd-user,
++ which might only perform account management tasks, from inadvertently clearing a user's
++ failed attempt records. This ensures the faillock counter is only reset by a service that
++ performs a full, successful authentication.
++
+
+
+
+diff -up Linux-PAM-1.5.1/modules/pam_faillock/pam_faillock.c.pam-faillock-skip Linux-PAM-1.5.1/modules/pam_faillock/pam_faillock.c
+--- Linux-PAM-1.5.1/modules/pam_faillock/pam_faillock.c.pam-faillock-skip 2025-12-10 16:12:22.924887130 +0100
++++ Linux-PAM-1.5.1/modules/pam_faillock/pam_faillock.c 2025-12-10 16:12:22.969905176 +0100
+@@ -61,6 +61,8 @@
+ #define FAILLOCK_ACTION_AUTHSUCC 1
+ #define FAILLOCK_ACTION_AUTHFAIL 2
+
++#define FAILLOCK_AUTH_EXECUTED "pam_faillock:auth_executed"
++
+ static int
+ args_parse(pam_handle_t *pamh, int argc, const char **argv,
+ int flags, struct options *opts)
+@@ -452,6 +454,10 @@ pam_sm_authenticate(pam_handle_t *pamh,
+ goto err;
+ }
+
++ rv = pam_set_data(pamh, FAILLOCK_AUTH_EXECUTED, (void *)1, NULL);
++ if (rv != PAM_SUCCESS)
++ goto err;
++
+ if (!(opts.flags & FAILLOCK_FLAG_LOCAL_ONLY) ||
+ check_local_user (pamh, opts.user) != 0) {
+ switch (opts.action) {
+@@ -505,6 +511,7 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int
+ struct options opts;
+ int rv, fd = -1;
+ struct tally_data tallies;
++ const void *auth_flag;
+
+ memset(&tallies, 0, sizeof(tallies));
+
+@@ -515,6 +522,12 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int
+
+ opts.action = FAILLOCK_ACTION_AUTHSUCC;
+
++ rv = pam_get_data(pamh, FAILLOCK_AUTH_EXECUTED, &auth_flag);
++ if (rv == PAM_NO_MODULE_DATA) {
++ rv = PAM_SUCCESS;
++ goto err;
++ }
++
+ if ((rv=get_pam_user(pamh, &opts)) != PAM_SUCCESS) {
+ goto err;
+ }
diff --git a/pam.spec b/pam.spec
index 7100abc..1d07632 100644
--- a/pam.spec
+++ b/pam.spec
@@ -3,7 +3,7 @@
Summary: An extensible library which provides authentication for applications
Name: pam
Version: 1.5.1
-Release: 27%{?dist}
+Release: 28%{?dist}
# The library is BSD licensed with option to relicense as GPLv2+
# - this option is redundant as the BSD license allows that anyway.
# pam_timestamp, pam_loginuid, and pam_console modules are GPLv2+.
@@ -83,6 +83,8 @@ Patch25: pam-1.5.1-pam-unix-blank-expiration.patch
Patch26: pam-1.5.1-pam-inline-pam-asprintf.patch
# https://github.com/linux-pam/linux-pam/commit/475bd60c552b98c7eddb3270b0b4196847c0072e
Patch27: pam-1.5.1-pam-namespace-rebase.patch
+# https://github.com/linux-pam/linux-pam/commit/7d96d452e65ba5dec73f2c77104113977dd3aeb1
+Patch28: pam-1.5.1-pam-faillock-skip.patch
%global _pamlibdir %{_libdir}
%global _moduledir %{_libdir}/security
@@ -192,6 +194,7 @@ cp %{SOURCE18} .
%patch25 -p1 -b .pam-unix-blank-expiration
%patch26 -p1 -b .pam-inline-pam-asprintf
%patch27 -p1 -b .pam-namespace-rebase
+%patch28 -p1 -b .pam-faillock-skip
autoreconf -i
@@ -447,6 +450,10 @@ done
%doc doc/sag/*.txt doc/sag/html
%changelog
+* Wed Dec 10 2025 Iker Pedrosa - 1.5.1-28
+- pam_faillock: skip clearing user's failed attempt.
+ Resolves: RHEL-130875
+
* Tue Aug 5 2025 Iker Pedrosa - 1.5.1-27
- pam_unix: sync expiry checks with shadow.
Resolves: RHEL-70519, RHEL-95475, RHEL-96955 and RHEL-96973