mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-25 18:59:33 +03:00
Fix memory corruption during parallel zpool import with -o cachefile (#16419)
When importing multiple pools, the nvlist of properties given with "-o" is shared amongst the several threads. So no thread should modify it. Previously, in the course of validating the cachefile property, the zpool_valid_proplist function would temporarily modify the value, and then change it back. Now it will operate on a clone of the value. Sponsored by: Axcient Fixes #16405 Signed-off-by: Alan Somers <asomers@gmail.com> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Allan Jude <allan@klarasystems.com> Reviewed-by: George Wilson <gwilson@delphix.com> Reviewed-by: Alexander Motin <mav@FreeBSD.org>
This commit is contained in:
parent
bd949b10be
commit
1f5bf91a85
@ -529,9 +529,10 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
|
|||||||
zpool_prop_t prop;
|
zpool_prop_t prop;
|
||||||
const char *strval;
|
const char *strval;
|
||||||
uint64_t intval;
|
uint64_t intval;
|
||||||
const char *slash, *check;
|
const char *check;
|
||||||
struct stat64 statbuf;
|
struct stat64 statbuf;
|
||||||
zpool_handle_t *zhp;
|
zpool_handle_t *zhp;
|
||||||
|
char *parent, *slash;
|
||||||
char report[1024];
|
char report[1024];
|
||||||
|
|
||||||
if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
|
if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
|
||||||
@ -785,30 +786,36 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
slash = strrchr(strval, '/');
|
parent = strdup(strval);
|
||||||
|
if (parent == NULL) {
|
||||||
|
(void) zfs_error(hdl, EZFS_NOMEM, errbuf);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
slash = strrchr(parent, '/');
|
||||||
|
|
||||||
if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
|
if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
|
||||||
strcmp(slash, "/..") == 0) {
|
strcmp(slash, "/..") == 0) {
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
"'%s' is not a valid file"), strval);
|
"'%s' is not a valid file"), parent);
|
||||||
(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
|
(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
|
||||||
|
free(parent);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(char *)slash = '\0';
|
*slash = '\0';
|
||||||
|
|
||||||
if (strval[0] != '\0' &&
|
if (parent[0] != '\0' &&
|
||||||
(stat64(strval, &statbuf) != 0 ||
|
(stat64(parent, &statbuf) != 0 ||
|
||||||
!S_ISDIR(statbuf.st_mode))) {
|
!S_ISDIR(statbuf.st_mode))) {
|
||||||
*(char *)slash = '/';
|
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
"'%s' is not a valid directory"),
|
"'%s' is not a valid directory"),
|
||||||
strval);
|
parent);
|
||||||
(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
|
(void) zfs_error(hdl, EZFS_BADPATH, errbuf);
|
||||||
|
free(parent);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
free(parent);
|
||||||
|
|
||||||
*(char *)slash = '/';
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZPOOL_PROP_COMPATIBILITY:
|
case ZPOOL_PROP_COMPATIBILITY:
|
||||||
|
Loading…
Reference in New Issue
Block a user