Bug #6376
segmentation fault when sharing with 'sec=none,root=*' options
100%
Description
Problem
# share -o 'sec=none,root=*' /tmp Bad root list Segmentation Fault (core dumped) # mdb core Loading modules: [ libumem.so.1 libc.so.1 libuutil.so.1 libtopo.so.1 libavl.so.1 libnvpair.so.1 ld.so.1 ] > ::stack libshare_nfs.so.1`cleanup_export+0x57(80473e0, fed50018, fee648ab, fed6847e) libshare_nfs.so.1`nfs_enable_share+0x68f(80d96a0, 8083028, 8047478, fedb8000) libshare.so.1`sa_proto_share+0x24(805d6d5, 80d96a0, fea40018, 8051c75, 0, 80531a0) libshare.so.1`sa_enable_share+0xa3(80d96a0, 805d6d5, 805d6d5, feadcca7, feb14d20, 80bdca0) sa_legacy_share+0x5f3(8081f98, 3, 4, 8047e30) run_command+0x4c(8047eec, 4, 8047e30, 0, 8081f98, 805d68b) main+0x104(8047dec, fef646a8, 8047e24, 8053c43, 4, 8047e30) _start+0x83(4, 8047eec, 8047ef2, 8047ef5, 8047f05, 0) >
Root Cause
The libshare_nfs cores in cleanup_export() because s_rootcnt is greater than zero, but s_rootnames is NULL here:
1060 while (s->s_rootcnt > 0) 1061 free(s->s_rootnames[--s->s_rootcnt]);
The cleanup_export() is called from nfs_enable_share() where the exportdata structure is initialized. In general, the s_rootnames should point to an allocated array of s_rootcnt allocated strings. The nfs_enable_share() initialize/allocate both s_rootcnt and s_rootnames via fill_security_from_secopts() and get_rootnames().
1172 sp->s_rootnames = get_rootnames(&sp->s_secinfo, 1173 value, &sp->s_rootcnt);
The get_rootnames() should return a pointer to allocated root names. The number of allocated root names is returned in the 3rd output parameter (s_rootcnt).
The problem is that there are some possible cases when on failure the get_rootnames() returns NULL, but leave some non-zero value in the 3rd output parameter:
1091 *count = c; 1092 1093 a = (caddr_t *)malloc(c * sizeof (char *)); 1094 if (a == NULL) { 1095 (void) printf(dgettext(TEXT_DOMAIN, 1096 "get_rootnames: no memory\n")); 1097 } else { 1098 for (i = 0; i < c; i++) { 1099 host = strtok(list, ":"); 1100 if (!nfs_get_root_principal(sec, host, &a[i])) { 1101 while (i > 0) 1102 free(a[--i]); 1103 free(a); 1104 a = NULL; 1105 break; 1106 } 1107 list = NULL; 1108 } 1109 } 1110 1111 return (a);
There are two such cases: One is when malloc() at line 1093 fails, the next one is around line 1100 when the nfs_get_root_principal() call fails. In both cases NULL is returned, but *count is left with some non-zero value.
Fix
The fix just make sure that get_rootnames() consistently returns zero in 3rd parameter in a case the return value is NULL.
Updated by Electric Monk over 5 years ago
- Status changed from Pending RTI to Closed
- % Done changed from 0 to 100
git commit 07b64d17ebeb1cc3f2777494d108511275630d14
commit 07b64d17ebeb1cc3f2777494d108511275630d14 Author: Marcel Telka <marcel.telka@nexenta.com> Date: 2015-10-28T22:28:34.000Z 6376 segmentation fault when sharing with 'sec=none,root=*' options Reviewed by: Gordon Ross <gordon.ross@nexenta.com> Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com> Reviewed by: Toomas Soome <tsoome@me.com> Approved by: Robert Mustacchi <rm@joyent.com>