Hello community,

here is the log from the commit of package krb5.4619 for openSUSE:13.2:Update 
checked in at 2016-02-10 12:48:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:13.2:Update/krb5.4619 (Old)
 and      /work/SRC/openSUSE:13.2:Update/.krb5.4619.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "krb5.4619"

Changes:
--------
New Changes file:

--- /dev/null   2016-01-27 19:41:03.648095915 +0100
+++ /work/SRC/openSUSE:13.2:Update/.krb5.4619.new/krb5-mini.changes     
2016-02-10 12:48:51.000000000 +0100
@@ -0,0 +1,1304 @@
+-------------------------------------------------------------------
+Wed Mar 11 19:45:44 UTC 2015 - [email protected]
+
+- bnc#918595 VUL-0: CVE-2014-5355: krb5: denial of service in krb5_read_message
+patches:
+0001-Fix-krb5_read_message-handling-CVE-2014-5355.patch 
+
+-------------------------------------------------------------------
+Mon Feb 16 12:51:51 UTC 2015 - [email protected]
+
+- bnc#910457: CVE-2014-5353: NULL pointer dereference when using a ticket 
policy name as password name
+- bnc#910458: CVE-2014-5354: NULL pointer dereference when using keyless 
entries
+
+patches:
+krb5-1.12.2-CVE-2014-5353.patch  
+krb5-1.12.2-CVE-2014-5354.patch 
+
+-------------------------------------------------------------------
+Mon Feb  2 22:44:46 UTC 2015 - [email protected]
+
+- bnc#912002 VUL-0: CVE-2014-5352 CVE-2014-9421 CVE-2014-9422 CVE-2014-9423:
+  krb5: Vulnerabilities in kadmind, libgssrpc, gss_process_context_token
+- added patches:
+  * bnc#912002.diff
+
+-------------------------------------------------------------------
+Thu Sep 25 12:48:32 UTC 2014 - [email protected]
+
+- Work around replay cache creation race; (bnc#898439).
+  krb5-1.13-work-around-replay-cache-creation-race.patch
+
+-------------------------------------------------------------------
+Tue Sep 23 13:25:33 UTC 2014 - [email protected]
+
+-  bnc#897874 CVE-2014-5351: krb5: current keys returned when randomizing the 
keys for a service principal 
+- added patches:
+  * bnc#897874-CVE-2014-5351.diff
+-------------------------------------------------------------------
+Sat Aug 30 22:29:28 UTC 2014 - [email protected]
+
+- krb5 5.12.2:
+  * Work around a gcc optimizer bug that could cause DB2 KDC
+    database operations to spin in an infinite loop
+  * Fix a backward compatibility problem with the LDAP KDB schema
+    that could prevent krb5-1.11 and later from decoding entries
+    created by krb5-1.6.
+  * Avoid an infinite loop under some circumstances when the GSS
+    mechglue loads a dynamic mechanism.
+  * Fix krb5kdc argument parsing so "-w" and "-r" options work
+    togetherreliably.
+- Vulnerability fixes previously fixed in package via patches:
+  * Handle certain invalid RFC 1964 GSS tokens correctly to avoid
+    invalid memory reference vulnerabilities.  [CVE-2014-4341
+    CVE-2014-4342]
+  * Fix memory management vulnerabilities in GSSAPI SPNEGO.
+    [CVE-2014-4343 CVE-2014-4344]
+  * Fix buffer overflow vulnerability in LDAP KDB back end.
+    [CVE-2014-4345]
+- updated patches:
+  * krb5-1.7-doublelog.patch for context change
+  * krb5-1.6.3-ktutil-manpage.dif, same
+- removed patches, in upstream:
+  * krb5-master-keyring-kdcsync.patch
+  * krb5-1.12-CVE-2014-4341-CVE-2014-4342.patch
+  * krb5-1.12-CVE-2014-4343-Fix-double-free-in-SPNEGO.patch
+  * krb5-1.12-CVE-2014-4344-Fix-null-deref-in-SPNEGO-acceptor.patch
+  * krb5-1.12-CVE-2014-4345-buffer-overrun-in-kadmind-with-LDAP-backend.patch
+- Fix build with doxygen 1.8.8 - adding krb5-1.12-doxygen.patch
+  from upstream
+
+-------------------------------------------------------------------
+Fri Aug  8 15:55:01 UTC 2014 - [email protected]
+
+- buffer overrun in kadmind with LDAP backend
+  CVE-2014-4345 (bnc#891082)
+  krb5-1.12-CVE-2014-4345-buffer-overrun-in-kadmind-with-LDAP-backend.patch 
+
+-------------------------------------------------------------------
+Mon Jul 28 09:22:06 UTC 2014 - [email protected]
+
+- Fix double-free in SPNEGO [CVE-2014-4343] (bnc#888697)
+  krb5-1.12-CVE-2014-4343-Fix-double-free-in-SPNEGO.patch
+  Fix null deref in SPNEGO acceptor [CVE-2014-4344]
+  krb5-1.12-CVE-2014-4344-Fix-null-deref-in-SPNEGO-acceptor.patch
+
+-------------------------------------------------------------------
+Sat Jul 19 12:38:21 UTC 2014 - [email protected]
+
+- Do not depend of insserv if systemd is used 
+
+-------------------------------------------------------------------
+Thu Jul 10 15:59:52 UTC 2014 - [email protected]
+
+- denial of service flaws when handling RFC 1964 tokens (bnc#886016)
+  krb5-1.12-CVE-2014-4341-CVE-2014-4342.patch
+- start krb5kdc after slapd (bnc#886102)
+
+-------------------------------------------------------------------
+Fri Jun  6 11:08:08 UTC 2014 - [email protected]
+
+- obsolete krb5-plugin-preauth-pkinit-nss (bnc#881674)
+  similar functionality is provided by krb5-plugin-preauth-pkinit
+
+-------------------------------------------------------------------
+Tue Feb 18 15:25:57 UTC 2014 - [email protected]
+
+- don't deliver SysV init files to systemd distributions
+
+-------------------------------------------------------------------
+Tue Jan 21 14:23:37 UTC 2014 - [email protected]
+
+- update to version 1.12.1
+  * Make KDC log service principal names more consistently during
+    some error conditions, instead of "<unknown server>"
+  * Fix several bugs related to building AES-NI support on less
+    common configurations
+  * Fix several bugs related to keyring credential caches
+- upstream obsoletes:
+  krb5-1.12-copy_context.patch
+  krb5-1.12-enable-NX.patch
+  krb5-1.12-pic-aes-ni.patch
+  krb5-master-no-malloc0.patch
+  krb5-master-ignore-empty-unnecessary-final-token.patch
+  krb5-master-gss_oid_leak.patch
+  krb5-master-keytab_close.patch
+  krb5-master-spnego_error_messages.patch
+- Fix Get time offsets for all keyring ccaches
+  krb5-master-keyring-kdcsync.patch (RT#7820)
+
+-------------------------------------------------------------------
+Mon Jan 13 15:37:16 UTC 2014 - [email protected]
+
+- update to version 1.12
+  * Add GSSAPI extensions for constructing MIC tokens using IOV lists
+  * Add a FAST OTP preauthentication module for the KDC which uses
+    RADIUS to validate OTP token values.
+  * The AES-based encryption types will use AES-NI instructions
+    when possible for improved performance.
+- revert dependency on libcom_err-mini-devel since it's not yet
+  available
+- update and rebase patches
+  * krb5-1.10-buildconf.patch -> krb5-1.12-buildconf.patch
+  * krb5-1.11-pam.patch -> krb5-1.12-pam.patch
+  * krb5-1.11-selinux-label.patch -> krb5-1.12-selinux-label.patch
+  * krb5-1.8-api.patch -> krb5-1.12-api.patch
+  * krb5-1.9-ksu-path.patch -> krb5-1.12-ksu-path.patch
+  * krb5-1.9-debuginfo.patch
+  * krb5-1.9-kprop-mktemp.patch
+  * krb5-kvno-230379.patch
+- added upstream patches
+  - Fix krb5_copy_context
+    * krb5-1.12-copy_context.patch
+  - Mark AESNI files as not needing executable stacks
+    * krb5-1.12-enable-NX.patch
+    * krb5-1.12-pic-aes-ni.patch
+  - Fix memory leak in SPNEGO initiator
+    * krb5-master-gss_oid_leak.patch
+  - Fix SPNEGO one-hop interop against old IIS
+    * krb5-master-ignore-empty-unnecessary-final-token.patch
+  - Fix GSS krb5 acceptor acquire_cred error handling 
+    * krb5-master-keytab_close.patch
+  - Avoid malloc(0) in SPNEGO get_input_token
+    * krb5-master-no-malloc0.patch
+  - Test SPNEGO error message in t_s4u.py
+    * krb5-master-spnego_error_messages.patch
+
+-------------------------------------------------------------------
+Tue Dec 10 02:43:32 UTC 2013 - [email protected]
+
+- Reduce build dependencies for krb5-mini by removing
+  doxygen and changing libcom_err-devel to
+  libcom_err-mini-devel
+- Small fix to pre_checkin.sh so krb5-mini.spec is correct.
+
+-------------------------------------------------------------------
+Fri Nov 15 13:33:53 UTC 2013 - [email protected]
+
+- update to version 1.11.4
+  - Fix a KDC null pointer dereference [CVE-2013-1417] that could
+    affect realms with an uncommon configuration.
+  - Fix a KDC null pointer dereference [CVE-2013-1418] that could
+    affect KDCs that serve multiple realms.
+  - Fix a number of bugs related to KDC master key rollover.
+
+-------------------------------------------------------------------
+Mon Jun 24 16:21:07 UTC 2013 - [email protected]
+
+- install and enable systemd service files also in -mini package
+
+-------------------------------------------------------------------
+Fri Jun 21 02:12:03 UTC 2013 - [email protected]
+
+- remove fstack-protector-all from CFLAGS, just use the 
+  lighter/fast version already present in %optflags
+
+- Use LFS_CFLAGS to build in 32 bit archs.
+
++++ 1107 more lines (skipped)
++++ between /dev/null
++++ and /work/SRC/openSUSE:13.2:Update/.krb5.4619.new/krb5-mini.changes
New Changes file:

--- /dev/null   2016-01-27 19:41:03.648095915 +0100
+++ /work/SRC/openSUSE:13.2:Update/.krb5.4619.new/krb5.changes  2016-02-10 
12:48:52.000000000 +0100
@@ -0,0 +1,1334 @@
+-------------------------------------------------------------------
+Tue Feb  2 08:37:15 UTC 2016 - [email protected]
+
+- Fix CVE-2015-8629: krb5: xdr_nullstring() doesn't check for terminating null 
character
+  with patch 0104-Verify-decoded-kadmin-C-strings-CVE-2015-8629.patch
+  (bsc#963968)
+- Fix CVE-2015-8631: krb5: Memory leak caused by supplying a null principal 
name in request
+  with patch 0105-Fix-leaks-in-kadmin-server-stubs-CVE-2015-8631.patch
+  (bsc#963975)
+- Fix CVE-2015-8630: krb5: krb5 doesn't check for null policy when 
KADM5_POLICY is set in the mask
+  with patch 0106-Check-for-null-kadm5-policy-name-CVE-2015-8630.patch
+  (bsc#963964)
+
+-------------------------------------------------------------------
+Tue Nov 10 14:54:51 UTC 2015 - [email protected]
+
+- Apply patch 0103-Fix-IAKERB-context-export-import-CVE-2015-2698.patch
+  to fix a memory corruption regression introduced by resolution of
+  CVE-2015-2698. bsc#954204
+
+-------------------------------------------------------------------
+Wed Oct 28 14:42:38 UTC 2015 - [email protected]
+
+- Apply patch 0100-Fix-build_principal-memory-bug-CVE-2015-2697.patch
+  to fix build_principal memory bug [CVE-2015-2697] bsc#952190
+- Apply patch 0101-Fix-IAKERB-context-aliasing-bugs-CVE-2015-2696.patch
+  to fix IAKERB context aliasing bugs [CVE-2015-2696] bsc#952189
+- Apply patch 0102-Fix-SPNEGO-context-aliasing-bugs-CVE-2015-2695.patch
+  to fix SPNEGO context aliasing bugs [CVE-2015-2695] bsc#952188
+
+-------------------------------------------------------------------
+Wed Mar 11 19:45:44 UTC 2015 - [email protected]
+
+- bnc#918595 VUL-0: CVE-2014-5355: krb5: denial of service in krb5_read_message
+patches:
+0001-Fix-krb5_read_message-handling-CVE-2014-5355.patch 
+
+-------------------------------------------------------------------
+Mon Feb 16 12:51:51 UTC 2015 - [email protected]
+
+- bnc#910457: CVE-2014-5353: NULL pointer dereference when using a ticket 
policy name as password name
+- bnc#910458: CVE-2014-5354: NULL pointer dereference when using keyless 
entries
+
+patches:
+krb5-1.12.2-CVE-2014-5353.patch  
+krb5-1.12.2-CVE-2014-5354.patch 
+
+-------------------------------------------------------------------
+Mon Feb  2 22:44:46 UTC 2015 - [email protected]
+
+- bnc#912002 VUL-0: CVE-2014-5352 CVE-2014-9421 CVE-2014-9422 CVE-2014-9423:
+  krb5: Vulnerabilities in kadmind, libgssrpc, gss_process_context_token
+- added patches:
+  * bnc#912002.diff
+
+-------------------------------------------------------------------
+Thu Sep 25 12:48:32 UTC 2014 - [email protected]
+
+- Work around replay cache creation race; (bnc#898439).
+  krb5-1.13-work-around-replay-cache-creation-race.patch
+
+-------------------------------------------------------------------
+Tue Sep 23 13:25:33 UTC 2014 - [email protected]
+
+-  bnc#897874 CVE-2014-5351: krb5: current keys returned when randomizing the 
keys for a service principal 
+- added patches:
+  * bnc#897874-CVE-2014-5351.diff
+-------------------------------------------------------------------
+Sat Aug 30 22:29:28 UTC 2014 - [email protected]
+
+- krb5 5.12.2:
+  * Work around a gcc optimizer bug that could cause DB2 KDC
+    database operations to spin in an infinite loop
+  * Fix a backward compatibility problem with the LDAP KDB schema
+    that could prevent krb5-1.11 and later from decoding entries
+    created by krb5-1.6.
+  * Avoid an infinite loop under some circumstances when the GSS
+    mechglue loads a dynamic mechanism.
+  * Fix krb5kdc argument parsing so "-w" and "-r" options work
+    togetherreliably.
+- Vulnerability fixes previously fixed in package via patches:
+  * Handle certain invalid RFC 1964 GSS tokens correctly to avoid
+    invalid memory reference vulnerabilities.  [CVE-2014-4341
+    CVE-2014-4342]
+  * Fix memory management vulnerabilities in GSSAPI SPNEGO.
+    [CVE-2014-4343 CVE-2014-4344]
+  * Fix buffer overflow vulnerability in LDAP KDB back end.
+    [CVE-2014-4345]
+- updated patches:
+  * krb5-1.7-doublelog.patch for context change
+  * krb5-1.6.3-ktutil-manpage.dif, same
+- removed patches, in upstream:
+  * krb5-master-keyring-kdcsync.patch
+  * krb5-1.12-CVE-2014-4341-CVE-2014-4342.patch
+  * krb5-1.12-CVE-2014-4343-Fix-double-free-in-SPNEGO.patch
+  * krb5-1.12-CVE-2014-4344-Fix-null-deref-in-SPNEGO-acceptor.patch
+  * krb5-1.12-CVE-2014-4345-buffer-overrun-in-kadmind-with-LDAP-backend.patch
+- Fix build with doxygen 1.8.8 - adding krb5-1.12-doxygen.patch
+  from upstream
+
+-------------------------------------------------------------------
+Fri Aug  8 15:55:01 UTC 2014 - [email protected]
+
+- buffer overrun in kadmind with LDAP backend
+  CVE-2014-4345 (bnc#891082)
+  krb5-1.12-CVE-2014-4345-buffer-overrun-in-kadmind-with-LDAP-backend.patch 
+
+-------------------------------------------------------------------
+Mon Jul 28 09:22:06 UTC 2014 - [email protected]
+
+- Fix double-free in SPNEGO [CVE-2014-4343] (bnc#888697)
+  krb5-1.12-CVE-2014-4343-Fix-double-free-in-SPNEGO.patch
+  Fix null deref in SPNEGO acceptor [CVE-2014-4344]
+  krb5-1.12-CVE-2014-4344-Fix-null-deref-in-SPNEGO-acceptor.patch
+
+-------------------------------------------------------------------
+Sat Jul 19 12:38:21 UTC 2014 - [email protected]
+
+- Do not depend of insserv if systemd is used 
+
+-------------------------------------------------------------------
+Thu Jul 10 15:59:52 UTC 2014 - [email protected]
+
+- denial of service flaws when handling RFC 1964 tokens (bnc#886016)
+  krb5-1.12-CVE-2014-4341-CVE-2014-4342.patch
+- start krb5kdc after slapd (bnc#886102)
+
+-------------------------------------------------------------------
+Fri Jun  6 11:08:08 UTC 2014 - [email protected]
+
+- obsolete krb5-plugin-preauth-pkinit-nss (bnc#881674)
+  similar functionality is provided by krb5-plugin-preauth-pkinit
+
+-------------------------------------------------------------------
+Tue Feb 18 15:25:57 UTC 2014 - [email protected]
+
+- don't deliver SysV init files to systemd distributions
+
+-------------------------------------------------------------------
+Tue Jan 21 14:23:37 UTC 2014 - [email protected]
+
+- update to version 1.12.1
+  * Make KDC log service principal names more consistently during
+    some error conditions, instead of "<unknown server>"
+  * Fix several bugs related to building AES-NI support on less
+    common configurations
+  * Fix several bugs related to keyring credential caches
+- upstream obsoletes:
+  krb5-1.12-copy_context.patch
+  krb5-1.12-enable-NX.patch
+  krb5-1.12-pic-aes-ni.patch
+  krb5-master-no-malloc0.patch
+  krb5-master-ignore-empty-unnecessary-final-token.patch
+  krb5-master-gss_oid_leak.patch
+  krb5-master-keytab_close.patch
+  krb5-master-spnego_error_messages.patch
+- Fix Get time offsets for all keyring ccaches
+  krb5-master-keyring-kdcsync.patch (RT#7820)
+
+-------------------------------------------------------------------
+Mon Jan 13 15:37:16 UTC 2014 - [email protected]
+
+- update to version 1.12
+  * Add GSSAPI extensions for constructing MIC tokens using IOV lists
+  * Add a FAST OTP preauthentication module for the KDC which uses
+    RADIUS to validate OTP token values.
+  * The AES-based encryption types will use AES-NI instructions
+    when possible for improved performance.
+- revert dependency on libcom_err-mini-devel since it's not yet
+  available
+- update and rebase patches
+  * krb5-1.10-buildconf.patch -> krb5-1.12-buildconf.patch
+  * krb5-1.11-pam.patch -> krb5-1.12-pam.patch
+  * krb5-1.11-selinux-label.patch -> krb5-1.12-selinux-label.patch
+  * krb5-1.8-api.patch -> krb5-1.12-api.patch
+  * krb5-1.9-ksu-path.patch -> krb5-1.12-ksu-path.patch
+  * krb5-1.9-debuginfo.patch
+  * krb5-1.9-kprop-mktemp.patch
+  * krb5-kvno-230379.patch
+- added upstream patches
+  - Fix krb5_copy_context
+    * krb5-1.12-copy_context.patch
+  - Mark AESNI files as not needing executable stacks
+    * krb5-1.12-enable-NX.patch
+    * krb5-1.12-pic-aes-ni.patch
+  - Fix memory leak in SPNEGO initiator
+    * krb5-master-gss_oid_leak.patch
+  - Fix SPNEGO one-hop interop against old IIS
+    * krb5-master-ignore-empty-unnecessary-final-token.patch
+  - Fix GSS krb5 acceptor acquire_cred error handling 
+    * krb5-master-keytab_close.patch
+  - Avoid malloc(0) in SPNEGO get_input_token
+    * krb5-master-no-malloc0.patch
+  - Test SPNEGO error message in t_s4u.py
+    * krb5-master-spnego_error_messages.patch
+
+-------------------------------------------------------------------
++++ 1137 more lines (skipped)
++++ between /dev/null
++++ and /work/SRC/openSUSE:13.2:Update/.krb5.4619.new/krb5.changes

New:
----
  0001-Fix-krb5_read_message-handling-CVE-2014-5355.patch
  0100-Fix-build_principal-memory-bug-CVE-2015-2697.patch
  0101-Fix-IAKERB-context-aliasing-bugs-CVE-2015-2696.patch
  0102-Fix-SPNEGO-context-aliasing-bugs-CVE-2015-2695.patch
  0103-Fix-IAKERB-context-export-import-CVE-2015-2698.patch
  0104-Verify-decoded-kadmin-C-strings-CVE-2015-8629.patch
  0105-Fix-leaks-in-kadmin-server-stubs-CVE-2015-8631.patch
  0106-Check-for-null-kadm5-policy-name-CVE-2015-8630.patch
  baselibs.conf
  bnc#897874-CVE-2014-5351.diff
  bnc#912002.diff
  krb5-1.10-kpasswd_tcp.patch
  krb5-1.10-ksu-access.patch
  krb5-1.12-api.patch
  krb5-1.12-buildconf.patch
  krb5-1.12-doxygen.patch
  krb5-1.12-ksu-path.patch
  krb5-1.12-pam.patch
  krb5-1.12-selinux-label.patch
  krb5-1.12.2-CVE-2014-5353.patch
  krb5-1.12.2-CVE-2014-5354.patch
  krb5-1.12.2.tar.gz
  krb5-1.13-work-around-replay-cache-creation-race.patch
  krb5-1.6.3-gssapi_improve_errormessages.dif
  krb5-1.6.3-ktutil-manpage.dif
  krb5-1.7-doublelog.patch
  krb5-1.9-debuginfo.patch
  krb5-1.9-kprop-mktemp.patch
  krb5-1.9-manpaths.dif
  krb5-kvno-230379.patch
  krb5-mini.changes
  krb5-mini.spec
  krb5-rpmlintrc
  krb5.changes
  krb5.spec
  pre_checkin.sh
  vendor-files.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ krb5-mini.spec ++++++
++++ 733 lines (skipped)

krb5.spec: same change
++++++ 0001-Fix-krb5_read_message-handling-CVE-2014-5355.patch ++++++
>From 102bb6ebf20f9174130c85c3b052ae104e5073ec Mon Sep 17 00:00:00 2001
From: Greg Hudson <[email protected]>
Date: Tue, 9 Dec 2014 12:37:44 -0500
Subject: [PATCH] Fix krb5_read_message handling [CVE-2014-5355]

In recvauth_common, do not use strcmp against the data fields of
krb5_data objects populated by krb5_read_message(), as there is no
guarantee that they are C strings.  Instead, create an expected
krb5_data value and use data_eq().

In the sample user-to-user server application, check that the received
client principal name is null-terminated before using it with printf
and krb5_parse_name.

CVE-2014-5355:

In MIT krb5, when a server process uses the krb5_recvauth function, an
unauthenticated remote attacker can cause a NULL dereference by
sending a zero-byte version string, or a read beyond the end of
allocated storage by sending a non-null-terminated version string.
The example user-to-user server application (uuserver) is similarly
vulnerable to a zero-length or non-null-terminated principal name
string.

The krb5_recvauth function reads two version strings from the client
using krb5_read_message(), which produces a krb5_data structure
containing a length and a pointer to an octet sequence.  krb5_recvauth
assumes that the data pointer is a valid C string and passes it to
strcmp() to verify the versions.  If the client sends an empty octet
sequence, the data pointer will be NULL and strcmp() will dereference
a NULL pointer, causing the process to crash.  If the client sends a
non-null-terminated octet sequence, strcmp() will read beyond the end
of the allocated storage, possibly causing the process to crash.

uuserver similarly uses krb5_read_message() to read a client principal
name, and then passes it to printf() and krb5_parse_name() without
verifying that it is a valid C string.

The krb5_recvauth function is used by kpropd and the Kerberized
versions of the BSD rlogin and rsh daemons.  These daemons are usually
run out of inetd or in a mode which forks before processing incoming
connections, so a process crash will generally not result in a
complete denial of service.

Thanks to Tim Uglow for discovering this issue.

CVSSv2: AV:N/AC:L/Au:N/C:N/I:N/A:P/E:POC/RL:OF/RC:C

[[email protected]: CVSS score]

ticket: 8050 (new)
target_version: 1.13.1
tags: pullup
---
 src/appl/user_user/server.c | 4 +++-
 src/lib/krb5/krb/recvauth.c | 9 ++++++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/appl/user_user/server.c b/src/appl/user_user/server.c
index 09ea4e0..f2b5b61 100644
--- a/src/appl/user_user/server.c
+++ b/src/appl/user_user/server.c
@@ -111,8 +111,10 @@ int main(argc, argv)
     }
 #endif
 
+    /* principal name must be sent null-terminated. */
     retval = krb5_read_message(context, (krb5_pointer) &sock, &pname_data);
-    if (retval) {
+    if (retval || pname_data.length == 0 ||
+        pname_data.data[pname_data.length - 1] != '\0') {
         com_err ("uu-server", retval, "reading pname");
         return 2;
     }
diff --git a/src/lib/krb5/krb/recvauth.c b/src/lib/krb5/krb/recvauth.c
index da836283..5adc6dd 100644
--- a/src/lib/krb5/krb/recvauth.c
+++ b/src/lib/krb5/krb/recvauth.c
@@ -59,6 +59,7 @@ recvauth_common(krb5_context context,
     krb5_rcache           rcache = 0;
     krb5_octet            response;
     krb5_data             null_server;
+    krb5_data             d;
     int                   need_error_free = 0;
     int                   local_rcache = 0, local_authcon = 0;
 
@@ -77,7 +78,8 @@ recvauth_common(krb5_context context,
          */
         if ((retval = krb5_read_message(context, fd, &inbuf)))
             return(retval);
-        if (strcmp(inbuf.data, sendauth_version)) {
+        d = make_data((char *)sendauth_version, strlen(sendauth_version) + 1);
+        if (!data_eq(inbuf, d)) {
             problem = KRB5_SENDAUTH_BADAUTHVERS;
             response = 1;
         }
@@ -93,8 +95,9 @@ recvauth_common(krb5_context context,
      */
     if ((retval = krb5_read_message(context, fd, &inbuf)))
         return(retval);
-    if (appl_version && strcmp(inbuf.data, appl_version)) {
-        if (!problem) {
+    if (appl_version != NULL && !problem) {
+        d = make_data(appl_version, strlen(appl_version) + 1);
+        if (!data_eq(inbuf, d)) {
             problem = KRB5_SENDAUTH_BADAPPLVERS;
             response = 2;
         }
-- 
1.8.5.2

++++++ 0100-Fix-build_principal-memory-bug-CVE-2015-2697.patch ++++++
>From f0c094a1b745d91ef2f9a4eae2149aac026a5789 Mon Sep 17 00:00:00 2001
From: Greg Hudson <[email protected]>
Date: Fri, 25 Sep 2015 12:51:47 -0400
Subject: [PATCH] Fix build_principal memory bug [CVE-2015-2697]

In build_principal_va(), use k5memdup0() instead of strdup() to make a
copy of the realm, to ensure that we allocate the correct number of
bytes and do not read past the end of the input string.  This bug
affects krb5_build_principal(), krb5_build_principal_va(), and
krb5_build_principal_alloc_va().  krb5_build_principal_ext() is not
affected.

CVE-2015-2697:

In MIT krb5 1.7 and later, an authenticated attacker may be able to
cause a KDC to crash using a TGS request with a large realm field
beginning with a null byte.  If the KDC attempts to find a referral to
answer the request, it constructs a principal name for lookup using
krb5_build_principal() with the requested realm.  Due to a bug in this
function, the null byte causes only one byte be allocated for the
realm field of the constructed principal, far less than its length.
Subsequent operations on the lookup principal may cause a read beyond
the end of the mapped memory region, causing the KDC process to crash.

CVSSv2: AV:N/AC:L/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C

ticket: 8252 (new)
target_version: 1.14
tags: pullup

diff --git a/src/lib/krb5/krb/bld_princ.c b/src/lib/krb5/krb/bld_princ.c
index ab6fed8..8604268 100644
--- a/src/lib/krb5/krb/bld_princ.c
+++ b/src/lib/krb5/krb/bld_princ.c
@@ -40,10 +40,8 @@ build_principal_va(krb5_context context, krb5_principal 
princ,
     data = malloc(size * sizeof(krb5_data));
     if (!data) { retval = ENOMEM; }
 
-    if (!retval) {
-        r = strdup(realm);
-        if (!r) { retval = ENOMEM; }
-    }
+    if (!retval)
+        r = k5memdup0(realm, rlen, &retval);
 
     while (!retval && (component = va_arg(ap, char *))) {
         if (count == size) {
-- 
2.6.2

++++++ 0101-Fix-IAKERB-context-aliasing-bugs-CVE-2015-2696.patch ++++++
++++ 729 lines (skipped)

++++++ 0102-Fix-SPNEGO-context-aliasing-bugs-CVE-2015-2695.patch ++++++
>From b51b33f2bc5d1497ddf5bd107f791c101695000d Mon Sep 17 00:00:00 2001
From: Nicolas Williams <[email protected]>
Date: Mon, 14 Sep 2015 12:27:52 -0400
Subject: [PATCH] Fix SPNEGO context aliasing bugs [CVE-2015-2695]

The SPNEGO mechanism currently replaces its context handle with the
mechanism context handle upon establishment, under the assumption that
most GSS functions are only called after context establishment.  This
assumption is incorrect, and can lead to aliasing violations for some
programs.  Maintain the SPNEGO context structure after context
establishment and refer to it in all GSS methods.  Add initiate and
opened flags to the SPNEGO context structure for use in
gss_inquire_context() prior to context establishment.

CVE-2015-2695:

In MIT krb5 1.5 and later, applications which call
gss_inquire_context() on a partially-established SPNEGO context can
cause the GSS-API library to read from a pointer using the wrong type,
generally causing a process crash.  This bug may go unnoticed, because
the most common SPNEGO authentication scenario establishes the context
after just one call to gss_accept_sec_context().  Java server
applications using the native JGSS provider are vulnerable to this
bug.  A carefully crafted SPNEGO packet might allow the
gss_inquire_context() call to succeed with attacker-determined
results, but applications should not make access control decisions
based on gss_inquire_context() results prior to context establishment.

    CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:C/E:POC/RL:OF/RC:C

[[email protected]: several bugfixes, style changes, and edge-case
behavior changes; commit message and CVE description]

ticket: 8244
target_version: 1.14
tags: pullup

diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h 
b/src/lib/gssapi/spnego/gssapiP_spnego.h
index 57372de..5c82764 100644
--- a/src/lib/gssapi/spnego/gssapiP_spnego.h
+++ b/src/lib/gssapi/spnego/gssapiP_spnego.h
@@ -103,6 +103,8 @@ typedef struct {
        int firstpass;
        int mech_complete;
        int nego_done;
+       int initiate;
+       int opened;
        OM_uint32 ctx_flags;
        gss_name_t internal_name;
        gss_OID actual_mech;
diff --git a/src/lib/gssapi/spnego/spnego_mech.c 
b/src/lib/gssapi/spnego/spnego_mech.c
index ef76e1f..7849c85 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -102,7 +102,7 @@ static OM_uint32 get_negotiable_mechs(OM_uint32 *, 
spnego_gss_cred_id_t,
                                      gss_cred_usage_t, gss_OID_set *);
 static void release_spnego_ctx(spnego_gss_ctx_id_t *);
 static void check_spnego_options(spnego_gss_ctx_id_t);
-static spnego_gss_ctx_id_t create_spnego_ctx(void);
+static spnego_gss_ctx_id_t create_spnego_ctx(int);
 static int put_mech_set(gss_OID_set mechSet, gss_buffer_t buf);
 static int put_input_token(unsigned char **, gss_buffer_t, unsigned int);
 static int put_mech_oid(unsigned char **, gss_OID_const, unsigned int);
@@ -454,7 +454,7 @@ check_spnego_options(spnego_gss_ctx_id_t spnego_ctx)
 }
 
 static spnego_gss_ctx_id_t
-create_spnego_ctx(void)
+create_spnego_ctx(int initiate)
 {
        spnego_gss_ctx_id_t spnego_ctx = NULL;
        spnego_ctx = (spnego_gss_ctx_id_t)
@@ -477,6 +477,8 @@ create_spnego_ctx(void)
        spnego_ctx->mic_rcvd = 0;
        spnego_ctx->mech_complete = 0;
        spnego_ctx->nego_done = 0;
+       spnego_ctx->opened = 0;
+       spnego_ctx->initiate = initiate;
        spnego_ctx->internal_name = GSS_C_NO_NAME;
        spnego_ctx->actual_mech = GSS_C_NO_OID;
 
@@ -642,7 +644,7 @@ init_ctx_new(OM_uint32 *minor_status,
        OM_uint32 ret;
        spnego_gss_ctx_id_t sc = NULL;
 
-       sc = create_spnego_ctx();
+       sc = create_spnego_ctx(1);
        if (sc == NULL)
                return GSS_S_FAILURE;
 
@@ -659,10 +661,7 @@ init_ctx_new(OM_uint32 *minor_status,
                ret = GSS_S_FAILURE;
                goto cleanup;
        }
-       /*
-        * The actual context is not yet determined, set the output
-        * context handle to refer to the spnego context itself.
-        */
+
        sc->ctx_handle = GSS_C_NO_CONTEXT;
        *ctx = (gss_ctx_id_t)sc;
        sc = NULL;
@@ -1108,16 +1107,11 @@ cleanup:
        }
        gss_release_buffer(&tmpmin, &mechtok_out);
        if (ret == GSS_S_COMPLETE) {
-               /*
-                * Now, switch the output context to refer to the
-                * negotiated mechanism's context.
-                */
-               *context_handle = (gss_ctx_id_t)spnego_ctx->ctx_handle;
+               spnego_ctx->opened = 1;
                if (actual_mech != NULL)
                        *actual_mech = spnego_ctx->actual_mech;
                if (ret_flags != NULL)
                        *ret_flags = spnego_ctx->ctx_flags;
-               release_spnego_ctx(&spnego_ctx);
        } else if (ret != GSS_S_CONTINUE_NEEDED) {
                if (spnego_ctx != NULL) {
                        gss_delete_sec_context(&tmpmin,
@@ -1285,7 +1279,7 @@ acc_ctx_hints(OM_uint32 *minor_status,
        if (ret != GSS_S_COMPLETE)
                goto cleanup;
 
-       sc = create_spnego_ctx();
+       sc = create_spnego_ctx(0);
        if (sc == NULL) {
                ret = GSS_S_FAILURE;
                goto cleanup;
@@ -1367,7 +1361,7 @@ acc_ctx_new(OM_uint32 *minor_status,
                gss_release_buffer(&tmpmin, &sc->DER_mechTypes);
                assert(mech_wanted != GSS_C_NO_OID);
        } else
-               sc = create_spnego_ctx();
+               sc = create_spnego_ctx(0);
        if (sc == NULL) {
                ret = GSS_S_FAILURE;
                *return_token = NO_TOKEN_SEND;
@@ -1750,13 +1744,12 @@ cleanup:
                        ret = GSS_S_FAILURE;
        }
        if (ret == GSS_S_COMPLETE) {
-               *context_handle = (gss_ctx_id_t)sc->ctx_handle;
+               sc->opened = 1;
                if (sc->internal_name != GSS_C_NO_NAME &&
                    src_name != NULL) {
                        *src_name = sc->internal_name;
                        sc->internal_name = GSS_C_NO_NAME;
                }
-               release_spnego_ctx(&sc);
        } else if (ret != GSS_S_CONTINUE_NEEDED) {
                if (sc != NULL) {
                        gss_delete_sec_context(&tmpmin, &sc->ctx_handle,
@@ -2069,8 +2062,13 @@ spnego_gss_unwrap(
                gss_qop_t *qop_state)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_NO_CONTEXT);
+
        ret = gss_unwrap(minor_status,
-                       context_handle,
+                       sc->ctx_handle,
                        input_message_buffer,
                        output_message_buffer,
                        conf_state,
@@ -2090,8 +2088,13 @@ spnego_gss_wrap(
                gss_buffer_t output_message_buffer)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_NO_CONTEXT);
+
        ret = gss_wrap(minor_status,
-                   context_handle,
+                   sc->ctx_handle,
                    conf_req_flag,
                    qop_req,
                    input_message_buffer,
@@ -2108,8 +2111,14 @@ spnego_gss_process_context_token(
                                const gss_buffer_t token_buffer)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       /* SPNEGO doesn't have its own context tokens. */
+       if (!sc->opened)
+               return (GSS_S_DEFECTIVE_TOKEN);
+
        ret = gss_process_context_token(minor_status,
-                                       context_handle,
+                                       sc->ctx_handle,
                                        token_buffer);
 
        return (ret);
@@ -2133,19 +2142,9 @@ spnego_gss_delete_sec_context(
        if (*ctx == NULL)
                return (GSS_S_COMPLETE);
 
-       /*
-        * If this is still an SPNEGO mech, release it locally.
-        */
-       if ((*ctx)->magic_num == SPNEGO_MAGIC_ID) {
-               (void) gss_delete_sec_context(minor_status,
-                                   &(*ctx)->ctx_handle,
-                                   output_token);
-               (void) release_spnego_ctx(ctx);
-       } else {
-               ret = gss_delete_sec_context(minor_status,
-                                   context_handle,
-                                   output_token);
-       }
+       (void) gss_delete_sec_context(minor_status, &(*ctx)->ctx_handle,
+                                     output_token);
+       (void) release_spnego_ctx(ctx);
 
        return (ret);
 }
@@ -2157,8 +2156,13 @@ spnego_gss_context_time(
                        OM_uint32       *time_rec)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_NO_CONTEXT);
+
        ret = gss_context_time(minor_status,
-                           context_handle,
+                           sc->ctx_handle,
                            time_rec);
        return (ret);
 }
@@ -2170,9 +2174,20 @@ spnego_gss_export_sec_context(
                            gss_buffer_t interprocess_token)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = *(spnego_gss_ctx_id_t *)context_handle;
+
+       /* We don't currently support exporting partially established
+        * contexts. */
+       if (!sc->opened)
+               return GSS_S_UNAVAILABLE;
+
        ret = gss_export_sec_context(minor_status,
-                                   context_handle,
+                                   &sc->ctx_handle,
                                    interprocess_token);
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT) {
+               release_spnego_ctx(&sc);
+               *context_handle = GSS_C_NO_CONTEXT;
+       }
        return (ret);
 }
 
@@ -2182,11 +2197,12 @@ spnego_gss_import_sec_context(
        const gss_buffer_t      interprocess_token,
        gss_ctx_id_t            *context_handle)
 {
-       OM_uint32 ret;
-       ret = gss_import_sec_context(minor_status,
-                                   interprocess_token,
-                                   context_handle);
-       return (ret);
+       /*
+        * Until we implement partial context exports, there are no SPNEGO
+        * exported context tokens, only tokens for underlying mechs.  So just
+        * return an error for now.
+        */
+       return GSS_S_UNAVAILABLE;
 }
 #endif /* LEAN_CLIENT */
 
@@ -2203,16 +2219,48 @@ spnego_gss_inquire_context(
                        int             *opened)
 {
        OM_uint32 ret = GSS_S_COMPLETE;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       if (src_name != NULL)
+               *src_name = GSS_C_NO_NAME;
+       if (targ_name != NULL)
+               *targ_name = GSS_C_NO_NAME;
+       if (lifetime_rec != NULL)
+               *lifetime_rec = 0;
+       if (mech_type != NULL)
+               *mech_type = (gss_OID)gss_mech_spnego;
+       if (ctx_flags != NULL)
+               *ctx_flags = 0;
+       if (locally_initiated != NULL)
+               *locally_initiated = sc->initiate;
+       if (opened != NULL)
+               *opened = sc->opened;
+
+       if (sc->ctx_handle != GSS_C_NO_CONTEXT) {
+               ret = gss_inquire_context(minor_status, sc->ctx_handle,
+                                         src_name, targ_name, lifetime_rec,
+                                         mech_type, ctx_flags, NULL, NULL);
+       }
 
-       ret = gss_inquire_context(minor_status,
-                               context_handle,
-                               src_name,
-                               targ_name,
-                               lifetime_rec,
-                               mech_type,
-                               ctx_flags,
-                               locally_initiated,
-                               opened);
+       if (!sc->opened) {
+               /*
+                * We are still doing SPNEGO negotiation, so report SPNEGO as
+                * the OID.  After negotiation is complete we will report the
+                * underlying mechanism OID.
+                */
+               if (mech_type != NULL)
+                       *mech_type = (gss_OID)gss_mech_spnego;
+
+               /*
+                * Remove flags we don't support with partially-established
+                * contexts.  (Change this to keep GSS_C_TRANS_FLAG if we add
+                * support for exporting partial SPNEGO contexts.)
+                */
+               if (ctx_flags != NULL) {
+                       *ctx_flags &= ~GSS_C_PROT_READY_FLAG;
+                       *ctx_flags &= ~GSS_C_TRANS_FLAG;
+               }
+       }
 
        return (ret);
 }
@@ -2227,8 +2275,13 @@ spnego_gss_wrap_size_limit(
        OM_uint32       *max_input_size)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_NO_CONTEXT);
+
        ret = gss_wrap_size_limit(minor_status,
-                               context_handle,
+                               sc->ctx_handle,
                                conf_req_flag,
                                qop_req,
                                req_output_size,
@@ -2245,8 +2298,13 @@ spnego_gss_get_mic(
                gss_buffer_t message_token)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_NO_CONTEXT);
+
        ret = gss_get_mic(minor_status,
-                   context_handle,
+                   sc->ctx_handle,
                    qop_req,
                    message_buffer,
                    message_token);
@@ -2262,8 +2320,13 @@ spnego_gss_verify_mic(
                gss_qop_t *qop_state)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_NO_CONTEXT);
+
        ret = gss_verify_mic(minor_status,
-                           context_handle,
+                           sc->ctx_handle,
                            msg_buffer,
                            token_buffer,
                            qop_state);
@@ -2278,8 +2341,14 @@ spnego_gss_inquire_sec_context_by_oid(
                gss_buffer_set_t *data_set)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       /* There are no SPNEGO-specific OIDs for this function. */
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_UNAVAILABLE);
+
        ret = gss_inquire_sec_context_by_oid(minor_status,
-                           context_handle,
+                           sc->ctx_handle,
                            desired_object,
                            data_set);
        return (ret);
@@ -2359,8 +2428,15 @@ spnego_gss_set_sec_context_option(
                const gss_buffer_t value)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)*context_handle;
+
+       /* There are no SPNEGO-specific OIDs for this function, and we cannot
+        * construct an empty SPNEGO context with it. */
+       if (sc == NULL || sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_UNAVAILABLE);
+
        ret = gss_set_sec_context_option(minor_status,
-                           context_handle,
+                           &sc->ctx_handle,
                            desired_object,
                            value);
        return (ret);
@@ -2377,8 +2453,13 @@ spnego_gss_wrap_aead(OM_uint32 *minor_status,
                     gss_buffer_t output_message_buffer)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_NO_CONTEXT);
+
        ret = gss_wrap_aead(minor_status,
-                           context_handle,
+                           sc->ctx_handle,
                            conf_req_flag,
                            qop_req,
                            input_assoc_buffer,
@@ -2399,8 +2480,13 @@ spnego_gss_unwrap_aead(OM_uint32 *minor_status,
                       gss_qop_t *qop_state)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_NO_CONTEXT);
+
        ret = gss_unwrap_aead(minor_status,
-                             context_handle,
+                             sc->ctx_handle,
                              input_message_buffer,
                              input_assoc_buffer,
                              output_payload_buffer,
@@ -2419,8 +2505,13 @@ spnego_gss_wrap_iov(OM_uint32 *minor_status,
                    int iov_count)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_NO_CONTEXT);
+
        ret = gss_wrap_iov(minor_status,
-                          context_handle,
+                          sc->ctx_handle,
                           conf_req_flag,
                           qop_req,
                           conf_state,
@@ -2438,8 +2529,13 @@ spnego_gss_unwrap_iov(OM_uint32 *minor_status,
                      int iov_count)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_NO_CONTEXT);
+
        ret = gss_unwrap_iov(minor_status,
-                            context_handle,
+                            sc->ctx_handle,
                             conf_state,
                             qop_state,
                             iov,
@@ -2457,8 +2553,13 @@ spnego_gss_wrap_iov_length(OM_uint32 *minor_status,
                           int iov_count)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_NO_CONTEXT);
+
        ret = gss_wrap_iov_length(minor_status,
-                                 context_handle,
+                                 sc->ctx_handle,
                                  conf_req_flag,
                                  qop_req,
                                  conf_state,
@@ -2475,8 +2576,13 @@ spnego_gss_complete_auth_token(
                gss_buffer_t input_message_buffer)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_UNAVAILABLE);
+
        ret = gss_complete_auth_token(minor_status,
-                                     context_handle,
+                                     sc->ctx_handle,
                                      input_message_buffer);
        return (ret);
 }
@@ -2721,8 +2827,13 @@ spnego_gss_pseudo_random(OM_uint32 *minor_status,
                         gss_buffer_t prf_out)
 {
        OM_uint32 ret;
+       spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context;
+
+       if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+               return (GSS_S_NO_CONTEXT);
+
        ret = gss_pseudo_random(minor_status,
-                               context,
+                               sc->ctx_handle,
                                prf_key,
                                prf_in,
                                desired_output_len,
@@ -2863,7 +2974,12 @@ spnego_gss_get_mic_iov(OM_uint32 *minor_status, 
gss_ctx_id_t context_handle,
                       gss_qop_t qop_req, gss_iov_buffer_desc *iov,
                       int iov_count)
 {
-    return gss_get_mic_iov(minor_status, context_handle, qop_req, iov,
+    spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+    if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+           return (GSS_S_NO_CONTEXT);
+
+    return gss_get_mic_iov(minor_status, sc->ctx_handle, qop_req, iov,
                           iov_count);
 }
 
@@ -2872,7 +2988,12 @@ spnego_gss_verify_mic_iov(OM_uint32 *minor_status, 
gss_ctx_id_t context_handle,
                          gss_qop_t *qop_state, gss_iov_buffer_desc *iov,
                          int iov_count)
 {
-    return gss_verify_mic_iov(minor_status, context_handle, qop_state, iov,
+    spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+    if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+           return (GSS_S_NO_CONTEXT);
+
+    return gss_verify_mic_iov(minor_status, sc->ctx_handle, qop_state, iov,
                              iov_count);
 }
 
@@ -2881,7 +3002,12 @@ spnego_gss_get_mic_iov_length(OM_uint32 *minor_status,
                              gss_ctx_id_t context_handle, gss_qop_t qop_req,
                              gss_iov_buffer_desc *iov, int iov_count)
 {
-    return gss_get_mic_iov_length(minor_status, context_handle, qop_req, iov,
+    spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
+
+    if (sc->ctx_handle == GSS_C_NO_CONTEXT)
+           return (GSS_S_NO_CONTEXT);
+
+    return gss_get_mic_iov_length(minor_status, sc->ctx_handle, qop_req, iov,
                                  iov_count);
 }
 
-- 
2.6.2

++++++ 0103-Fix-IAKERB-context-export-import-CVE-2015-2698.patch ++++++
>From 3db8dfec1ef50ddd78d6ba9503185995876a39fd Mon Sep 17 00:00:00 2001
From: Greg Hudson <[email protected]>
Date: Sun, 1 Nov 2015 22:45:21 -0500
Subject: [PATCH] Fix IAKERB context export/import [CVE-2015-2698]

The patches for CVE-2015-2696 contained a regression in the newly
added IAKERB iakerb_gss_export_sec_context() function, which could
cause it to corrupt memory.  Fix the regression by properly
dereferencing the context_handle pointer before casting it.

Also, the patches did not implement an IAKERB gss_import_sec_context()
function, under the erroneous belief that an exported IAKERB context
would be tagged as a krb5 context.  Implement it now to allow IAKERB
contexts to be successfully exported and imported after establishment.

CVE-2015-2698:

In any MIT krb5 release with the patches for CVE-2015-2696 applied, an
application which calls gss_export_sec_context() may experience memory
corruption if the context was established using the IAKERB mechanism.
Historically, some vulnerabilities of this nature can be translated
into remote code execution, though the necessary exploits must be
tailored to the individual application and are usually quite
complicated.

    CVSSv2 Vector: AV:N/AC:H/Au:S/C:C/I:C/A:C/E:POC/RL:OF/RC:C

ticket: 8273 (new)
target_version: 1.14
tags: pullup

Line numbers are adjusted by Howard Guo <[email protected]> to fit into this older
Kerberos version distributed on SLE 12.

diff -rupN krb5-1.12.1/src/lib/gssapi/krb5/gssapi_krb5.c 
krb5-1.12.1-patched/src/lib/gssapi/krb5/gssapi_krb5.c
--- krb5-1.12.1/src/lib/gssapi/krb5/gssapi_krb5.c       2015-11-10 
15:37:32.209657599 +0100
+++ krb5-1.12.1-patched/src/lib/gssapi/krb5/gssapi_krb5.c       2015-11-10 
15:38:52.106323672 +0100
@@ -945,7 +945,7 @@ static struct gss_config iakerb_mechanis
     NULL,
 #else
     iakerb_gss_export_sec_context,
-    NULL,
+    iakerb_gss_import_sec_context,
 #endif
     krb5_gss_inquire_cred_by_mech,
     krb5_gss_inquire_names_for_mech,
diff -rupN krb5-1.12.1/src/lib/gssapi/krb5/gssapiP_krb5.h 
krb5-1.12.1-patched/src/lib/gssapi/krb5/gssapiP_krb5.h
--- krb5-1.12.1/src/lib/gssapi/krb5/gssapiP_krb5.h      2015-11-10 
15:37:32.209657599 +0100
+++ krb5-1.12.1-patched/src/lib/gssapi/krb5/gssapiP_krb5.h      2015-11-10 
15:38:52.106323672 +0100
@@ -1393,6 +1393,11 @@ OM_uint32 KRB5_CALLCONV
 iakerb_gss_export_sec_context(OM_uint32 *minor_status,
                               gss_ctx_id_t *context_handle,
                               gss_buffer_t interprocess_token);
+
+OM_uint32 KRB5_CALLCONV
+iakerb_gss_import_sec_context(OM_uint32 *minor_status,
+                              const gss_buffer_t interprocess_token,
+                              gss_ctx_id_t *context_handle);
 #endif /* LEAN_CLIENT */
 
 OM_uint32 KRB5_CALLCONV
diff -rupN krb5-1.12.1/src/lib/gssapi/krb5/iakerb.c 
krb5-1.12.1-patched/src/lib/gssapi/krb5/iakerb.c
--- krb5-1.12.1/src/lib/gssapi/krb5/iakerb.c    2015-11-10 15:37:32.209657599 
+0100
+++ krb5-1.12.1-patched/src/lib/gssapi/krb5/iakerb.c    2015-11-10 
15:41:43.431752632 +0100
@@ -1061,7 +1061,7 @@ iakerb_gss_export_sec_context(OM_uint32
                               gss_buffer_t interprocess_token)
 {
     OM_uint32 maj;
-    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)*context_handle;
 
     /* We don't currently support exporting partially established contexts. */
     if (!ctx->established)
@@ -1076,12 +1076,41 @@ iakerb_gss_export_sec_context(OM_uint32
     return maj;
 }
 
-/*
- * Until we implement partial context exports, there are no SPNEGO exported
- * context tokens, only tokens for the underlying krb5 context.  So we do not
- * need to implement an iakerb_gss_import_sec_context() yet; it would be
- * unreachable except via a manually constructed token.
- */
+OM_uint32 KRB5_CALLCONV
+iakerb_gss_import_sec_context(OM_uint32 *minor_status,
+                              gss_buffer_t interprocess_token,
+                              gss_ctx_id_t *context_handle)
+{
+    OM_uint32 maj, tmpmin;
+    krb5_error_code code;
+    gss_ctx_id_t gssc;
+    krb5_gss_ctx_id_t kctx;
+    iakerb_ctx_id_t ctx;
+
+    maj = krb5_gss_import_sec_context(minor_status, interprocess_token, &gssc);
+    if (maj != GSS_S_COMPLETE)
+        return maj;
+    kctx = (krb5_gss_ctx_id_t)gssc;
+
+    if (!kctx->established) {
+        /* We don't currently support importing partially established
+         * contexts. */
+        krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER);
+        return GSS_S_FAILURE;
+    }
+
+    code = iakerb_alloc_context(&ctx, kctx->initiate);
+    if (code != 0) {
+        krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER);
+        *minor_status = code;
+        return GSS_S_FAILURE;
+    }
+
+    ctx->gssc = gssc;
+    ctx->established = 1;
+    *context_handle = (gss_ctx_id_t)ctx;
+    return GSS_S_COMPLETE;
+}
 
 #endif /* LEAN_CLIENT */
 
++++++ 0104-Verify-decoded-kadmin-C-strings-CVE-2015-8629.patch ++++++
>From df17a1224a3406f57477bcd372c61e04c0e5a5bb Mon Sep 17 00:00:00 2001
From: Greg Hudson <[email protected]>
Date: Fri, 8 Jan 2016 12:45:25 -0500
Subject: [PATCH] Verify decoded kadmin C strings [CVE-2015-8629]

In xdr_nullstring(), check that the decoded string is terminated with
a zero byte and does not contain any internal zero bytes.

CVE-2015-8629:

In all versions of MIT krb5, an authenticated attacker can cause
kadmind to read beyond the end of allocated memory by sending a string
without a terminating zero byte.  Information leakage may be possible
for an attacker with permission to modify the database.

    CVSSv2 Vector: AV:N/AC:H/Au:S/C:P/I:N/A:N/E:POC/RL:OF/RC:C

ticket: 8341 (new)
target_version: 1.14-next
target_version: 1.13-next
tags: pullup

diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c
index 2bef858..ba67084 100644
--- a/src/lib/kadm5/kadm_rpc_xdr.c
+++ b/src/lib/kadm5/kadm_rpc_xdr.c
@@ -64,7 +64,14 @@ bool_t xdr_nullstring(XDR *xdrs, char **objp)
                    return FALSE;
               }
          }
-         return (xdr_opaque(xdrs, *objp, size));
+         if (!xdr_opaque(xdrs, *objp, size))
+                 return FALSE;
+         /* Check that the unmarshalled bytes are a C string. */
+         if ((*objp)[size - 1] != '\0')
+                 return FALSE;
+         if (memchr(*objp, '\0', size - 1) != NULL)
+                 return FALSE;
+         return TRUE;
 
      case XDR_ENCODE:
          if (size != 0)
-- 
2.7.0

++++++ 0105-Fix-leaks-in-kadmin-server-stubs-CVE-2015-8631.patch ++++++
>From 83ed75feba32e46f736fcce0d96a0445f29b96c2 Mon Sep 17 00:00:00 2001
From: Greg Hudson <[email protected]>
Date: Fri, 8 Jan 2016 13:16:54 -0500
Subject: [PATCH] Fix leaks in kadmin server stubs [CVE-2015-8631]

In each kadmind server stub, initialize the client_name and
server_name variables, and release them in the cleanup handler.  Many
of the stubs will otherwise leak the client and server name if
krb5_unparse_name() fails.  Also make sure to free the prime_arg
variables in rename_principal_2_svc(), or we can leak the first one if
unparsing the second one fails.  Discovered by Simo Sorce.

CVE-2015-8631:

In all versions of MIT krb5, an authenticated attacker can cause
kadmind to leak memory by supplying a null principal name in a request
which uses one.  Repeating these requests will eventually cause
kadmind to exhaust all available memory.

    CVSSv2 Vector: AV:N/AC:L/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C

ticket: 8343 (new)
target_version: 1.14-next
target_version: 1.13-next
tags: pullup

diff --git a/src/kadmin/server/server_stubs.c b/src/kadmin/server/server_stubs.c
index 1879dc6..6ac797e 100644
--- a/src/kadmin/server/server_stubs.c
+++ b/src/kadmin/server/server_stubs.c
@@ -334,7 +334,8 @@ create_principal_2_svc(cprinc_arg *arg, struct svc_req 
*rqstp)
 {
     static generic_ret          ret;
     char                        *prime_arg;
-    gss_buffer_desc             client_name, service_name;
+    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                   minor_stat;
     kadm5_server_handle_t       handle;
     restriction_t               *rp;
@@ -382,10 +383,10 @@ create_principal_2_svc(cprinc_arg *arg, struct svc_req 
*rqstp)
             krb5_free_error_message(handle->context, errmsg);
     }
     free(prime_arg);
-    gss_release_buffer(&minor_stat, &client_name);
-    gss_release_buffer(&minor_stat, &service_name);
 
 exit_func:
+    gss_release_buffer(&minor_stat, &client_name);
+    gss_release_buffer(&minor_stat, &service_name);
     free_server_handle(handle);
     return &ret;
 }
@@ -395,7 +396,8 @@ create_principal3_2_svc(cprinc3_arg *arg, struct svc_req 
*rqstp)
 {
     static generic_ret          ret;
     char                        *prime_arg;
-    gss_buffer_desc             client_name, service_name;
+    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                   minor_stat;
     kadm5_server_handle_t       handle;
     restriction_t               *rp;
@@ -444,10 +446,10 @@ create_principal3_2_svc(cprinc3_arg *arg, struct svc_req 
*rqstp)
             krb5_free_error_message(handle->context, errmsg);
     }
     free(prime_arg);
-    gss_release_buffer(&minor_stat, &client_name);
-    gss_release_buffer(&minor_stat, &service_name);
 
 exit_func:
+    gss_release_buffer(&minor_stat, &client_name);
+    gss_release_buffer(&minor_stat, &service_name);
     free_server_handle(handle);
     return &ret;
 }
@@ -457,8 +459,8 @@ delete_principal_2_svc(dprinc_arg *arg, struct svc_req 
*rqstp)
 {
     static generic_ret              ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -501,10 +503,10 @@ delete_principal_2_svc(dprinc_arg *arg, struct svc_req 
*rqstp)
 
     }
     free(prime_arg);
-    gss_release_buffer(&minor_stat, &client_name);
-    gss_release_buffer(&minor_stat, &service_name);
 
 exit_func:
+    gss_release_buffer(&minor_stat, &client_name);
+    gss_release_buffer(&minor_stat, &service_name);
     free_server_handle(handle);
     return &ret;
 }
@@ -514,8 +516,8 @@ modify_principal_2_svc(mprinc_arg *arg, struct svc_req 
*rqstp)
 {
     static generic_ret              ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     restriction_t                   *rp;
@@ -559,9 +561,9 @@ modify_principal_2_svc(mprinc_arg *arg, struct svc_req 
*rqstp)
             krb5_free_error_message(handle->context, errmsg);
     }
     free(prime_arg);
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -570,10 +572,9 @@ generic_ret *
 rename_principal_2_svc(rprinc_arg *arg, struct svc_req *rqstp)
 {
     static generic_ret          ret;
-    char                        *prime_arg1,
-        *prime_arg2;
-    gss_buffer_desc             client_name,
-        service_name;
+    char                        *prime_arg1 = NULL, *prime_arg2 = NULL;
+    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                   minor_stat;
     kadm5_server_handle_t       handle;
     restriction_t               *rp;
@@ -655,11 +656,11 @@ rename_principal_2_svc(rprinc_arg *arg, struct svc_req 
*rqstp)
             krb5_free_error_message(handle->context, errmsg);
 
     }
+exit_func:
     free(prime_arg1);
     free(prime_arg2);
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -669,8 +670,8 @@ get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp)
 {
     static gprinc_ret               ret;
     char                            *prime_arg, *funcname;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -719,9 +720,9 @@ get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp)
             krb5_free_error_message(handle->context, errmsg);
     }
     free(prime_arg);
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -731,8 +732,8 @@ get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp)
 {
     static gprincs_ret              ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -777,9 +778,9 @@ get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp)
             krb5_free_error_message(handle->context, errmsg);
 
     }
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -789,8 +790,8 @@ chpass_principal_2_svc(chpass_arg *arg, struct svc_req 
*rqstp)
 {
     static generic_ret              ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -840,9 +841,9 @@ chpass_principal_2_svc(chpass_arg *arg, struct svc_req 
*rqstp)
     }
 
     free(prime_arg);
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -852,8 +853,8 @@ chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req 
*rqstp)
 {
     static generic_ret              ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -909,9 +910,9 @@ chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req 
*rqstp)
     }
 
     free(prime_arg);
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -921,8 +922,8 @@ setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req 
*rqstp)
 {
     static generic_ret              ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -969,9 +970,9 @@ setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req 
*rqstp)
     }
 
     free(prime_arg);
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -981,8 +982,8 @@ setkey_principal_2_svc(setkey_arg *arg, struct svc_req 
*rqstp)
 {
     static generic_ret              ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -1029,9 +1030,9 @@ setkey_principal_2_svc(setkey_arg *arg, struct svc_req 
*rqstp)
     }
 
     free(prime_arg);
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -1041,8 +1042,8 @@ setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req 
*rqstp)
 {
     static generic_ret              ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -1092,9 +1093,9 @@ setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req 
*rqstp)
     }
 
     free(prime_arg);
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -1106,8 +1107,8 @@ chrand_principal_2_svc(chrand_arg *arg, struct svc_req 
*rqstp)
     krb5_keyblock               *k;
     int                         nkeys;
     char                        *prime_arg, *funcname;
-    gss_buffer_desc             client_name,
-        service_name;
+    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                   minor_stat;
     kadm5_server_handle_t       handle;
     const char                  *errmsg = NULL;
@@ -1164,9 +1165,9 @@ chrand_principal_2_svc(chrand_arg *arg, struct svc_req 
*rqstp)
             krb5_free_error_message(handle->context, errmsg);
     }
     free(prime_arg);
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -1178,8 +1179,8 @@ chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req 
*rqstp)
     krb5_keyblock               *k;
     int                         nkeys;
     char                        *prime_arg, *funcname;
-    gss_buffer_desc             client_name,
-        service_name;
+    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                   minor_stat;
     kadm5_server_handle_t       handle;
     const char                  *errmsg = NULL;
@@ -1241,9 +1242,9 @@ chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req 
*rqstp)
             krb5_free_error_message(handle->context, errmsg);
     }
     free(prime_arg);
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -1253,8 +1254,8 @@ create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp)
 {
     static generic_ret              ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -1295,9 +1296,9 @@ create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp)
         if (errmsg != NULL)
             krb5_free_error_message(handle->context, errmsg);
     }
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -1307,8 +1308,8 @@ delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp)
 {
     static generic_ret              ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -1347,9 +1348,9 @@ delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp)
         if (errmsg != NULL)
             krb5_free_error_message(handle->context, errmsg);
     }
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -1359,8 +1360,8 @@ modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp)
 {
     static generic_ret              ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -1400,9 +1401,9 @@ modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp)
         if (errmsg != NULL)
             krb5_free_error_message(handle->context, errmsg);
     }
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -1413,8 +1414,8 @@ get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp)
     static gpol_ret             ret;
     kadm5_ret_t         ret2;
     char                        *prime_arg, *funcname;
-    gss_buffer_desc             client_name,
-        service_name;
+    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                   minor_stat;
     kadm5_principal_ent_rec     caller_ent;
     kadm5_server_handle_t       handle;
@@ -1475,9 +1476,9 @@ get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp)
         log_unauth(funcname, prime_arg,
                    &client_name, &service_name, rqstp);
     }
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 
@@ -1488,8 +1489,8 @@ get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp)
 {
     static gpols_ret                ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -1531,9 +1532,9 @@ get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp)
         if (errmsg != NULL)
             krb5_free_error_message(handle->context, errmsg);
     }
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -1541,7 +1542,8 @@ exit_func:
 getprivs_ret * get_privs_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
 {
     static getprivs_ret            ret;
-    gss_buffer_desc                client_name, service_name;
+    gss_buffer_desc                client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                      minor_stat;
     kadm5_server_handle_t          handle;
     const char                     *errmsg = NULL;
@@ -1571,9 +1573,9 @@ getprivs_ret * get_privs_2_svc(krb5_ui_4 *arg, struct 
svc_req *rqstp)
     if (errmsg != NULL)
         krb5_free_error_message(handle->context, errmsg);
 
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -1583,7 +1585,8 @@ purgekeys_2_svc(purgekeys_arg *arg, struct svc_req *rqstp)
 {
     static generic_ret          ret;
     char                        *prime_arg, *funcname;
-    gss_buffer_desc             client_name, service_name;
+    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                   minor_stat;
     kadm5_server_handle_t       handle;
 
@@ -1629,9 +1632,9 @@ purgekeys_2_svc(purgekeys_arg *arg, struct svc_req *rqstp)
             krb5_free_error_message(handle->context, errmsg);
     }
     free(prime_arg);
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -1641,8 +1644,8 @@ get_strings_2_svc(gstrings_arg *arg, struct svc_req 
*rqstp)
 {
     static gstrings_ret             ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -1688,9 +1691,9 @@ get_strings_2_svc(gstrings_arg *arg, struct svc_req 
*rqstp)
             krb5_free_error_message(handle->context, errmsg);
     }
     free(prime_arg);
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -1700,8 +1703,8 @@ set_string_2_svc(sstring_arg *arg, struct svc_req *rqstp)
 {
     static generic_ret              ret;
     char                            *prime_arg;
-    gss_buffer_desc                 client_name,
-        service_name;
+    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
     OM_uint32                       minor_stat;
     kadm5_server_handle_t           handle;
     const char                      *errmsg = NULL;
@@ -1744,9 +1747,9 @@ set_string_2_svc(sstring_arg *arg, struct svc_req *rqstp)
             krb5_free_error_message(handle->context, errmsg);
     }
     free(prime_arg);
+exit_func:
     gss_release_buffer(&minor_stat, &client_name);
     gss_release_buffer(&minor_stat, &service_name);
-exit_func:
     free_server_handle(handle);
     return &ret;
 }
