sharenfs: Check for invalid characters

Check for invalid characters in sharenfs/sharesmb dataset props.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #18613
This commit is contained in:
Tony Hutter
2026-06-02 16:34:51 -07:00
committed by GitHub
parent 80fb85b80b
commit 0aa4088dce
2 changed files with 20 additions and 3 deletions
+12 -3
View File
@@ -177,6 +177,7 @@ changelist_postfix(prop_changelist_t *clp)
char shareopts[ZFS_MAXPROPLEN]; char shareopts[ZFS_MAXPROPLEN];
boolean_t commit_smb_shares = B_FALSE; boolean_t commit_smb_shares = B_FALSE;
boolean_t commit_nfs_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 * 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[] = const enum sa_protocol nfs[] =
{SA_PROTOCOL_NFS, SA_NO_PROTOCOL}; {SA_PROTOCOL_NFS, SA_NO_PROTOCOL};
if (sharenfs && mounted) { if (sharenfs && mounted) {
zfs_share(cn->cn_handle, nfs); rc = zfs_share(cn->cn_handle, nfs);
commit_nfs_shares = B_TRUE; commit_nfs_shares = B_TRUE;
} else if (cn->cn_shared || clp->cl_waslegacy) { } else if (cn->cn_shared || clp->cl_waslegacy) {
zfs_unshare(cn->cn_handle, NULL, nfs); zfs_unshare(cn->cn_handle, NULL, nfs);
@@ -275,7 +276,7 @@ changelist_postfix(prop_changelist_t *clp)
const enum sa_protocol smb[] = const enum sa_protocol smb[] =
{SA_PROTOCOL_SMB, SA_NO_PROTOCOL}; {SA_PROTOCOL_SMB, SA_NO_PROTOCOL};
if (sharesmb && mounted) { if (sharesmb && mounted) {
zfs_share(cn->cn_handle, smb); rc = zfs_share(cn->cn_handle, smb);
commit_smb_shares = B_TRUE; commit_smb_shares = B_TRUE;
} else if (cn->cn_shared || clp->cl_waslegacy) { } else if (cn->cn_shared || clp->cl_waslegacy) {
zfs_unshare(cn->cn_handle, NULL, smb); zfs_unshare(cn->cn_handle, NULL, smb);
@@ -291,7 +292,15 @@ changelist_postfix(prop_changelist_t *clp)
*p++ = SA_NO_PROTOCOL; *p++ = SA_NO_PROTOCOL;
zfs_commit_shares(proto); 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);
} }
/* /*
+8
View File
@@ -64,6 +64,10 @@ sa_enable_share(const char *zfsname, const char *mountpoint,
{ {
VALIDATE_PROTOCOL(protocol, SA_INVALID_PROTOCOL); 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 = const struct sa_share_impl args =
init_share(zfsname, mountpoint, shareopts); init_share(zfsname, mountpoint, shareopts);
return (fstypes[protocol]->enable_share(&args)); 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); 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)); return (fstypes[protocol]->validate_shareopts(options));
} }