[Bug 267987] kadmind's kadm5_ret_key_data() can leave pointers uninitialized, causing crash

From: <bugzilla-noreply_at_freebsd.org>
Date: Fri, 25 Nov 2022 12:12:31 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=267987

            Bug ID: 267987
           Summary: kadmind's kadm5_ret_key_data() can leave pointers
                    uninitialized, causing crash
           Product: Base System
           Version: CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: bin
          Assignee: bugs@FreeBSD.org
          Reporter: rtm@lcs.mit.edu
 Attachment #238335 text/plain
         mime type:

Created attachment 238335
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=238335&action=edit
cause kadmind's kadm5_ret_key_data() to yield an uninitialized pointer

For a client kadm_chpass_with_key request, kadmind_dispatch() calls
kadm5_ret_key_data() to fill key_data[] elements. kadm5_ret_key_data()
ignores any errors it may encounter:

kadm5_ret_t
kadm5_ret_key_data(krb5_storage *sp,
                   krb5_key_data *key)
{
    krb5_data c;
    int32_t tmp;
    krb5_ret_int32(sp, &tmp);
    key->key_data_ver = tmp;
    krb5_ret_int32(sp, &tmp);
    key->key_data_kvno = tmp;
    krb5_ret_int32(sp, &tmp);
    key->key_data_type[0] = tmp;
    krb5_ret_data(sp, &c);
    key->key_data_length[0] = c.length;
    key->key_data_contents[0] = c.data;
    krb5_ret_int32(sp, &tmp);
    key->key_data_type[1] = tmp;
    krb5_ret_data(sp, &c);
    key->key_data_length[1] = c.length;
    key->key_data_contents[1] = c.data;
    return 0;
}

In particular, if krb5_ret_data() encounters the end of a too-short
client message, it leaves c.data with its uninitialized value, and
thus kadm5_ret_key_data() can set an element of the caller's
key_data[] with invalid pointer contents, without returning an error.

Later, if kadmind_dispatch() calls kadm5_free_key_data() due
to some error (e.g. client message too short), the latter
ends up trying to free() invalid pointers.

I've attached a demo; it expects the user to have run kinit.

# valgrind /usr/libexec/kadmind --debug &
# cc kadmind17a.c -lkrb5
# ./a.out
2022-11-25T06:50:53 root@EXAMPLE.ORG: CHPASS_WITH_KEY @
==11284== Invalid free() / delete / delete[] / realloc()
==11284==    at 0x484E83C: free (in
/usr/local/libexec/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==11284==    by 0x48631BB: kadm5_free_key_data (in /usr/lib/libkadm5srv.so.11)
==11284==    by 0x112569: ??? (in /usr/libexec/kadmind)
==11284==    by 0x1129A8: ??? (in /usr/libexec/kadmind)
==11284==    by 0x10D1DC: ??? (in /usr/libexec/kadmind)
==11284==    by 0x4823007: ???
==11284==  Address 0x5b77340 is 0 bytes after a block of size 0 free'd
==11284==    at 0x484E83C: free (in
/usr/local/libexec/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==11284==    by 0x48631AE: kadm5_free_key_data (in /usr/lib/libkadm5srv.so.11)
==11284==    by 0x112569: ??? (in /usr/libexec/kadmind)
==11284==    by 0x1129A8: ??? (in /usr/libexec/kadmind)
==11284==    by 0x10D1DC: ??? (in /usr/libexec/kadmind)
==11284==    by 0x4823007: ???
==11284==  Block was alloc'd at
==11284==    at 0x484CBC4: malloc (in
/usr/local/libexec/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==11284==    by 0x48E1B74: krb5_data_alloc (in /usr/lib/libkrb5.so.11)
==11284==    by 0x490B231: krb5_ret_data (in /usr/lib/libkrb5.so.11)
==11284==    by 0x4865C6D: kadm5_ret_key_data (in /usr/lib/libkadm5srv.so.11)
==11284==    by 0x1123D7: ??? (in /usr/libexec/kadmind)
==11284==    by 0x1129A8: ??? (in /usr/libexec/kadmind)
==11284==    by 0x10D1DC: ??? (in /usr/libexec/kadmind)
==11284==    by 0x4823007: ???

-- 
You are receiving this mail because:
You are the assignee for the bug.