@@ -1754,8 +1757,8 @@ exit_func:
 generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
 {
     static generic_ret         ret;
-    gss_buffer_desc            client_name,
-        service_name;
+    gss_buffer_desc            client_name = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc            service_name = GSS_C_EMPTY_BUFFER;
     kadm5_server_handle_t      handle;
     OM_uint32                  minor_stat;
     const char                 *errmsg = NULL;
@@ -1797,10 +1800,10 @@ generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req 
*rqstp)
                      rqstp->rq_cred.oa_flavor);
     if (errmsg != NULL)
         krb5_free_error_message(NULL, errmsg);
-    gss_release_buffer(&minor_stat, &client_name);
-    gss_release_buffer(&minor_stat, &service_name);
 
 exit_func:
+    gss_release_buffer(&minor_stat, &client_name);
+    gss_release_buffer(&minor_stat, &service_name);
     return(&ret);
 }
 
-- 
2.7.0

++++++ 0106-Check-for-null-kadm5-policy-name-CVE-2015-8630.patch ++++++
>From b863de7fbf080b15e347a736fdda0a82d42f4f6b Mon Sep 17 00:00:00 2001
From: Greg Hudson <[email protected]>
Date: Fri, 8 Jan 2016 12:52:28 -0500
Subject: [PATCH] Check for null kadm5 policy name [CVE-2015-8630]

