Bug #13671
closedprofiles -l can crash in ldap backend
100%
Description
When invoking profiles -l
, the following sequence occurs in show_profs()
:
usr/src/cmd/profiles/profiles.c:147
if (print_flag & PRINT_LONG) { exec = getexecuser(username, KV_COMMAND, NULL, GET_ALL|__SEARCH_ALL_POLS); if (exec != NULL) { print_profs_long(exec); free_execattr(exec); } else { status = EXIT_NON_FATAL; }
Note that getexecuser()
is called with __SEARCH_ALL_POLS
set in search_flags
. In getexecuser()
in usr/src/lib/libsecdb/common/getexecattr.c:139, we have:
if (IS_GET_ONE(search_flag)) { head = userprof((const char *)(utmp->name), type, id, search_flag); } else if (IS_GET_ALL(search_flag)) { head = userprof((const char *)(utmp->name), type, id, search_flag); if (head != NULL) { prev = get_tail(head); }
So userprof()
is called with the value of search_flag. Following further, at usr/src/lib/libsecdb/common/getexecattr.c:276
result.head = result.prev = NULL; call.type = type; call.id = id; call.sflag = search_flag; (void) _enum_profs(username, findexecattr, &call, &result);
Skipping the _enum_profs()
code (it just loops and calls findexecattr
). In findexecattr()
, we see:
if ((exec = getexecprof(prof, c->type, c->id, c->sflag)) != NULL) {
In turn, in getexecprof()
, we have:
tmp = _getexecprof(name, type, id, search_flag, &exec, buf, NSS_BUFLEN_EXECATTR, &err);
Then in _getexecprof()
, we have:
retry_policy: _priv_exec.policy = IS_SEARCH_ALL(search_flag) ? NULL : policy_buf; _priv_exec.search_flag = search_flag; _priv_exec.head_exec = NULL; _priv_exec.prev_exec = NULL; arg.key.attrp = &(_priv_exec);
The key thing to note that when __SEARCH_ALL_POLS
is set by show_profs()
, this causes _priv_exec.policy
to be set to NULL.
In the ldap backend, in usr/src/lib/nsswitch/ldap/common/getexecattr.c:535
, we have
static nss_status_t getbynam(ldap_backend_ptr be, void *a) { char searchfilter[SEARCHFILTERLEN]; char userdata[SEARCHFILTERLEN]; char name[SEARCHFILTERLEN]; int ret; nss_status_t nss_stat; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); const char *policy = _priv_exec->policy; const char *type = _priv_exec->type; if (strpbrk(policy, "*()\\") != NULL || type != NULL && strpbrk(type, "*()\\") != NULL || _ldap_filter_name(name, _priv_exec->name, sizeof (name)) != 0) return ((nss_status_t)NSS_NOTFOUND);
And a crash will occur because policy
is NULL
.
At minimum, it would appear that policy != NULL && ...
should be prepended to the start of the if
expression.
Likely, the following snprinf()
calls may also need to use the ISWILD()
macro with policy
.
Updated by Jason King about 1 year ago
Without the fix, profiles -l
will segfault.
With the fix, it now displays the expected output (user and hostnames masked):
[yyy@xxx (zzz) /var/tmp]$ profiles -l yyy yyy: Primary Administrator * uid=0 gid=0 Basic Solaris User /usr/lib/fs/smbfs/mount privs=sys_mount /usr/lib/fs/smbfs/umount privs=sys_mount All * [yyy@xxx (zzz) /var/tmp]$ profiles -l aaa aaa: Network Management /sbin/dladm euid=dladm egid=netadm privs=sys_dl_config,net_rawaccess,proc_audit /sbin/dlstat euid=dladm egid=sys /sbin/flowadm euid=dladm egid=sys privs=sys_dl_config,net_rawaccess,proc_audit /sbin/flowstat euid=dladm egid=sys /sbin/ifconfig uid=0 /sbin/ipadm euid=netadm egid=netadm privs=sys_ip_config,net_rawaccess /sbin/route privs=sys_ip_config /sbin/routeadm euid=0 privs=proc_chroot,proc_owner,sys_ip_config /usr/sbin/snoop privs=net_observability /usr/bin/netstat uid=0 /usr/bin/rup euid=0 /usr/bin/ruptime euid=0 /usr/bin/setuname euid=0 /usr/sbin/asppp2pppd euid=0 /usr/sbin/ifconfig uid=0 /usr/sbin/ipaddrsel euid=0 /usr/sbin/ipqosconf euid=0 /usr/sbin/rndc privs=file_dac_read /usr/sbin/route uid=0 /usr/sbin/snoop uid=0 /usr/sbin/spray euid=0 Network Observability privs=net_observability /usr/sbin/snoop privs=net_observability Process Management /usr/bin/kill privs=proc_owner /usr/bin/nice privs=proc_owner,proc_priocntl /usr/bin/pcred privs=proc_owner /usr/bin/pfiles privs=proc_owner /usr/bin/pflags privs=proc_owner /usr/bin/ppriv privs=proc_owner /usr/bin/renice privs=proc_owner,proc_priocntl /usr/sbin/rcapadm uid=0 /usr/bin/crontab euid=0 /usr/bin/kill euid=0 /usr/bin/nice euid=0 /usr/bin/pcred euid=0 /usr/bin/pfiles euid=0 /usr/bin/pflags euid=0 /usr/bin/pldd euid=0 /usr/bin/pmap euid=0 /usr/bin/prun euid=0 /usr/bin/ps euid=0 /usr/bin/psig euid=0 /usr/bin/pstack euid=0 /usr/bin/pstop euid=0 /usr/bin/ptime euid=0 /usr/bin/ptree euid=0 /usr/bin/pwait euid=0 /usr/bin/pwdx euid=0 /usr/bin/renice euid=0 /usr/bin/truss euid=0 /usr/sbin/fuser euid=0 ZFS File System Management /sbin/zfs euid=0 Zone Management /usr/sbin/zlogin euid=0 /usr/sbin/zoneadm euid=0 Zone Security /usr/sbin/txzonemgr uid=0 /usr/sbin/zonecfg uid=0 Cron Management /usr/bin/crontab euid=0 File System Management /sbin/mount privs=sys_mount /sbin/umount privs=sys_mount /usr/sbin/iscsiadm euid=0 privs=basic /usr/sbin/mpathadm privs=sys_devices /usr/sbin/quotacheck uid=0 gid=sys /usr/sbin/quotaoff uid=0 gid=sys /usr/sbin/quotaon uid=0 gid=sys /usr/sbin/raidctl privs=sys_config,sys_devices euid=0 /usr/sbin/sasinfo privs=sys_devices /usr/sbin/sbdadm privs=sys_devices /usr/sbin/stmfadm privs=sys_devices /usr/bin/eject euid=0 /usr/bin/mkdir euid=0 /usr/bin/rmdir euid=0 /usr/lib/autofs/automountd euid=0 /usr/lib/fs/autofs/automount euid=0 /usr/lib/fs/nfs/showmount euid=0 /usr/lib/fs/ufs/fsirand euid=0 /usr/lib/fs/ufs/newfs euid=0 /usr/lib/fs/ufs/tunefs uid=0 /usr/sbin/clri euid=0 /usr/sbin/devinfo euid=0 /usr/sbin/dfmounts euid=0 /usr/sbin/dfshares euid=0 /usr/sbin/ff euid=0 /usr/sbin/format euid=0 /usr/sbin/fsck euid=0 /usr/sbin/fsdb euid=0 /usr/sbin/fstyp euid=0 /usr/sbin/fuser euid=0 /usr/sbin/mkfile euid=0 /usr/sbin/mkfs euid=0 /usr/sbin/mount uid=0 /usr/sbin/mountall uid=0 /usr/sbin/ramdiskadm euid=0 /usr/sbin/share uid=0 gid=root /usr/sbin/shareall uid=0 gid=root /usr/sbin/sharemgr uid=0 gid=root /usr/sbin/swap euid=0 /usr/sbin/umount uid=0 /usr/sbin/umountall uid=0 /usr/sbin/unshare uid=0 gid=root /usr/sbin/unshareall uid=0 gid=root Basic Solaris User /usr/lib/fs/smbfs/mount privs=sys_mount /usr/lib/fs/smbfs/umount privs=sys_mount All *
Updated by Electric Monk about 1 year ago
- Status changed from New to Closed
- % Done changed from 0 to 100
git commit a0570dbda2f64cada915185eb4e1b42c3b4bf755
commit a0570dbda2f64cada915185eb4e1b42c3b4bf755 Author: Jason King <jason.king@joyent.com> Date: 2021-03-28T21:51:08.000Z 13671 profiles -l can crash in ldap backend Reviewed by: Brian Bennett <brian.bennett@joyent.com> Reviewed by: Andy Fiddaman <andy@omniosce.org> Approved by: Robert Mustacchi <rm@fingolfin.org>