mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-23 02:44:41 +03:00
Forbid basename(3) and dirname(3)
There are at least two interpretations of basename(3), in addition to both functions being allowed to /both/ return a static buffer (unsuitable in multi-threaded environments) /and/ raze the input (which encourages overallocations, at best) Reviewed-by: John Kennedy <john.kennedy@delphix.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz> Closes #12105
This commit is contained in:
+27
-10
@@ -154,6 +154,17 @@ zutil_strdup(libpc_handle_t *hdl, const char *str)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static char *
|
||||
zutil_strndup(libpc_handle_t *hdl, const char *str, size_t n)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
if ((ret = strndup(str, n)) == NULL)
|
||||
(void) zutil_no_memory(hdl);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Intermediate structures used to gather configuration information.
|
||||
*/
|
||||
@@ -1272,20 +1283,22 @@ zpool_find_import_scan_path(libpc_handle_t *hdl, pthread_mutex_t *lock,
|
||||
{
|
||||
int error = 0;
|
||||
char path[MAXPATHLEN];
|
||||
char *d, *b;
|
||||
char *dpath, *name;
|
||||
char *d = NULL;
|
||||
ssize_t dl;
|
||||
const char *dpath, *name;
|
||||
|
||||
/*
|
||||
* Separate the directory part and last part of the
|
||||
* path. We do this so that we can get the realpath of
|
||||
* Separate the directory and the basename.
|
||||
* We do this so that we can get the realpath of
|
||||
* the directory. We don't get the realpath on the
|
||||
* whole path because if it's a symlink, we want the
|
||||
* path of the symlink not where it points to.
|
||||
*/
|
||||
d = zutil_strdup(hdl, dir);
|
||||
b = zutil_strdup(hdl, dir);
|
||||
dpath = dirname(d);
|
||||
name = basename(b);
|
||||
name = zfs_basename(dir);
|
||||
if ((dl = zfs_dirnamelen(dir)) == -1)
|
||||
dpath = ".";
|
||||
else
|
||||
dpath = d = zutil_strndup(hdl, dir, dl);
|
||||
|
||||
if (realpath(dpath, path) == NULL) {
|
||||
error = errno;
|
||||
@@ -1303,7 +1316,6 @@ zpool_find_import_scan_path(libpc_handle_t *hdl, pthread_mutex_t *lock,
|
||||
zpool_find_import_scan_add_slice(hdl, lock, cache, path, name, order);
|
||||
|
||||
out:
|
||||
free(b);
|
||||
free(d);
|
||||
return (error);
|
||||
}
|
||||
@@ -1506,6 +1518,7 @@ discover_cached_paths(libpc_handle_t *hdl, nvlist_t *nv,
|
||||
avl_tree_t *cache, pthread_mutex_t *lock)
|
||||
{
|
||||
char *path = NULL;
|
||||
ssize_t dl;
|
||||
uint_t children;
|
||||
nvlist_t **child;
|
||||
|
||||
@@ -1521,8 +1534,12 @@ discover_cached_paths(libpc_handle_t *hdl, nvlist_t *nv,
|
||||
* our directory cache.
|
||||
*/
|
||||
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
|
||||
if ((dl = zfs_dirnamelen(path)) == -1)
|
||||
path = ".";
|
||||
else
|
||||
path[dl] = '\0';
|
||||
return (zpool_find_import_scan_dir(hdl, lock, cache,
|
||||
dirname(path), 0));
|
||||
path, 0));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user