Project

General

Profile

Bug #6376

segmentation fault when sharing with 'sec=none,root=*' options

Added by Marcel Telka about 4 years ago. Updated about 4 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
nfs - NFS server and client
Start date:
2015-10-22
Due date:
% Done:

100%

Estimated time:
Difficulty:
Bite-size
Tags:
needs-triage

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.

History

#1

Updated by Marcel Telka about 4 years ago

  • Status changed from In Progress to Pending RTI
#2

Updated by Electric Monk about 4 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>

Also available in: Atom PDF