[Bug 281657] security/krb5

From: <bugzilla-noreply_at_freebsd.org>
Date: Mon, 23 Sep 2024 00:45:04 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=281657

            Bug ID: 281657
           Summary: security/krb5
           Product: Ports & Packages
           Version: Latest
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: Individual Port(s)
          Assignee: cy@FreeBSD.org
          Reporter: cyschow@shaw.ca
          Assignee: cy@FreeBSD.org
             Flags: maintainer-feedback?(cy@FreeBSD.org)

I am experiencing segmentation fault when logging in to my newly updated 13.4
FreeBSD machine. I am using pam_ldap and nss_ldap to lookup accounts on my LDAP
server. Here is the stack trace for the crash (account name replaced with
xxxxxxx):

# lldb `which tcsh` -c tcsh.core
(lldb) target create "/bin/tcsh" --core "tcsh.core"
Core file 'tcsh.core' (x86_64) was loaded.
(lldb) bt
* thread #1, name = 'tcsh', stop reason = signal SIGSEGV
  * frame #0: 0x000018b37c64018e libgssapi_krb5.so.2.2`loadConfigFiles at
g_initialize.c:504:39
    frame #1: 0x000018b37c63bf3d libgssapi_krb5.so.2.2`updateMechList at
g_initialize.c:532:2
    frame #2: 0x000018b37c63bb59 libgssapi_krb5.so.2.2`build_mechSet at
g_initialize.c:342:2
    frame #3: 0x000018b37c63bac8
libgssapi_krb5.so.2.2`gss_indicate_mechs(minorStatus=0x000018b37303e8ec,
mechSet_out=0x000018b37303e868) at g_initialize.c:292:6
    frame #4: 0x000018b37c6447cc
libgssapi_krb5.so.2.2`gss_indicate_mechs_by_attrs(minor=0x000018b37303e8ec,
desired_mech_attrs=0x000018b37303e8d8, except_mech_attrs=0x000018b37303e8c8,
critical_mech_attrs=0x0000000000000000, mechs=0x000018b3859d72c0) at
g_mechattr.c:112:14
    frame #5: 0x000018b3859d0bdb libgs2.so`___lldb_unnamed_symbol132 + 523
    frame #6: 0x000018b3859d0ddc libgs2.so`gs2_client_plug_init + 108
    frame #7: 0x000018b37c02ec1a libsasl2.so.3`sasl_client_add_plugin + 90
    frame #8: 0x000018b37c03bda5 libsasl2.so.3`_sasl_load_plugins + 981
    frame #9: 0x000018b37c02f050 libsasl2.so.3`sasl_client_init + 528
    frame #10: 0x000018b37af628fe libldap.so.2`ldap_int_sasl_init + 110
    frame #11: 0x000018b37af7871e libldap.so.2`ldap_int_initialize + 142
    frame #12: 0x000018b37af5c7d1 libldap.so.2`ldap_create + 49
    frame #13: 0x000018b37af5cc44 libldap.so.2`ldap_initialize + 52
    frame #14: 0x000018b3798a0530 nss_ldap.so.1`___lldb_unnamed_symbol440 +
1008
    frame #15: 0x000018b3798a16d8 nss_ldap.so.1`_nss_ldap_search_s + 88
    frame #16: 0x000018b3798a26b0 nss_ldap.so.1`_nss_ldap_getbyname + 192
    frame #17: 0x000018b3798a4243 nss_ldap.so.1`_nss_ldap_getpwnam_r + 67
    frame #18: 0x000018b3752244ef
libc.so.7`__nss_compat_getpwnam_r(retval=0x000018b373041510,
mdata=<unavailable>, ap=0x000018b3730413d0) at nss_compat.c:211:15
    frame #19: 0x000018b37522126d
libc.so.7`_nsdispatch(retval=0x000018b373041510, disp_tab=0x000018b375302700,
database="", method_name="", defaults=<unavailable>) at nsdispatch.c:727:14
    frame #20: 0x000018b3751dbf2c libc.so.7`getpwnam [inlined]
getpwnam_r(name="xxxxxxx", pwd=0x000018b375311648, buffer="root", bufsize=1024,
result=0x000018b373041510) at getpwent.c:575:7
    frame #21: 0x000018b3751dbee0 libc.so.7`getpwnam [inlined]