In kadm5_create_principal_3() and kadm5_modify_principal(), check for
entry->policy being null when KADM5_POLICY is included in the mask.

CVE-2015-8630:

In MIT krb5 1.12 and later, an authenticated attacker with permission
to modify a principal entry can cause kadmind to dereference a null
pointer by supplying a null policy value but including KADM5_POLICY in
the mask.

    CVSSv2 Vector: AV:N/AC:H/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C

ticket: 8342 (new)
target_version: 1.14-next
target_version: 1.13-next
tags: pullup

diff --git a/src/lib/kadm5/srv/svr_principal.c 
b/src/lib/kadm5/srv/svr_principal.c
index 5b95fa3..1d4365c 100644
--- a/src/lib/kadm5/srv/svr_principal.c
+++ b/src/lib/kadm5/srv/svr_principal.c
@@ -395,6 +395,8 @@ kadm5_create_principal_3(void *server_handle,
     /*
      * Argument sanity checking, and opening up the DB
      */
+    if (entry == NULL)
+        return EINVAL;
     if(!(mask & KADM5_PRINCIPAL) || (mask & KADM5_MOD_NAME) ||
        (mask & KADM5_MOD_TIME) || (mask & KADM5_LAST_PWD_CHANGE) ||
        (mask & KADM5_MKVNO) || (mask & KADM5_AUX_ATTRIBUTES) ||
@@ -403,12 +405,12 @@ kadm5_create_principal_3(void *server_handle,
         return KADM5_BAD_MASK;
     if ((mask & KADM5_KEY_DATA) && entry->n_key_data != 0)
         return KADM5_BAD_MASK;
+    if((mask & KADM5_POLICY) && entry->policy == NULL)
+        return KADM5_BAD_MASK;
     if((mask & KADM5_POLICY) && (mask & KADM5_POLICY_CLR))
         return KADM5_BAD_MASK;
     if((mask & ~ALL_PRINC_MASK))
         return KADM5_BAD_MASK;
-    if (entry == NULL)
-        return EINVAL;
 
     /*
      * Check to see if the principal exists
@@ -643,6 +645,8 @@ kadm5_modify_principal(void *server_handle,
 
     krb5_clear_error_message(handle->context);
 
+    if(entry == NULL)
+        return EINVAL;
     if((mask & KADM5_PRINCIPAL) || (mask & KADM5_LAST_PWD_CHANGE) ||
        (mask & KADM5_MOD_TIME) || (mask & KADM5_MOD_NAME) ||
        (mask & KADM5_MKVNO) || (mask & KADM5_AUX_ATTRIBUTES) ||
@@ -651,10 +655,10 @@ kadm5_modify_principal(void *server_handle,
         return KADM5_BAD_MASK;
     if((mask & ~ALL_PRINC_MASK))
         return KADM5_BAD_MASK;
+    if((mask & KADM5_POLICY) && entry->policy == NULL)
+        return KADM5_BAD_MASK;
     if((mask & KADM5_POLICY) && (mask & KADM5_POLICY_CLR))
         return KADM5_BAD_MASK;
-    if(entry == (kadm5_principal_ent_t) NULL)
-        return EINVAL;
     if (mask & KADM5_TL_DATA) {
         tl_data_orig = entry->tl_data;
         while (tl_data_orig) {
-- 
2.7.0

++++++ baselibs.conf ++++++
krb5
  obsoletes "heimdal-lib-<targettype>"
  provides  "heimdal-lib-<targettype>"
krb5-devel
++++++ bnc#897874-CVE-2014-5351.diff ++++++
diff --git a/src/lib/kadm5/srv/svr_principal.c 
b/src/lib/kadm5/srv/svr_principal.c
index 5d358bd..d4e74cc 100644
--- a/src/lib/kadm5/srv/svr_principal.c
+++ b/src/lib/kadm5/srv/svr_principal.c
@@ -344,6 +344,20 @@ check_1_6_dummy(kadm5_principal_ent_t entry, long mask,
     *passptr = NULL;
 }
 
+/* Return the number of keys with the newest kvno.  Assumes that all key data
+ * with the newest kvno are at the front of the key data array. */
+static int
+count_new_keys(int n_key_data, krb5_key_data *key_data)
+{
+    int n;
+
+    for (n = 1; n < n_key_data; n++) {
+        if (key_data[n - 1].key_data_kvno != key_data[n].key_data_kvno)
+            return n;
+    }
+    return n_key_data;
+}
+
 kadm5_ret_t
 kadm5_create_principal(void *server_handle,
                        kadm5_principal_ent_t entry, long mask,
@@ -1593,7 +1607,7 @@ kadm5_randkey_principal_3(void *server_handle,
     osa_princ_ent_rec           adb;
     krb5_int32                  now;
     kadm5_policy_ent_rec        pol;
-    int                         ret, last_pwd;
+    int                         ret, last_pwd, n_new_keys;
     krb5_boolean                have_pol = FALSE;
     kadm5_server_handle_t       handle = server_handle;
     krb5_keyblock               *act_mkey;
@@ -1686,8 +1700,9 @@ kadm5_randkey_principal_3(void *server_handle,
     kdb->fail_auth_count = 0;
 
     if (keyblocks) {
-        ret = decrypt_key_data(handle->context,
-                               kdb->n_key_data, kdb->key_data,
+        /* Return only the new keys added by krb5_dbe_crk. */
+        n_new_keys = count_new_keys(kdb->n_key_data, kdb->key_data);
+        ret = decrypt_key_data(handle->context, n_new_keys, kdb->key_data,
                                keyblocks, n_keys);
         if (ret)
             goto done;
-- 
1.8.5.2

++++++ bnc#912002.diff ++++++
diff --git a/src/kadmin/server/kadm_rpc_svc.c
b/src/kadmin/server/kadm_rpc_svc.c
index 3837931..f4d2a7c 100644
--- a/src/kadmin/server/kadm_rpc_svc.c
+++ b/src/kadmin/server/kadm_rpc_svc.c
@@ -4,7 +4,7 @@
  *
  */

-#include <k5-platform.h>
+#include <k5-int.h>
 #include <gssrpc/rpc.h>
 #include <gssapi/gssapi_krb5.h> /* for gss_nt_krb5_name */
 #include <syslog.h>
@@ -296,14 +296,8 @@ check_rpcsec_auth(struct svc_req *rqstp)
      c1 = krb5_princ_component(kctx, princ, 0);
      c2 = krb5_princ_component(kctx, princ, 1);
      realm = krb5_princ_realm(kctx, princ);
-     if (strncmp(handle->params.realm, realm->data, realm->length) == 0
-        && strncmp("kadmin", c1->data, c1->length) == 0) {
-
-         if (strncmp("history", c2->data, c2->length) == 0)
-              goto fail_princ;
-         else
-              success = 1;
-     }
+     success = data_eq_string(*realm, handle->params.realm) &&
+            data_eq_string(*c1, "kadmin") && !data_eq_string(*c2, "history");

 fail_princ:
      if (!success) {
diff --git a/src/lib/gssapi/krb5/context_time.c
b/src/lib/gssapi/krb5/context_time.c
index b3d1db0..a18cfb0 100644
--- a/src/lib/gssapi/krb5/context_time.c
+++ b/src/lib/gssapi/krb5/context_time.c
@@ -40,7 +40,7 @@ krb5_gss_context_time(minor_status, context_handle, time_rec)

     ctx = (krb5_gss_ctx_id_rec *) context_handle;

-    if (! ctx->established) {
+    if (ctx->terminated || !ctx->established) {
         *minor_status = KG_CTX_INCOMPLETE;
         return(GSS_S_NO_CONTEXT);
     }
diff --git a/src/lib/gssapi/krb5/export_sec_context.c
b/src/lib/gssapi/krb5/export_sec_context.c
index 18a3a34..1b3de68 100644
--- a/src/lib/gssapi/krb5/export_sec_context.c
+++ b/src/lib/gssapi/krb5/export_sec_context.c
@@ -45,6 +45,11 @@ krb5_gss_export_sec_context(minor_status, context_handle, 
interprocess_token)
     *minor_status = 0;

     ctx = (krb5_gss_ctx_id_t) *context_handle;
+    if (ctx->terminated) {
+        *minor_status = KG_CTX_INCOMPLETE;
+        return (GSS_S_NO_CONTEXT);
+    }
+
     context = ctx->k5_context;
     kret = krb5_gss_ser_init(context);
     if (kret)
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h
b/src/lib/gssapi/krb5/gssapiP_krb5.h
index 7e807cc..a0e8625 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -206,6 +206,7 @@ typedef struct _krb5_gss_ctx_id_rec {
     unsigned int established : 1;
     unsigned int have_acceptor_subkey : 1;
     unsigned int seed_init : 1;  /* XXX tested but never actually set */
+    unsigned int terminated : 1;
     OM_uint32 gss_flags;
     unsigned char seed[16];
     krb5_gss_name_t here;
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c
b/src/lib/gssapi/krb5/gssapi_krb5.c
index 6456b23..77b7fff 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.c
+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
@@ -369,7 +369,7 @@ krb5_gss_inquire_sec_context_by_oid (OM_uint32 
*minor_status,

     ctx = (krb5_gss_ctx_id_rec *) context_handle;

-    if (!ctx->established)
+    if (ctx->terminated || !ctx->established)
         return GSS_S_NO_CONTEXT;

     for (i = 0; i < sizeof(krb5_gss_inquire_sec_context_by_oid_ops)/
diff --git a/src/lib/gssapi/krb5/inq_context.c
b/src/lib/gssapi/krb5/inq_context.c
index eacb0fd..096df2a 100644
--- a/src/lib/gssapi/krb5/inq_context.c
+++ b/src/lib/gssapi/krb5/inq_context.c
@@ -105,7 +105,7 @@ krb5_gss_inquire_context(minor_status, context_handle, 
initiator_name,

     ctx = (krb5_gss_ctx_id_rec *) context_handle;

-    if (! ctx->established) {
+    if (ctx->terminated || !ctx->established) {
         *minor_status = KG_CTX_INCOMPLETE;
         return(GSS_S_NO_CONTEXT);
     }
diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c
index 7665cba..f1c74dd 100644
--- a/src/lib/gssapi/krb5/k5seal.c
+++ b/src/lib/gssapi/krb5/k5seal.c
@@ -342,7 +342,7 @@ kg_seal(minor_status, context_handle, conf_req_flag, 
qop_req,

     ctx = (krb5_gss_ctx_id_rec *) context_handle;

-    if (! ctx->established) {
+    if (ctx->terminated || !ctx->established) {
         *minor_status = KG_CTX_INCOMPLETE;
         return(GSS_S_NO_CONTEXT);
     }
diff --git a/src/lib/gssapi/krb5/k5sealiov.c
b/src/lib/gssapi/krb5/k5sealiov.c
index a129670..b53e348 100644
--- a/src/lib/gssapi/krb5/k5sealiov.c
+++ b/src/lib/gssapi/krb5/k5sealiov.c
@@ -281,7 +281,7 @@ kg_seal_iov(OM_uint32 *minor_status,
     }

     ctx = (krb5_gss_ctx_id_rec *)context_handle;
-    if (!ctx->established) {
+    if (ctx->terminated || !ctx->established) {
         *minor_status = KG_CTX_INCOMPLETE;
         return GSS_S_NO_CONTEXT;
     }
diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
index 0573958..673c883 100644
--- a/src/lib/gssapi/krb5/k5unseal.c
+++ b/src/lib/gssapi/krb5/k5unseal.c
@@ -492,7 +492,7 @@ kg_unseal(minor_status, context_handle, input_token_buffer,

     ctx = (krb5_gss_ctx_id_rec *) context_handle;

-    if (! ctx->established) {
+    if (ctx->terminated || !ctx->established) {
         *minor_status = KG_CTX_INCOMPLETE;
         return(GSS_S_NO_CONTEXT);
     }
diff --git a/src/lib/gssapi/krb5/k5unsealiov.c
b/src/lib/gssapi/krb5/k5unsealiov.c
index f34d802..8b67042 100644
--- a/src/lib/gssapi/krb5/k5unsealiov.c
+++ b/src/lib/gssapi/krb5/k5unsealiov.c
@@ -625,7 +625,7 @@ kg_unseal_iov(OM_uint32 *minor_status,
     OM_uint32 code;

     ctx = (krb5_gss_ctx_id_rec *)context_handle;
-    if (!ctx->established) {
+    if (ctx->terminated || !ctx->established) {
         *minor_status = KG_CTX_INCOMPLETE;
         return GSS_S_NO_CONTEXT;
     }
diff --git a/src/lib/gssapi/krb5/prf.c b/src/lib/gssapi/krb5/prf.c
index e19291f..e897074 100644
--- a/src/lib/gssapi/krb5/prf.c
+++ b/src/lib/gssapi/krb5/prf.c
@@ -58,6 +58,10 @@ krb5_gss_pseudo_random(OM_uint32 *minor_status,
     ns.data = NULL;

     ctx = (krb5_gss_ctx_id_t)context;
+    if (ctx->terminated || !ctx->established) {
+        *minor_status = KG_CTX_INCOMPLETE;
+        return GSS_S_NO_CONTEXT;
+    }

     switch (prf_key) {
     case GSS_C_PRF_KEY_FULL:
diff --git a/src/lib/gssapi/krb5/process_context_token.c
b/src/lib/gssapi/krb5/process_context_token.c
index ae33180..a672f48 100644
--- a/src/lib/gssapi/krb5/process_context_token.c
+++ b/src/lib/gssapi/krb5/process_context_token.c
@@ -39,11 +39,18 @@ krb5_gss_process_context_token(minor_status, context_handle,

     ctx = (krb5_gss_ctx_id_t) context_handle;

-    if (! ctx->established) {
+    if (ctx->terminated || !ctx->established) {
         *minor_status = KG_CTX_INCOMPLETE;
         return(GSS_S_NO_CONTEXT);
     }

+    /* We only support context deletion tokens for now, and RFC 4121 does not
+     * define a context deletion token. */
+    if (ctx->proto) {
+        *minor_status = 0;
+        return(GSS_S_DEFECTIVE_TOKEN);
+    }
+
     /* "unseal" the token */

     if (GSS_ERROR(majerr = kg_unseal(minor_status, context_handle,
@@ -52,8 +59,8 @@ krb5_gss_process_context_token(minor_status, context_handle,
                                      KG_TOK_DEL_CTX)))
         return(majerr);

-    /* that's it.  delete the context */
-
-    return(krb5_gss_delete_sec_context(minor_status, &context_handle,
-                                       GSS_C_NO_BUFFER));
+    /* Mark the context as terminated, but do not delete it (as that would
+     * leave the caller with a dangling context handle). */
+    ctx->terminated = 1;
+    return(GSS_S_COMPLETE);
 }
diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c
b/src/lib/gssapi/krb5/wrap_size_limit.c
index 7bc4221..ed5c599 100644
--- a/src/lib/gssapi/krb5/wrap_size_limit.c
+++ b/src/lib/gssapi/krb5/wrap_size_limit.c
@@ -95,7 +95,7 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, 
conf_req_flag,
     }

     ctx = (krb5_gss_ctx_id_rec *) context_handle;
-    if (! ctx->established) {
+    if (ctx->terminated || !ctx->established) {
         *minor_status = KG_CTX_INCOMPLETE;
         return(GSS_S_NO_CONTEXT);
     }
diff --git a/src/lib/gssapi/mechglue/mglueP.h
b/src/lib/gssapi/mechglue/mglueP.h
index e56b9c1..2b5145e 100644
--- a/src/lib/gssapi/mechglue/mglueP.h
+++ b/src/lib/gssapi/mechglue/mglueP.h
@@ -25,7 +25,6 @@ do {                                                          
\
  */
 typedef struct gss_union_ctx_id_struct {
        struct gss_union_ctx_id_struct *loopback;
-       struct gss_union_ctx_id_struct *interposer;
        gss_OID                 mech_type;
        gss_ctx_id_t            internal_ctx_id;
 } gss_union_ctx_id_desc, *gss_union_ctx_id_t;
diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c
index 42ac783..975f94c 100644
--- a/src/lib/kadm5/kadm_rpc_xdr.c
+++ b/src/lib/kadm5/kadm_rpc_xdr.c
@@ -320,6 +320,7 @@ bool_t xdr_krb5_tl_data(XDR *xdrs, krb5_tl_data 
**tl_data_head)
               free(tl);
               tl = tl2;
          }
+         *tl_data_head = NULL;
          break;

      case XDR_ENCODE:
@@ -1096,6 +1097,7 @@ xdr_krb5_principal(XDR *xdrs, krb5_principal *objp)
     case XDR_FREE:
        if(*objp != NULL)
            krb5_free_principal(context, *objp);
+       *objp = NULL;
        break;
     }
     return TRUE;
diff --git a/src/lib/rpc/auth_gssapi_misc.c b/src/lib/rpc/auth_gssapi_misc.c
index 53bdb98..a05ea19 100644
--- a/src/lib/rpc/auth_gssapi_misc.c
+++ b/src/lib/rpc/auth_gssapi_misc.c
@@ -322,7 +322,6 @@ bool_t auth_gssapi_unwrap_data(
      if (! (*xdr_func)(&temp_xdrs, xdr_ptr)) {
          PRINTF(("gssapi_unwrap_data: deserializing arguments failed\n"));
          gss_release_buffer(minor, &out_buf);
-         xdr_free(xdr_func, xdr_ptr);
          XDR_DESTROY(&temp_xdrs);
          return FALSE;
      }
diff --git a/src/lib/rpc/svc_auth_gss.c b/src/lib/rpc/svc_auth_gss.c
index 09a3534..b81c4a3 100644
--- a/src/lib/rpc/svc_auth_gss.c
+++ b/src/lib/rpc/svc_auth_gss.c
@@ -65,16 +65,6 @@ extern const gss_OID_desc * const gss_mech_spkm3;

 extern SVCAUTH svc_auth_none;

-/*
- * from mit-krb5-1.2.1 mechglue/mglueP.h:
- * Array of context IDs typed by mechanism OID
- */
-typedef struct gss_union_ctx_id_t {
-  gss_OID     mech_type;
-  gss_ctx_id_t    internal_ctx_id;
-} gss_union_ctx_id_desc, *gss_union_ctx_id_t;
-
-
 static auth_gssapi_log_badauth_func log_badauth = NULL;
 static caddr_t log_badauth_data = NULL;
 static auth_gssapi_log_badauth2_func log_badauth2 = NULL;
@@ -239,16 +229,8 @@ svcauth_gss_accept_sec_context(struct svc_req *rqst,
                gd->ctx = GSS_C_NO_CONTEXT;
                goto errout;
        }
-       /*
-        * ANDROS: krb5 mechglue returns ctx of size 8 - two pointers,
-        * one to the mechanism oid, one to the internal_ctx_id
-        */
-       if ((gr->gr_ctx.value = mem_alloc(sizeof(gss_union_ctx_id_desc))) == 
NULL) {
-               fprintf(stderr, "svcauth_gss_accept_context: out of memory\n");
-               goto errout;
-       }
-       memcpy(gr->gr_ctx.value, gd->ctx, sizeof(gss_union_ctx_id_desc));
-       gr->gr_ctx.length = sizeof(gss_union_ctx_id_desc);
+       gr->gr_ctx.value = "xxxx";
+       gr->gr_ctx.length = 4;

        /* gr->gr_win = 0x00000005; ANDROS: for debugging linux kernel 
version...  */
        gr->gr_win = sizeof(gd->seqmask) * 8;
@@ -520,8 +502,6 @@ gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg 
*msg,

                if (!svcauth_gss_nextverf(rqst, htonl(gr.gr_win))) {
                        gss_release_buffer(&min_stat, &gr.gr_token);
-                       mem_free(gr.gr_ctx.value,
-                                sizeof(gss_union_ctx_id_desc));
                        ret_freegc (AUTH_FAILED);
                }
                *no_dispatch = TRUE;
@@ -531,7 +511,6 @@ gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg 
*msg,

                gss_release_buffer(&min_stat, &gr.gr_token);
                gss_release_buffer(&min_stat, &gd->checksum);
-               mem_free(gr.gr_ctx.value, sizeof(gss_union_ctx_id_desc));
                if (!call_stat)
                        ret_freegc (AUTH_FAILED);

--- krb5-1.12.1/src/lib/gssapi/krb5/lucid_context.c.orig        2015-01-07 
11:30:04.873975606 +0100
+++ krb5-1.12.1/src/lib/gssapi/krb5/lucid_context.c     2015-01-07 
12:59:59.957371445 +0100
@@ -75,6 +75,11 @@
     *minor_status = 0;
     *data_set = GSS_C_NO_BUFFER_SET;
 
+    if (ctx->terminated || !ctx->established) {
+        *minor_status = KG_CTX_INCOMPLETE;
+        return GSS_S_NO_CONTEXT;
+    }
+
     retval = generic_gss_oid_decompose(minor_status,
                                        GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID,
                                        
GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH,
++++++ krb5-1.10-kpasswd_tcp.patch ++++++
Fall back to TCP on kdc-unresolvable/unreachable errors.  We still have
to wait for UDP to fail, so this might not be ideal.  RT #5868.

Index: krb5-1.10.2/src/lib/krb5/os/changepw.c
===================================================================
--- krb5-1.10.2.orig/src/lib/krb5/os/changepw.c
+++ krb5-1.10.2/src/lib/krb5/os/changepw.c
@@ -274,10 +274,22 @@ change_set_password(krb5_context context
                          &callback_info, &chpw_rep, ss2sa(&remote_addr),
                          &addrlen, NULL, NULL, NULL);
         if (code) {
-            /*
-             * Here we may want to switch to TCP on some errors.
-             * right?
-             */
+            /* if we're not using a stream socket, and it's an error which
+             * might reasonably be specific to a datagram "connection", try
+             * again with a stream socket */
+            if (!use_tcp) {
+                switch (code) {
+                case KRB5_KDC_UNREACH:
+                case KRB5_REALM_CANT_RESOLVE:
+                case KRB5KRB_ERR_RESPONSE_TOO_BIG:
+                /* should we do this for more result codes than these? */
+                    k5_free_serverlist (&sl);
+                    use_tcp = 1;
+                    continue;
+                default:
+                    break;
+                }
+            }
             break;
         }
 
++++++ krb5-1.10-ksu-access.patch ++++++
The idea is to not complain about problems in the default ticket file if we
couldn't read it, because the client would be able to tell if it's there or
not, and we're implicitly letting the client tell us where it is.  Still needs
work, I think.

Index: krb5-1.11.1/src/clients/ksu/ccache.c
===================================================================
--- krb5-1.11.1.orig/src/clients/ksu/ccache.c
+++ krb5-1.11.1/src/clients/ksu/ccache.c
@@ -77,7 +77,7 @@ krb5_error_code krb5_ccache_copy (contex
     cc_def_name = krb5_cc_get_name(context, cc_def);
     cc_other_name = krb5_cc_get_name(context, *cc_other);
 
-    if ( ! stat(cc_def_name, &st_temp)){
+    if ( ! access(cc_def_name, R_OK) && ! stat(cc_def_name, &st_temp)){
         if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){
             return retval;
         }
Index: krb5-1.11.1/src/clients/ksu/heuristic.c
===================================================================
--- krb5-1.11.1.orig/src/clients/ksu/heuristic.c
+++ krb5-1.11.1/src/clients/ksu/heuristic.c
@@ -409,7 +409,7 @@ krb5_error_code find_either_ticket (cont
 
     cc_source_name = krb5_cc_get_name(context, cc);
 
-    if ( ! stat(cc_source_name, &st_temp)){
+    if ( ! access(cc_source_name, F_OK | R_OK) && ! stat(cc_source_name, 
&st_temp)){
 
         retval = find_ticket(context, cc, client, end_server, &temp_found);
         if (retval)
@@ -569,7 +569,7 @@ krb5_error_code get_best_princ_for_targe
     cc_source_name = krb5_cc_get_name(context, cc_source);
 
 
-    if (! stat(cc_source_name, &st_temp)) {
+    if (! access(cc_source_name, F_OK | R_OK) && ! stat(cc_source_name, 
&st_temp)) {
         retval = krb5_cc_get_principal(context, cc_source, &cc_def_princ);
         if (retval)
             return retval;
Index: krb5-1.11.1/src/clients/ksu/main.c
===================================================================
--- krb5-1.11.1.orig/src/clients/ksu/main.c
+++ krb5-1.11.1/src/clients/ksu/main.c
@@ -271,7 +271,7 @@ main (argc, argv)
                 if ( strchr(cc_source_tag, ':')){
                     cc_source_tag_tmp = strchr(cc_source_tag, ':') + 1;
 
-                    if( stat( cc_source_tag_tmp, &st_temp)){
+                    if( access( cc_source_tag_tmp, F_OK | R_OK) || stat( 
cc_source_tag_tmp, &st_temp)){
                         com_err(prog_name, errno,
                                 _("while looking for credentials file %s"),
                                 cc_source_tag_tmp);
++++++ krb5-1.12-api.patch ++++++
Reference docs don't define what happens if you call krb5_realm_compare() with
malformed krb5_principal structures.  Define a behavior which keeps it from
crashing if applications don't check ahead of time.

--- krb5/src/lib/krb5/krb/princ_comp.c
+++ krb5/src/lib/krb5/krb/princ_comp.c
@@ -41,6 +41,10 @@ realm_compare_flags(krb5_context context
     const krb5_data *realm1 = &princ1->realm;
     const krb5_data *realm2 = &princ2->realm;
 
+    if (princ1 == NULL || princ2 == NULL)
+        return FALSE;
+    if (realm1 == NULL || realm2 == NULL)
+        return FALSE;
     if (realm1->length != realm2->length)
         return FALSE;
     if (realm1->length == 0)
@@ -92,6 +98,9 @@ krb5_principal_compare_flags(krb5_contex
     krb5_principal upn2 = NULL;
     krb5_boolean ret = FALSE;
 
+    if (princ1 == NULL || princ2 == NULL)
+        return FALSE;
+
     if (flags & KRB5_PRINCIPAL_COMPARE_ENTERPRISE) {
         /* Treat UPNs as if they were real principals */
         if (princ1->type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
++++++ krb5-1.12-buildconf.patch ++++++
Build binaries in this package as RELRO PIEs, libraries as partial RELRO,
and install shared libraries with the execute bit set on them.  Prune out
the -L/usr/lib* and PIE flags where they might leak out and affect
apps which just want to link with the libraries. FIXME: needs to check and
not just assume that the compiler supports using these flags.

--- krb5/src/config/shlib.conf
+++ krb5/src/config/shlib.conf
@@ -419,7 +419,7 @@ mips-*-netbsd*)
        SHLIBEXT=.so
        # Linux ld doesn't default to stuffing the SONAME field...
        # Use objdump -x to examine the fields of the library
-       LDCOMBINE='$(CC) -shared -fPIC 
-Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT),--no-undefined'
+       LDCOMBINE='$(CC) -shared -fPIC 
-Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT),--no-undefined -Wl,-z,relro'
        # 
        LDCOMBINE_TAIL='-Wl,--version-script binutils.versions && $(PERL) -w 
$(top_srcdir)/util/export-check.pl $(SHLIB_EXPORT_FILE) $@'
        SHLIB_EXPORT_FILE_DEP=binutils.versions
@@ -430,7 +430,8 @@
        SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)'
        PROFFLAGS=-pg
        PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)'
-       CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) 
$(LDFLAGS)'
+       CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) 
-pie -Wl,-z,relro -Wl,-z,now $(LDFLAGS)'
+       INSTALL_SHLIB='${INSTALL} -m755'
        CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)'
        CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) 
$(LDFLAGS)'
        CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)'
--- krb5/src/build-tools/krb5-config.in
+++ krb5/src/build-tools/krb5-config.in
@@ -189,6 +189,13 @@ if test -n "$do_libs"; then
            -e 's#\$(PTHREAD_CFLAGS)#'"$PTHREAD_CFLAGS"'#' \
            -e 's#\$(CFLAGS)##'`
 
+    if test `dirname $libdir` = /usr ; then
+        lib_flags=`echo $lib_flags | sed -e "s#-L$libdir##" -e 
"s#$RPATH_FLAG$libdir##"`
+    fi
+    lib_flags=`echo $lib_flags | sed -e "s#-fPIE##g" -e "s#-pie##g"`
+    lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,relro##g"`
+    lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,now##g"`
+
     if test $library = 'kdb'; then
        lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB"
        library=krb5
--- krb5/src/config/pre.in
+++ krb5/src/config/pre.in
@@ -188,7 +188,7 @@
 INSTALL_SCRIPT=@INSTALL_PROGRAM@
 INSTALL_DATA=@INSTALL_DATA@
 INSTALL_SHLIB=@INSTALL_SHLIB@
-INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root
+INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755
 ## This is needed because autoconf will sometimes define @exec_prefix@ to be
 ## ${prefix}.
 prefix=@prefix@
++++++ krb5-1.12-doxygen.patch ++++++
commit b7a4d695263f1a5b7fe72b1eadce4acdc3f0490b
From: Ben Kaduk <[email protected]>
Date:   Thu Aug 28 17:54:39 2014 -0400
Subject: Map .hin files to the C language for doxygen
Upstream: Committed
References: 
https://github.com/krb5/krb5/commit/b7a4d695263f1a5b7fe72b1eadce4acdc3f0490b 
https://github.com/krb5/krb5/pull/198
    
Doxygen 1.8.8 is unhappy with the generated Doxyfile, and does not
handle krb5.hin in the expected fashion (as a C header). Work
around this issue by explicitly specifying that files with the
 .hin extension are to be treated as C language files.

Fixes the following build failure with doxygen 1.8.8:

[  326s] cp rst_apiref/*.rst rst_composite/appdev/refs/api
[  326s] cp: cannot stat 'rst_apiref/*.rst': No such file or directory
[  326s] Makefile:692: recipe for target 'composite' failed
[  326s] make: *** [composite] Error 1

diff --git a/src/doc/Doxyfile.in b/src/doc/Doxyfile.in
index 2082b6d..c225864 100644
--- a/src/doc/Doxyfile.in
+++ b/src/doc/Doxyfile.in
@@ -4,6 +4,7 @@ JAVADOC_AUTOBRIEF      = YES
 OPTIMIZE_OUTPUT_FOR_C  = YES
 WARN_IF_UNDOCUMENTED   = NO
 SHOW_FILES             = NO
+EXTENSION_MAPPING      = hin=C
 INPUT                  = @SRC@/include/krb5/krb5.hin @DOC@/doxy_examples
 EXAMPLE_PATH           = @DOC@/doxy_examples
 GENERATE_HTML          = NO
lines 1-28/28 (END)
++++++ krb5-1.12-ksu-path.patch ++++++
Set the default PATH to the one set by login.

--- krb5/src/clients/ksu/Makefile.in
+++ krb5/src/clients/ksu/Makefile.in
@@ -1,6 +1,6 @@
 mydir=clients$(S)ksu
 BUILDTOP=$(REL)..$(S)..
-DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin 
/local/bin"'
+DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin 
/usr/local/bin /sbin /bin /usr/sbin /usr/bin"'
 
 KSU_LIBS=@KSU_LIBS@
 PAM_LIBS=@PAM_LIBS@
++++++ krb5-1.12-pam.patch ++++++
++++ 752 lines (skipped)

++++++ krb5-1.12-selinux-label.patch ++++++
++++ 979 lines (skipped)

++++++ krb5-1.12.2-CVE-2014-5353.patch ++++++
>From d1f707024f1d0af6e54a18885322d70fa15ec4d3 Mon Sep 17 00:00:00 2001
From: Greg Hudson <[email protected]>
Date: Fri, 5 Dec 2014 14:01:39 -0500
Subject: [PATCH] Fix LDAP misused policy name crash [CVE-2014-5353]

In krb5_ldap_get_password_policy_from_dn, if LDAP_SEARCH returns
successfully with no results, return KRB5_KDB_NOENTRY instead of
returning success with a zeroed-out policy object.  This fixes a null
dereference when an admin attempts to use an LDAP ticket policy name
as a password policy name.

CVE-2014-5353:

In MIT krb5, when kadmind is configured to use LDAP for the KDC
database, an authenticated remote attacker can cause a NULL dereference
by attempting to use a named ticket policy object as a password policy
for a principal.  The attacker needs to be authenticated as a user who
has the elevated privilege for setting password policy by adding or
modifying principals.

Queries to LDAP scoped to the krbPwdPolicy object class will correctly
not return entries of other classes, such as ticket policy objects, but
may return success with no returned elements if an object with the
requested DN exists in a different object class.  In this case, the
routine to retrieve a password policy returned success with a password
policy object that consisted entirely of zeroed memory.  In particular,
accesses to the policy name will dereference a NULL pointer.  KDC
operation does not access the policy name field, but most kadmin
operations involving the principal with incorrect password policy
will trigger the crash.

Thanks to Patrik Kis for reporting this problem.

CVSSv2 Vector: AV:N/AC:M/Au:S/C:N/I:N/A:C/E:H/RL:OF/RC:C

[[email protected]: CVE description and CVSS score]

ticket: 8051 (new)
target_version: 1.13.1
tags: pullup
---
 src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c 
b/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c
index 522773e..6779f51 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c
@@ -314,10 +314,11 @@ krb5_ldap_get_password_policy_from_dn(krb5_context 
context, char *pol_name,
     LDAP_SEARCH(pol_dn, LDAP_SCOPE_BASE, "(objectclass=krbPwdPolicy)", 
password_policy_attributes);
 
     ent=ldap_first_entry(ld, result);
-    if (ent != NULL) {
-        if ((st = populate_policy(context, ld, ent, pol_name, *policy)) != 0)
-            goto cleanup;
+    if (ent == NULL) {
+        st = KRB5_KDB_NOENTRY;
+        goto cleanup;
     }
+    st = populate_policy(context, ld, ent, pol_name, *policy);
 
 cleanup:
     ldap_msgfree(result);
++++++ krb5-1.12.2-CVE-2014-5354.patch ++++++
>From 04038bf3633c4b909b5ded3072dc88c8c419bf16 Mon Sep 17 00:00:00 2001
From: Ben Kaduk <[email protected]>
Date: Wed, 19 Nov 2014 12:04:46 -0500
Subject: [PATCH] Support keyless principals in LDAP [CVE-2014-5354]

Operations like "kadmin -q 'addprinc -nokey foo'" or
"kadmin -q 'purgekeys -all foo'" result in principal entries with
no keys present, so krb5_encode_krbsecretkey() would just return
NULL, which then got unconditionally dereferenced in
krb5_add_ber_mem_ldap_mod().

Apply some fixes to krb5_encode_krbsecretkey() to handle zero-key
principals better, correct the test for an allocation failure, and
slightly restructure the cleanup handler to be shorter and more
appropriate for the usage.  Once it no longer short-circuits when
n_key_data is zero, it will produce an array of length two with both
entries NULL, which is treated as an empty list by the LDAP library,
the correct behavior for a keyless principal.

However, attributes with empty values are only handled by the LDAP
library for Modify operations, not Add operations (which only get
a sequence of Attribute, with no operation field).  Therefore, only
add an empty krbprincipalkey to the modlist when we will be performing a
Modify, and not when we will be performing an Add, which is conditional
on the (misspelled) create_standalone_prinicipal boolean.

CVE-2014-5354:

In MIT krb5, when kadmind is configured to use LDAP for the KDC
database, an authenticated remote attacker can cause a NULL
dereference by inserting into the database a principal entry which
contains no long-term keys.

In order for the LDAP KDC backend to translate a principal entry
from the database abstraction layer into the form expected by the
LDAP schema, the principal's keys are encoded into a
NULL-terminated array of length-value entries to be stored in the
LDAP database.  However, the subroutine which produced this array
did not correctly handle the case where no keys were present,
returning NULL instead of an empty array, and the array was
unconditionally dereferenced while adding to the list of LDAP
operations to perform.

Versions of MIT krb5 prior to 1.12 did not expose a way for
principal entries to have no long-term key material, and
therefore are not vulnerable.

    CVSSv2 Vector: AV:N/AC:M/Au:S/C:N/I:N/A:P/E:H/RL:OF/RC:C

ticket: 8041 (new)
tags: pullup
target_version: 1.13.1
subject: kadmind with ldap backend crashes when putting keyless entries
---
 src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c | 25 +++++++++++++++-------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c 
b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
index 3e560d9..10b5982 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
@@ -406,14 +406,14 @@ krb5_encode_krbsecretkey(krb5_key_data *key_data_in, int 
n_key_data,
     int num_versions = 1;
     int i, j, last;
     krb5_error_code err = 0;
-    krb5_key_data *key_data;
+    krb5_key_data *key_data = NULL;
 
-    if (n_key_data <= 0)
+    if (n_key_data < 0)
         return NULL;
 
     /* Make a shallow copy of the key data so we can alter it. */
     key_data = k5calloc(n_key_data, sizeof(*key_data), &err);
-    if (key_data_in == NULL)
+    if (key_data == NULL)
         goto cleanup;
     memcpy(key_data, key_data_in, n_key_data * sizeof(*key_data));
 
@@ -467,9 +467,8 @@ krb5_encode_krbsecretkey(krb5_key_data *key_data_in, int 
n_key_data,
     free(key_data);
     if (err != 0) {
         if (ret != NULL) {
-            for (i = 0; i <= num_versions; i++)
-                if (ret[i] != NULL)
-                    free (ret[i]);
+            for (i = 0; ret[i] != NULL; i++)
+                free (ret[i]);
             free (ret);
             ret = NULL;
         }
@@ -1036,9 +1035,19 @@ krb5_ldap_put_principal(krb5_context context, 
krb5_db_entry *entry,
         bersecretkey = krb5_encode_krbsecretkey (entry->key_data,
                                                  entry->n_key_data, mkvno);
 
-        if ((st=krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey",
-                                          LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, 
bersecretkey)) != 0)
+        if (bersecretkey == NULL) {
+            st = ENOMEM;
             goto cleanup;
+        }
+        /* An empty list of bervals is only accepted for modify operations,
+         * not add operations. */
+        if (bersecretkey[0] != NULL || !create_standalone_prinicipal) {
+            st = krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey",
+                                           LDAP_MOD_REPLACE | LDAP_MOD_BVALUES,
+                                           bersecretkey);
+            if (st != 0)
+                goto cleanup;
+        }
 
         if (!(entry->mask & KADM5_PRINCIPAL)) {
             memset(strval, 0, sizeof(strval));
++++++ krb5-1.13-work-around-replay-cache-creation-race.patch ++++++
>From 99e08376c14240e2141c6fa9289fafab8245c754 Mon Sep 17 00:00:00 2001
From: Greg Hudson <[email protected]>
Date: Wed, 17 Sep 2014 10:45:28 -0400
Subject: [PATCH] Work around replay cache creation race

If two processes try to initialize the same replay cache at the same
time, krb5_rc_io_creat can race between unlink and open, leading to a
KRB5_RC_IO_PERM error.  When this happens, make the losing process
retry so that it can continue.

This does not solve the replay cache creation race, nor is that the
only replay cache race issue.  It simply prevents the race from
causing a spurious failure.

(cherry picked from commit c61e8c0c6ad5fda8d23dd896c4aed0ac5b470020)

ticket: 3498
version_fixed: 1.13
status: resolved
---
 src/lib/krb5/rcache/rc_io.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/lib/krb5/rcache/rc_io.c b/src/lib/krb5/rcache/rc_io.c
index 7e3b7e9..b9859fe 100644
--- a/src/lib/krb5/rcache/rc_io.c
+++ b/src/lib/krb5/rcache/rc_io.c
@@ -158,7 +158,7 @@ krb5_rc_io_creat(krb5_context context, krb5_rc_iostuff *d, 
char **fn)
 {
     krb5_int16 rc_vno = htons(KRB5_RC_VNO);
     krb5_error_code retval = 0;
-    int do_not_unlink = 0;
+    int flags, do_not_unlink = 0;
     char *dir;
     size_t dirlen;
 
@@ -166,9 +166,13 @@ krb5_rc_io_creat(krb5_context context, krb5_rc_iostuff *d, 
char **fn)
     if (fn && *fn) {
         if (asprintf(&d->fn, "%s%s%s", dir, PATH_SEPARATOR, *fn) < 0)
             return KRB5_RC_IO_MALLOC;
-        unlink(d->fn);
-        d->fd = THREEPARAMOPEN(d->fn, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL |
-                               O_BINARY, 0600);
+        d->fd = -1;
+        do {
+            if (unlink(d->fn) == -1 && errno != ENOENT)
+                break;
+            flags = O_WRONLY | O_CREAT | O_TRUNC | O_EXCL | O_BINARY;
+            d->fd = THREEPARAMOPEN(d->fn, flags, 0600);
+        } while (d->fd == -1 && errno == EEXIST);
     } else {
         retval = krb5_rc_io_mkstemp(context, d, dir);
         if (retval)
-- 
1.8.4.5

++++++ krb5-1.6.3-gssapi_improve_errormessages.dif ++++++
Index: krb5-1.10.2/src/lib/gssapi/generic/disp_com_err_status.c
===================================================================
--- krb5-1.10.2.orig/src/lib/gssapi/generic/disp_com_err_status.c
+++ krb5-1.10.2/src/lib/gssapi/generic/disp_com_err_status.c
@@ -52,7 +52,7 @@ g_display_com_err_status(OM_uint32 *mino
     status_string->value = NULL;
 
     if (! g_make_string_buffer(((status_value == 0)?no_error:
-                                error_message(status_value)),
+                                error_message((long)status_value)),
                                status_string)) {
         *minor_status = ENOMEM;
         return(GSS_S_FAILURE);
++++++ krb5-1.6.3-ktutil-manpage.dif ++++++
---
 src/man/ktutil.man |   12 ++++++++++++
 1 file changed, 12 insertions(+)

Index: krb5-1.12.2/src/man/ktutil.man
===================================================================
--- krb5-1.12.2.orig/src/man/ktutil.man 2014-08-30 23:06:53.000000000 +0100
+++ krb5-1.12.2/src/man/ktutil.man      2014-08-30 23:07:00.000000000 +0100
@@ -162,6 +162,18 @@ ktutil:
 .UNINDENT
 .UNINDENT
 .UNINDENT
+.SH REMARKS
+Changes to the keytab are appended to the keytab file (i.e., the keytab file
+is never overwritten).  To directly modify a keytab, save the changes to a 
+temporary file and then overwrite the keytab file of interest.
+.TP
+.nf
+Example:
+ktutil> rkt /etc/krb5.keytab
+(modifications to keytab)
+ktutil> wkt /tmp/krb5.newtab
+ktutil> q
+# mv /tmp/krb5.newtab /etc/krb5.keytab
 .SH SEE ALSO
 .sp
 \fIkadmin(1)\fP, \fIkdb5_util(8)\fP
++++++ krb5-1.7-doublelog.patch ++++++
Don't double-log (actually, don't process /etc/krb5.conf twice) just
because we built with --sysconfdir=/etc.  RT#3277

---
 src/include/Makefile.in |    2 ++
 1 file changed, 2 insertions(+)

Index: krb5-1.12.2/src/include/Makefile.in
===================================================================
--- krb5-1.12.2.orig/src/include/Makefile.in    2014-08-30 23:08:41.000000000 
+0100
+++ krb5-1.12.2/src/include/Makefile.in 2014-08-30 23:09:04.000000000 +0100
@@ -68,6 +68,8 @@ PROCESS_REPLACE = -e "s+@KRB5RCTMPDIR+$(
                  -e "s+@GSSMODULEDIR+$(GSS_MODULE_DIR)+" \
                  -e 's+@LOCALSTATEDIR+$(LOCALSTATEDIR)+' \
                  -e 's+@SYSCONFDIR+$(SYSCONFDIR)+' \
+                 -e 's+:/etc/krb5.conf:/etc/krb5.conf"+:/etc/krb5.conf"+' \
+                 -e 's+"/etc/krb5.conf:/etc/krb5.conf"+"/etc/krb5.conf"+' \
                  -e 's+@DYNOBJEXT+$(DYNOBJEXT)+' \
                  -e 's+@SYSCONFCONF+$(SYSCONFCONF)+'
 
++++++ krb5-1.9-debuginfo.patch ++++++
We want to keep these y.tab.c files around because the debuginfo points to
them.  It would be more elegant at the end to use symbolic links, but that
could mess up people working in the tree on other things.

Index: src/kadmin/cli/Makefile.in
===================================================================
--- src/kadmin/cli/Makefile.in.orig
+++ src/kadmin/cli/Makefile.in
@@ -43,3 +43,8 @@ clean-unix::
 # CC_LINK is not meant for compilation and this use may break in the future.
 datetest: getdate.c
        $(CC_LINK) $(ALL_CFLAGS) -DTEST -o datetest getdate.c
+
+%.c: %.y
+       $(RM) y.tab.c $@
+       $(YACC.y) $< 
+       $(CP) y.tab.c $@
Index: src/plugins/kdb/ldap/ldap_util/Makefile.in
===================================================================
--- src/plugins/kdb/ldap/ldap_util/Makefile.in.orig
+++ src/plugins/kdb/ldap/ldap_util/Makefile.in
@@ -22,7 +22,7 @@ $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KR
 getdate.c: $(GETDATE)
        $(RM) getdate.c y.tab.c
        $(YACC) $(GETDATE)
-       $(MV) y.tab.c getdate.c
+       $(CP) y.tab.c getdate.c
 
 install::
        $(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG)
++++++ krb5-1.9-kprop-mktemp.patch ++++++
Use an in-memory ccache to silence a compiler warning, for RT#6414.

Index: krb5-1.11/src/slave/kprop.c
===================================================================
--- krb5-1.11.orig/src/slave/kprop.c
+++ krb5-1.11/src/slave/kprop.c
@@ -202,9 +202,8 @@ void PRS(argc, argv)
 void get_tickets(context)
     krb5_context context;
 {
-    char   buf[BUFSIZ], *def_realm;
+    char buf[] = "MEMORY:_kproptkt", *def_realm;
     krb5_error_code retval;
-    static char tkstring[] = "/tmp/kproptktXXXXXX";
     krb5_keytab keytab = NULL;
 
     /*
@@ -229,11 +228,8 @@ void get_tickets(context)
 #endif
 
     /*
-     * Initialize cache file which we're going to be using
+     * Initialize an in-memory cache for temporary use
      */
-    (void) mktemp(tkstring);
-    snprintf(buf, sizeof(buf), "FILE:%s", tkstring);
-
     retval = krb5_cc_resolve(context, buf, &ccache);
     if (retval) {
         com_err(progname, retval, _("while opening credential cache %s"), buf);
++++++ krb5-1.9-manpaths.dif ++++++
Change the absolute paths included in the man pages so that the correct
values can be dropped in by config.status.  After applying this patch,
these files should be renamed to their ".in" counterparts, and then the
configure scripts should be rebuilt.  Originally RT#6525

Index: krb5-1.11/src/man/kpropd.man
===================================================================
--- krb5-1.11.orig/src/man/kpropd.man
+++ krb5-1.11/src/man/kpropd.man
@@ -63,7 +63,7 @@ the \fB/etc/inetd.conf\fP file which loo
 .sp
 .nf
 .ft C
-kprop  stream  tcp  nowait  root  /usr/local/sbin/kpropd  kpropd
+kprop  stream  tcp  nowait  root  @SBINDIR@/kpropd  kpropd
 .ft P
 .fi
 .UNINDENT
++++++ krb5-kvno-230379.patch ++++++
>From patch attached to http://krbdev.mit.edu/rt/Ticket/Display.html?id=3349,
at http://krbdev.mit.edu/rt/Ticket/Attachment/23851/13214/kvno.diff, adjusted
as needed to apply to 1.10.  FIXME: I'd like to better handle cases where we
have a new key with the right version stored later in the keytab file.
Currently, we're setting up to overlook that possibility.

Note that this only affects the path taken when krb5_rd_rep() is passed a
server principal name, as without a server principal name it already tries
all of the keys it finds in the keytab, regardless of version numbers.

Index: krb5-1.11.1/src/kadmin/ktutil/ktutil.c
===================================================================
--- krb5-1.11.1.orig/src/kadmin/ktutil/ktutil.c
+++ krb5-1.11.1/src/kadmin/ktutil/ktutil.c
@@ -155,7 +155,7 @@ void ktutil_add_entry(argc, argv)
     char *princ = NULL;
     char *enctype = NULL;
     krb5_kvno kvno = 0;
-    int use_pass = 0, use_key = 0, i;
+    int use_pass = 0, use_key = 0, use_kvno = 0, i;
 
     for (i = 1; i < argc; i++) {
         if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) {
@@ -164,6 +164,7 @@ void ktutil_add_entry(argc, argv)
         }
         if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) {
             kvno = (krb5_kvno) atoi(argv[++i]);
+            use_kvno++;
             continue;
         }
         if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) {
@@ -180,7 +181,7 @@ void ktutil_add_entry(argc, argv)
         }
     }
 
-    if (argc != 8 || !(princ && kvno && enctype) || (use_pass+use_key != 1)) {
+    if (argc != 8 || !(princ && use_kvno && enctype) || (use_pass+use_key != 
1)) {
         fprintf(stderr, _("usage: %s (-key | -password) -p principal "
                           "-k kvno -e enctype\n"), argv[0]);
         return;
Index: krb5-1.11.1/src/lib/krb5/keytab/kt_file.c
===================================================================
--- krb5-1.11.1.orig/src/lib/krb5/keytab/kt_file.c
+++ krb5-1.11.1/src/lib/krb5/keytab/kt_file.c
@@ -349,7 +349,7 @@ krb5_ktfile_get_entry(krb5_context conte
                higher than that.  Short-term workaround: only compare
                the low 8 bits.  */
 
-            if (new_entry.vno == (kvno & 0xff)) {
+            if (new_entry.vno == (kvno & 0xff) || new_entry.vno == IGNORE_VNO) 
{
                 krb5_kt_free_entry(context, &cur_entry);
                 cur_entry = new_entry;
                 break;
++++++ krb5-rpmlintrc ++++++
addFilter("devel-file-in-non-devel-package .*libgssapi_krb5.so")
addFilter("hidden-file-or-dir .*/usr/share/man/man5/.k5login.5.gz")
addFilter("files-duplicate .*css")
addFilter("files-duplicate .*img.*png")
addFilter("devel-file-in-non-devel-package .*libkdb_ldap.so")
addFilter("shlib-policy-missing-suffix")
++++++ pre_checkin.sh ++++++
#!/bin/sh
sed -e 's/Name:.*/Name:           krb5-mini/g;' \
    -e 's/spec file for package.*/&-mini/' \
    -e 's/%define.*build_mini.*/%define build_mini 1/g' krb5.spec > 
krb5-mini.spec
cp krb5.changes krb5-mini.changes


Reply via email to