krb5-admin/1140: Patch for reproducible kadmind crash
mrl@isc.upenn.edu
mrl at isc.upenn.edu
Thu Jul 25 16:27:42 EDT 2002
>Number: 1140
>Category: krb5-admin
>Synopsis: kadmind dumps core when it receives bad data from client
>Confidential: yes
>Severity: serious
>Priority: high
>Responsible: krb5-unassigned
>State: open
>Class: sw-bug
>Submitter-Id: unknown
>Arrival-Date: Thu Jul 25 16:28:00 EDT 2002
>Last-Modified:
>Originator: Mark R. Levinson
>Organization:
University of Pennsylvania
>Release: krb5-1.2.5
>Environment:
System: SunOS gnaghi.isc-net.upenn.edu 5.8 Generic_108528-12 sun4u sparc SUNW,Ultra-5_10
Architecture: sun4
>Description:
Bad data in client requests can reliably cause kadmind to crash in
krb5_unparse_name_ext(), where it tries to dereference a NULL pointer.
The patch below prevents these crashes by checking for a NULL principal
argument in krb5_unparse_name_ext(), and checking the return values from
several calls to krb5_unparse_name() in kadmin/server/server_stubs.c.
Notes on the patch:
- I've reproduced this crash only in create_principal_1(), but the
patch also fixes the other calls to krb5_unparse_name() in
server_stubs.c that don't check its return value.
- I chose KADM5_BAD_PRINCIPAL as the error code to return from the
kadmin server functions when krb5_unparse_name() fails, although
doc/kadm5/api-funcspec.tex doesn't document this as an expected return
code for those functions.
- Currently any bad attempts that fail due to krb5_unparse_name() errors
aren't logged. It might be desirable to log them.
>How-To-Repeat:
I found this bug when someone made a mistake while experimenting with the
Authen::Krb5::Admin module for Perl, available from
http://www.cpan.org/modules/by-module/Authen/Authen-Krb5-Admin-0.03.tar.gz
I haven't developed C code to exercise the bug, but here's a minimal Perl
script that reliably crashes kadmind due to incorrect usage of the
Authen::Krb5::Admin module:
#!/usr/local/bin/perl
use Authen::Krb5;
Authen::Krb5::init_context();
Authen::Krb5::init_ets();
print "Principal: ";
chomp($principal = scalar(<STDIN>));
print "Password: ";
chomp($password = scalar(<STDIN>));
use Authen::Krb5::Admin;
$kadm5 = Authen::Krb5::Admin->init_with_password($principal, $password)
or die Authen::Krb5::Admin::error;
$x = Authen::Krb5::Admin::Principal::new('') or die Authen::Krb5::Admin::error;
$rc = $kadm5->create_principal($x, '') or die Authen::Krb5::Admin::error;
>Fix:
*** src/lib/krb5/krb/unparse.c Thu Jul 25 13:54:34 2002
--- src/lib/krb5/krb/unparse.c Thu Jul 25 09:41:34 2002
***************
*** 70,75 ****
--- 70,78 ----
krb5_int32 nelem;
register int totalsize = 0;
+ if (!principal)
+ return KRB5_PARSE_MALFORMED;
+
cp = krb5_princ_realm(context, principal)->data;
length = krb5_princ_realm(context, principal)->length;
totalsize += length;
*** src/kadmin/server/server_stubs.c Thu Jul 25 13:54:34 2002
--- src/kadmin/server/server_stubs.c Thu Jul 25 13:28:07 2002
***************
*** 257,263 ****
ret.code = KADM5_FAILURE;
return &ret;
}
! krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg);
if (CHANGEPW_SERVICE(rqstp)
|| !acl_check(handle->context, rqstp->rq_clntcred, ACL_ADD,
--- 257,266 ----
ret.code = KADM5_FAILURE;
return &ret;
}
! if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) {
! ret.code = KADM5_BAD_PRINCIPAL;
! return &ret;
! }
if (CHANGEPW_SERVICE(rqstp)
|| !acl_check(handle->context, rqstp->rq_clntcred, ACL_ADD,
***************
*** 311,317 ****
ret.code = KADM5_FAILURE;
return &ret;
}
! krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg);
if (CHANGEPW_SERVICE(rqstp)
|| !acl_check(handle->context, rqstp->rq_clntcred, ACL_ADD,
--- 314,323 ----
ret.code = KADM5_FAILURE;
return &ret;
}
! if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) {
! ret.code = KADM5_BAD_PRINCIPAL;
! return &ret;
! }
if (CHANGEPW_SERVICE(rqstp)
|| !acl_check(handle->context, rqstp->rq_clntcred, ACL_ADD,
***************
*** 367,373 ****
ret.code = KADM5_FAILURE;
return &ret;
}
! krb5_unparse_name(handle->context, arg->princ, &prime_arg);
if (CHANGEPW_SERVICE(rqstp)
|| !acl_check(handle->context, rqstp->rq_clntcred, ACL_DELETE,
--- 373,382 ----
ret.code = KADM5_FAILURE;
return &ret;
}
! if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
! ret.code = KADM5_BAD_PRINCIPAL;
! return &ret;
! }
if (CHANGEPW_SERVICE(rqstp)
|| !acl_check(handle->context, rqstp->rq_clntcred, ACL_DELETE,
***************
*** 415,421 ****
ret.code = KADM5_FAILURE;
return &ret;
}
! krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg);
if (CHANGEPW_SERVICE(rqstp)
|| !acl_check(handle->context, rqstp->rq_clntcred, ACL_MODIFY,
--- 424,433 ----
ret.code = KADM5_FAILURE;
return &ret;
}
! if (krb5_unparse_name(handle->context, arg->rec.principal, &prime_arg)) {
! ret.code = KADM5_BAD_PRINCIPAL;
! return &ret;
! }
if (CHANGEPW_SERVICE(rqstp)
|| !acl_check(handle->context, rqstp->rq_clntcred, ACL_MODIFY,
***************
*** 469,476 ****
ret.code = KADM5_FAILURE;
return &ret;
}
! krb5_unparse_name(handle->context, arg->src, &prime_arg1);
! krb5_unparse_name(handle->context, arg->dest, &prime_arg2);
sprintf(prime_arg, "%s to %s", prime_arg1, prime_arg2);
ret.code = KADM5_OK;
--- 481,491 ----
ret.code = KADM5_FAILURE;
return &ret;
}
! if (krb5_unparse_name(handle->context, arg->src, &prime_arg1) ||
! krb5_unparse_name(handle->context, arg->dest, &prime_arg2)) {
! ret.code = KADM5_BAD_PRINCIPAL;
! return &ret;
! }
sprintf(prime_arg, "%s to %s", prime_arg1, prime_arg2);
ret.code = KADM5_OK;
***************
*** 539,545 ****
ret.code = KADM5_FAILURE;
return &ret;
}
! krb5_unparse_name(handle->context, arg->princ, &prime_arg);
if (! cmp_gss_krb5_name(handle, rqstp->rq_clntcred, arg->princ) &&
(CHANGEPW_SERVICE(rqstp) || !acl_check(handle->context,
--- 554,563 ----
ret.code = KADM5_FAILURE;
return &ret;
}
! if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
! ret.code = KADM5_BAD_PRINCIPAL;
! return &ret;
! }
if (! cmp_gss_krb5_name(handle, rqstp->rq_clntcred, arg->princ) &&
(CHANGEPW_SERVICE(rqstp) || !acl_check(handle->context,
***************
*** 659,665 ****
ret.code = KADM5_FAILURE;
return &ret;
}
! krb5_unparse_name(handle->context, arg->princ, &prime_arg);
if (cmp_gss_krb5_name(handle, rqstp->rq_clntcred, arg->princ)) {
ret.code = chpass_principal_wrapper((void *)handle, arg->princ,
--- 677,686 ----
ret.code = KADM5_FAILURE;
return &ret;
}
! if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
! ret.code = KADM5_BAD_PRINCIPAL;
! return &ret;
! }
if (cmp_gss_krb5_name(handle, rqstp->rq_clntcred, arg->princ)) {
ret.code = chpass_principal_wrapper((void *)handle, arg->princ,
***************
*** 717,723 ****
ret.code = KADM5_FAILURE;
return &ret;
}
! krb5_unparse_name(handle->context, arg->princ, &prime_arg);
if (cmp_gss_krb5_name(handle, rqstp->rq_clntcred, arg->princ)) {
ret.code = chpass_principal_wrapper((void *)handle, arg->princ,
--- 738,747 ----
ret.code = KADM5_FAILURE;
return &ret;
}
! if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
! ret.code = KADM5_BAD_PRINCIPAL;
! return &ret;
! }
if (cmp_gss_krb5_name(handle, rqstp->rq_clntcred, arg->princ)) {
ret.code = chpass_principal_wrapper((void *)handle, arg->princ,
***************
*** 778,784 ****
ret.code = KADM5_FAILURE;
return &ret;
}
! krb5_unparse_name(handle->context, arg->princ, &prime_arg);
if (!(CHANGEPW_SERVICE(rqstp)) &&
acl_check(handle->context, rqstp->rq_clntcred,
--- 802,811 ----
ret.code = KADM5_FAILURE;
return &ret;
}
! if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
! ret.code = KADM5_BAD_PRINCIPAL;
! return &ret;
! }
if (!(CHANGEPW_SERVICE(rqstp)) &&
acl_check(handle->context, rqstp->rq_clntcred,
***************
*** 833,839 ****
ret.code = KADM5_FAILURE;
return &ret;
}
! krb5_unparse_name(handle->context, arg->princ, &prime_arg);
if (!(CHANGEPW_SERVICE(rqstp)) &&
acl_check(handle->context, rqstp->rq_clntcred,
--- 860,869 ----
ret.code = KADM5_FAILURE;
return &ret;
}
! if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
! ret.code = KADM5_BAD_PRINCIPAL;
! return &ret;
! }
if (!(CHANGEPW_SERVICE(rqstp)) &&
acl_check(handle->context, rqstp->rq_clntcred,
***************
*** 888,894 ****
ret.code = KADM5_FAILURE;
return &ret;
}
! krb5_unparse_name(handle->context, arg->princ, &prime_arg);
if (!(CHANGEPW_SERVICE(rqstp)) &&
acl_check(handle->context, rqstp->rq_clntcred,
--- 918,927 ----
ret.code = KADM5_FAILURE;
return &ret;
}
! if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
! ret.code = KADM5_BAD_PRINCIPAL;
! return &ret;
! }
if (!(CHANGEPW_SERVICE(rqstp)) &&
acl_check(handle->context, rqstp->rq_clntcred,
***************
*** 952,958 ****
free_server_handle(handle);
return &ret;
}
! krb5_unparse_name(handle->context, arg->princ, &prime_arg);
if (cmp_gss_krb5_name(handle, rqstp->rq_clntcred, arg->princ)) {
ret.code = randkey_principal_wrapper((void *)handle,
--- 985,994 ----
free_server_handle(handle);
return &ret;
}
! if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
! ret.code = KADM5_BAD_PRINCIPAL;
! return &ret;
! }
if (cmp_gss_krb5_name(handle, rqstp->rq_clntcred, arg->princ)) {
ret.code = randkey_principal_wrapper((void *)handle,
***************
*** 1025,1031 ****
free_server_handle(handle);
return &ret;
}
! krb5_unparse_name(handle->context, arg->princ, &prime_arg);
if (cmp_gss_krb5_name(handle, rqstp->rq_clntcred, arg->princ)) {
ret.code = randkey_principal_wrapper((void *)handle,
--- 1061,1070 ----
free_server_handle(handle);
return &ret;
}
! if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
! ret.code = KADM5_BAD_PRINCIPAL;
! return &ret;
! }
if (cmp_gss_krb5_name(handle, rqstp->rq_clntcred, arg->princ)) {
ret.code = randkey_principal_wrapper((void *)handle,
>Audit-Trail:
>Unformatted:
More information about the krb5-bugs
mailing list