wrap_getpwnam_r(key=(name = "xxxxxxx", uid = 1977254368),
pwd=0x000018b375311648, buffer="root", bufsize=1024, res=0x000018b373041510) at
getpwent.c:666:10
    frame #22: 0x000018b3751dbee0 libc.so.7`getpwnam [inlined]
getpw(fn=<unavailable>, key=<unavailable>) at getpwent.c:642:8
    frame #23: 0x000018b3751dbe92 libc.so.7`getpwnam(name="xxxxxxx") at
getpwent.c:692:10
    frame #24: 0x000018ab523a607c tcsh`xgetpwnam(name="xxxxxxx") at
sh.misc.c:635:19
    frame #25: 0x000018ab523d1e0e tcsh`gettilde [inlined]
gethomedir(us=L"xxxxxxx") at tc.func.c:1471:10
    frame #26: 0x000018ab523d1e01 tcsh`gettilde(us=L"xxxxxxx") at
tc.func.c:1555:10
    frame #27: 0x000018ab5238d45e tcsh`gethdir(home=<unavailable>) at
sh.c:2364:14
    frame #28: 0x000018ab5239dded tcsh`globexpand [inlined] globtilde(s=L"") at
sh.glob.c:87:12
    frame #29: 0x000018ab5239dd86 tcsh`globexpand(v=<unavailable>, noglob=0) at
sh.glob.c:356:12
    frame #30: 0x000018ab5239d81e tcsh`globone(str=L"~xxxxxxx", action=0) at
sh.glob.c:496:7
    frame #31: 0x000018ab5238f212 tcsh`dfollow(cp=<unavailable>, old=0) at
sh.dir.c:587:30
    frame #32: 0x000018ab5238efe4 tcsh`dochngd(v=0x000018b375dc7ce8,
c=<unavailable>) at sh.dir.c:522:12
    frame #33: 0x000018ab523abd32 tcsh`execute(t=0x000018b375e2a380,
wanttty=1884, pipein=<unavailable>, pipeout=0x0000000000000000,
do_glob=<unavailable>) at sh.sem.c:653:7
    frame #34: 0x000018ab523ab1ad tcsh`execute(t=0x000018b375e2a350,
wanttty=1884, pipein=0x0000000000000000, pipeout=0x0000000000000000, do_glob=1)
at sh.sem.c:0:3
    frame #35: 0x000018ab5238cc5e tcsh`process(catch=1) at sh.c:2162:2
    frame #36: 0x000018ab5238baaf tcsh`main(argc=<unavailable>,
argv=0x000018b373042280) at sh.c:1430:5
    frame #37: 0x000018ab52389dbd tcsh`_start(ap=<unavailable>,
cleanup=<unavailable>) at crt1_c.c:71:7

Here is the line of code that is crashing:

(lldb) down
frame #0: 0x000018b37c64018e libgssapi_krb5.so.2.2`loadConfigFiles at
g_initialize.c:504:39
   501
   502          memset(&globbuf, 0, sizeof(globbuf));
   503          if (glob(MECH_CONF_PATTERN, 0, NULL, &globbuf) == 0) {
-> 504                  for (path = globbuf.gl_pathv; *path != NULL; path++)
   505                          load_if_changed(*path, g_confFileModTime,
&highest);
   506          }
   507          globfree(&globbuf);

(lldb) p globbuf
(glob_t) {
  gl_pathc = 0
  gl_matchc = 1099511627776
  gl_offs = 0
  gl_flags = 0
  gl_pathv = 0x0000000000000000
  gl_errfunc = 0x0000000000000000
  gl_closedir = 0x0000000000000000
  gl_readdir = 0x0000000000000000
  gl_opendir = 0x0000000000000000
  gl_lstat = 0x0000000000000000
  gl_stat = 0x0000000000000000
}

The issue boils down to this man page:

# man 3 glob
...
     gl_pathv      contains a pointer to a NULL-terminated list of matched
                   pathnames.  However, if gl_pathc is zero, the contents of
                   gl_pathv are undefined.
...

The code is unconditionally referencing gl_pathv without check if gl_pathc is
non-zero. Unfortunately, in this case, gl_pathv is NULL, and the dereference
causes the crash.

I checked the manpage in Linux, and from what I read, it makes no mention of
that fact. At this time, I am assuming this is a FreeBSD-specific issue.

I am attaching a patch to avoid this problem. I can confirm that it works on my
systems.

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