summaryrefslogtreecommitdiff
path: root/x11/kdebase3
diff options
context:
space:
mode:
authorMichael Nottebrock <lofi@FreeBSD.org>2005-09-05 11:26:40 +0000
committerMichael Nottebrock <lofi@FreeBSD.org>2005-09-05 11:26:40 +0000
commit068cd2c16c400677ecf5893527613799881d8693 (patch)
tree4b05bf67bbbeab30b785afb437354da1839fa979 /x11/kdebase3
parentUpgrade to version 4.8. (diff)
Fix a potential local root vulnverability in kcheckpass.
Security: CAN-2005-2494
Notes
Notes: svn path=/head/; revision=141980
Diffstat (limited to 'x11/kdebase3')
-rw-r--r--x11/kdebase3/Makefile2
-rw-r--r--x11/kdebase3/files/patch-post-3.4.2-kdebase-kcheckpass.diff156
2 files changed, 157 insertions, 1 deletions
diff --git a/x11/kdebase3/Makefile b/x11/kdebase3/Makefile
index 9a9acf96aa95..b37100b46249 100644
--- a/x11/kdebase3/Makefile
+++ b/x11/kdebase3/Makefile
@@ -8,7 +8,7 @@
PORTNAME= kdebase
PORTVERSION= ${KDE_VERSION}
-PORTREVISION= 1
+PORTREVISION= 2
CATEGORIES= x11 kde
MASTER_SITES= ${MASTER_SITE_KDE}
MASTER_SITE_SUBDIR= stable/${PORTVERSION:S/.0//}/src
diff --git a/x11/kdebase3/files/patch-post-3.4.2-kdebase-kcheckpass.diff b/x11/kdebase3/files/patch-post-3.4.2-kdebase-kcheckpass.diff
new file mode 100644
index 000000000000..884f3e686ca8
--- /dev/null
+++ b/x11/kdebase3/files/patch-post-3.4.2-kdebase-kcheckpass.diff
@@ -0,0 +1,156 @@
+Index: kcheckpass.c
+===================================================================
+--- kcheckpass/kcheckpass.c (revision 453871)
++++ kcheckpass/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/spool/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/spool/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;
+ }
+