Hello community, here is the log from the commit of package krb5 for openSUSE:Factory checked in at 2016-02-12 11:20:54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/krb5 (Old) and /work/SRC/openSUSE:Factory/.krb5.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "krb5" Changes: -------- --- /work/SRC/openSUSE:Factory/krb5/krb5.changes 2016-01-13 22:44:01.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.krb5.new/krb5.changes 2016-02-12 11:20:58.000000000 +0100 @@ -1,0 +2,13 @@ +Tue Feb 2 08:41:13 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) + +------------------------------------------------------------------- New: ---- 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 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ krb5.spec ++++++ --- /var/tmp/diff_new_pack.lBxCDu/_old 2016-02-12 11:20:59.000000000 +0100 +++ /var/tmp/diff_new_pack.lBxCDu/_new 2016-02-12 11:20:59.000000000 +0100 @@ -86,6 +86,9 @@ Patch14: krbdev.mit.edu-8301.patch Patch15: krb5-fix_interposer.patch Patch16: krb5-mechglue_inqure_attrs.patch +Patch104: 0104-Verify-decoded-kadmin-C-strings-CVE-2015-8629.patch +Patch105: 0105-Fix-leaks-in-kadmin-server-stubs-CVE-2015-8631.patch +Patch106: 0106-Check-for-null-kadm5-policy-name-CVE-2015-8630.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build PreReq: mktemp, grep, /bin/touch, coreutils PreReq: %fillup_prereq @@ -206,6 +209,9 @@ %patch14 -p1 %patch15 -p1 %patch16 -p1 +%patch104 -p1 +%patch105 -p1 +%patch106 -p1 %build # needs to be re-generated ++++++ 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
