diff --git a/lib/libzfs/libzfs_changelist.c b/lib/libzfs/libzfs_changelist.c index eac06f8f5ab..b1a2e17cb7a 100644 --- a/lib/libzfs/libzfs_changelist.c +++ b/lib/libzfs/libzfs_changelist.c @@ -177,6 +177,7 @@ changelist_postfix(prop_changelist_t *clp) char shareopts[ZFS_MAXPROPLEN]; boolean_t commit_smb_shares = B_FALSE; boolean_t commit_nfs_shares = B_FALSE; + int rc = 0; /* * If CL_GATHER_DONT_UNMOUNT is set, it means we don't want to (un)mount @@ -266,7 +267,7 @@ changelist_postfix(prop_changelist_t *clp) const enum sa_protocol nfs[] = {SA_PROTOCOL_NFS, SA_NO_PROTOCOL}; if (sharenfs && mounted) { - zfs_share(cn->cn_handle, nfs); + rc = zfs_share(cn->cn_handle, nfs); commit_nfs_shares = B_TRUE; } else if (cn->cn_shared || clp->cl_waslegacy) { zfs_unshare(cn->cn_handle, NULL, nfs); @@ -275,7 +276,7 @@ changelist_postfix(prop_changelist_t *clp) const enum sa_protocol smb[] = {SA_PROTOCOL_SMB, SA_NO_PROTOCOL}; if (sharesmb && mounted) { - zfs_share(cn->cn_handle, smb); + rc = zfs_share(cn->cn_handle, smb); commit_smb_shares = B_TRUE; } else if (cn->cn_shared || clp->cl_waslegacy) { zfs_unshare(cn->cn_handle, NULL, smb); @@ -291,7 +292,15 @@ changelist_postfix(prop_changelist_t *clp) *p++ = SA_NO_PROTOCOL; zfs_commit_shares(proto); - return (0); + /* + * It's possible rc != 0 since we set a mountpoint or option while + * SMB/NFS was not running. This is fine, and we should not return + * an error up the stack. + * + * At this point we only want to report mountpoint/shareops parsing + * errors. + */ + return (rc == SA_SYNTAX_ERR ? rc : 0); } /* diff --git a/lib/libzfs/libzfs_share.c b/lib/libzfs/libzfs_share.c index bfac40f17de..98a09f7f331 100644 --- a/lib/libzfs/libzfs_share.c +++ b/lib/libzfs/libzfs_share.c @@ -64,6 +64,10 @@ sa_enable_share(const char *zfsname, const char *mountpoint, { VALIDATE_PROTOCOL(protocol, SA_INVALID_PROTOCOL); + int error = sa_validate_shareopts(shareopts, protocol); + if (error != SA_OK) + return (error); + const struct sa_share_impl args = init_share(zfsname, mountpoint, shareopts); return (fstypes[protocol]->enable_share(&args)); @@ -111,6 +115,10 @@ sa_validate_shareopts(const char *options, enum sa_protocol protocol) { VALIDATE_PROTOCOL(protocol, SA_INVALID_PROTOCOL); + /* error out on invalid characters */ + if (strpbrk(options, "\a\b\f\n\r") != NULL) + return (SA_SYNTAX_ERR); + return (fstypes[protocol]->validate_shareopts(options)); }