rpms/kdebase/devel post-3.4.2-kdebase-kcheckpass.diff, NONE, 1.1 kdebase.spec, 1.119, 1.120
fedora-cvs-commits at redhat.com
fedora-cvs-commits at redhat.com
Mon Sep 5 12:10:21 UTC 2005
Author: than
Update of /cvs/dist/rpms/kdebase/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv24848
Modified Files:
kdebase.spec
Added Files:
post-3.4.2-kdebase-kcheckpass.diff
Log Message:
apply patch to fix local root vulnerability in kcheckpass CAN-2005-2494, #166997
post-3.4.2-kdebase-kcheckpass.diff:
kcheckpass.c | 96 +++++++++++++++++++++++++++++++++++++++++------------------
1 files changed, 67 insertions(+), 29 deletions(-)
--- NEW FILE post-3.4.2-kdebase-kcheckpass.diff ---
Index: kcheckpass.c
===================================================================
--- kcheckpass.c (revision 453871)
+++ kcheckpass.c (working copy)
@@ -14,7 +14,7 @@
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
* kcheckpass is a simple password checker. Just invoke and
@@ -264,8 +264,13 @@
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
+ va_end(ap);
}
+#ifndef O_NOFOLLOW
+# define O_NOFOLLOW 0
+#endif
+
static void ATTR_NORETURN
usage(int exitval)
{
@@ -286,6 +291,14 @@
exit(exitval);
}
+static int exclusive_lock(int fd)
+{
+ struct flock lk;
+ lk.l_type = F_WRLCK;
+ lk.l_whence = SEEK_SET;
+ lk.l_start = lk.l_len = 0;
+ return fcntl(fd, F_SETLKW, &lk);
+}
int
main(int argc, char **argv)
@@ -299,10 +312,13 @@
char *p;
#endif
struct passwd *pw;
- int c, nfd, lfd, numtries;
+ int c, nfd, tfd, lfd;
uid_t uid;
- long lasttime;
+ time_t lasttime;
AuthReturn ret;
+ char tmpname[64], fname[64], fcont[64];
+ time_t left = 3;
+ lfd = tfd = 0;
#ifdef HAVE_OSF_C2_PASSWD
initialize_osf_security(argc, argv);
@@ -371,6 +387,41 @@
return AuthError;
}
}
+
+ /* see if we had already a failed attempt */
+ if ( uid != geteuid() ) {
+ strcpy(tmpname, "/var/lock/kcheckpass.tmp.XXXXXX");
+ if ((tfd=mkstemp(tmpname)) < 0)
+ return AuthError;
+
+ /* try locking out concurrent kcheckpass processes */
+ exclusive_lock(tfd);
+
+ write(tfd, fcont, sprintf(fcont, "%lu\n", time(0)+left));
+ (void) lseek(tfd, 0, SEEK_SET);
+
+ sprintf(fname, "/var/lock/kcheckpass.%d", uid );
+
+ if ((lfd = open(fname, O_RDWR | O_NOFOLLOW)) >= 0) {
+ if (exclusive_lock(lfd) == 0) {
+ if ((c = read(lfd, fcont, sizeof(fcont)-1)) > 0 &&
+ (fcont[c] = '\0', sscanf(fcont, "%ld", &lasttime) == 1))
+ {
+ time_t ct = time(0);
+
+ /* in case we were killed early, sleep the remaining time
+ * to properly enforce invocation throttling and make sure
+ * that users can't use kcheckpass for bruteforcing password
+ */
+ if(lasttime > ct && lasttime < ct + left)
+ sleep (lasttime - ct);
+ }
+ }
+ close(lfd);
+ }
+ rename(tmpname, fname);
+ }
+
/* Now do the fandango */
ret = Authenticate(
#ifdef HAVE_PAM
@@ -379,35 +430,21 @@
method,
username,
sfd < 0 ? conv_legacy : conv_server);
+
if (ret == AuthOk || ret == AuthBad) {
/* Security: Don't undermine the shadow system. */
if (uid != geteuid()) {
- char fname[32], fcont[32];
- sprintf(fname, "/var/lock/kcheckpass.%d", uid);
- if ((lfd = open(fname, O_RDWR | O_CREAT)) >= 0) {
- struct flock lk;
- lk.l_type = F_WRLCK;
- lk.l_whence = SEEK_SET;
- lk.l_start = lk.l_len = 0;
- if (fcntl(lfd, F_SETLKW, &lk))
- return AuthError;
- if ((c = read(lfd, fcont, sizeof(fcont))) > 0 &&
- (fcont[c] = 0, sscanf(fcont, "%ld %d\n", &lasttime, &numtries) == 2))
- {
- time_t left = lasttime - time(0);
- if (numtries < 20)
- numtries++;
- left += 2 << (numtries > 10 ? numtries - 10 : 0);
- if (left > 0)
- sleep(left);
- } else
- numtries = 0;
- if (ret == AuthBad) {
- lseek(lfd, 0, SEEK_SET);
- write(lfd, fcont, sprintf(fcont, "%ld %d\n", time(0), numtries));
- } else
- unlink(fname);
- }
+ if (ret == AuthBad) {
+ write(tfd, fcont, sprintf(fcont, "%lu\n", time(0)+left));
+ } else
+ unlink(fname);
+
+ unlink(tmpname);
+
+ if (ret == AuthBad)
+ sleep(left);
+
+ close(tfd);
}
if (ret == AuthBad) {
message("Authentication failure\n");
@@ -417,6 +454,7 @@
}
}
}
+
return ret;
}
Index: kdebase.spec
===================================================================
RCS file: /cvs/dist/rpms/kdebase/devel/kdebase.spec,v
retrieving revision 1.119
retrieving revision 1.120
diff -u -r1.119 -r1.120
--- kdebase.spec 18 Aug 2005 13:48:06 -0000 1.119
+++ kdebase.spec 5 Sep 2005 12:10:19 -0000 1.120
@@ -63,6 +63,9 @@
Patch92: kdebase-3.4.0-xdg.patch
Patch93: kdebase-3.4.1-pam.patch
+# KDE Security Advisory: kcheckpass local root vulnerability CAN-2005-2494
+Patch200: post-3.4.2-kdebase-kcheckpass.diff
+
Requires: kdelibs >= 6:%{version}
Requires: libxml2 >= 2.6.5
Requires: /etc/X11/xdm/Xaccess
@@ -151,6 +154,10 @@
%patch92 -p1 -b .xdg
%patch93 -p1 -b .loginuid
+pushd kcheckpass
+%patch200 -p0 -b .CAN-2005-2494
+popd
+
%if %{rhel}
rm -rf kdeprint/kdeprintfax
perl -pi -e "s,kdeprintfax,," kdeprint/Makefile.am
@@ -439,6 +446,9 @@
%{_includedir}/kde/ksplash/*
%changelog
+* Mon Sep 05 2005 Than Ngo <than at redhat.com> 6:3.4.2-4
+- apply patch to fix local root vulnerability in kcheckpass CAN-2005-2494, #166997
+
* Thu Aug 18 2005 Than Ngo <than at redhat.com> 6:3.4.2-3
- update config files
More information about the fedora-cvs-commits
mailing list