libbe(3): Impose dataset length restrictions on boot env name validation
Previously, we only validated names for character restrictions. This is helpful, but we should've also checked length restrictions- dataset names must be restricted to MAXNAMELEN. While here, move validation before doing a bunch of concatenations and fix error handling in be_rename. It was previously setting the error state based on return value from a libzfs function, which is wrong: libzfs errors don't necessarily match cleanly to libbe errors. This would cause the assertion in be_error to hit when the error was printed.
This commit is contained in:
parent
6d14f2c48f
commit
5b7803a993
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=337924
@ -486,7 +486,7 @@ be_create_from_existing(libbe_handle_t *lbh, const char *name, const char *old)
|
||||
int err;
|
||||
char buf[BE_MAXPATHLEN];
|
||||
|
||||
if ((err = be_snapshot(lbh, old, NULL, true, (char *)&buf)))
|
||||
if ((err = be_snapshot(lbh, old, NULL, true, (char *)&buf)) != 0)
|
||||
return (set_error(lbh, err));
|
||||
|
||||
err = be_create_from_existing_snap(lbh, name, (char *)buf);
|
||||
@ -577,11 +577,12 @@ be_root_concat(libbe_handle_t *lbh, const char *name, char *result)
|
||||
|
||||
/*
|
||||
* Verifies the validity of a boot environment name (A-Za-z0-9-_.). Returns
|
||||
* BE_ERR_SUCCESS (0) if name is valid, otherwise returns BE_ERR_INVALIDNAME.
|
||||
* BE_ERR_SUCCESS (0) if name is valid, otherwise returns BE_ERR_INVALIDNAME
|
||||
* or BE_ERR_PATHLEN.
|
||||
* Does not set internal library error state.
|
||||
*/
|
||||
int
|
||||
be_validate_name(libbe_handle_t *lbh __unused, const char *name)
|
||||
be_validate_name(libbe_handle_t *lbh, const char *name)
|
||||
{
|
||||
for (int i = 0; *name; i++) {
|
||||
char c = *(name++);
|
||||
@ -590,6 +591,12 @@ be_validate_name(libbe_handle_t *lbh __unused, const char *name)
|
||||
return (BE_ERR_INVALIDNAME);
|
||||
}
|
||||
|
||||
/*
|
||||
* Impose the additional restriction that the entire dataset name must
|
||||
* not exceed the maximum length of a dataset, i.e. MAXNAMELEN.
|
||||
*/
|
||||
if (strlen(lbh->root) + 1 + strlen(name) > MAXNAMELEN)
|
||||
return (BE_ERR_PATHLEN);
|
||||
return (BE_ERR_SUCCESS);
|
||||
}
|
||||
|
||||
@ -605,14 +612,17 @@ be_rename(libbe_handle_t *lbh, const char *old, const char *new)
|
||||
zfs_handle_t *zfs_hdl;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* be_validate_name is documented not to set error state, so we should
|
||||
* do so here.
|
||||
*/
|
||||
if ((err = be_validate_name(lbh, new)) != 0)
|
||||
return (set_error(lbh, err));
|
||||
if ((err = be_root_concat(lbh, old, full_old)) != 0)
|
||||
return (set_error(lbh, err));
|
||||
if ((err = be_root_concat(lbh, new, full_new)) != 0)
|
||||
return (set_error(lbh, err));
|
||||
|
||||
if ((err = be_validate_name(lbh, new)) != 0)
|
||||
return (err);
|
||||
|
||||
/* Check if old is active BE */
|
||||
if (strcmp(full_old, be_active_path(lbh)) == 0)
|
||||
return (set_error(lbh, BE_ERR_MOUNTED));
|
||||
@ -639,8 +649,9 @@ be_rename(libbe_handle_t *lbh, const char *old, const char *new)
|
||||
err = zfs_rename(zfs_hdl, NULL, full_new, flags);
|
||||
|
||||
zfs_close(zfs_hdl);
|
||||
|
||||
return (set_error(lbh, err));
|
||||
if (err != 0)
|
||||
return (set_error(lbh, BE_ERR_UNKNOWN));
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -331,7 +331,9 @@ environment name into
|
||||
.Pp
|
||||
The
|
||||
.Fn be_validate_name
|
||||
function will validate the given boot environment name.
|
||||
function will validate the given boot environment name for both length
|
||||
restrictions as well as valid character restrictions.
|
||||
This function does not set the internal library error state.
|
||||
.Pp
|
||||
The
|
||||
.Fn be_validate_snap
|
||||
|
Loading…
Reference in New Issue
Block a user