diff options
author | наб <[email protected]> | 2021-05-22 17:19:14 +0200 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2021-06-11 09:10:21 -0700 |
commit | feb04e66802ef96aa77951c43d4b632b376041ef (patch) | |
tree | 0d78f6283f001f8f66828bef33c9ace4185f7802 /lib/libzutil | |
parent | 64dfdaba372f07f91a6eab598b3480693b1d14c8 (diff) |
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 <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Ryan Moeller <[email protected]>
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
Closes #12105
Diffstat (limited to 'lib/libzutil')
-rw-r--r-- | lib/libzutil/zutil_import.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/lib/libzutil/zutil_import.c b/lib/libzutil/zutil_import.c index 871a75ab2..9bd12973f 100644 --- a/lib/libzutil/zutil_import.c +++ b/lib/libzutil/zutil_import.c @@ -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); } |