diff --git a/lib/libzfs/libzfs_import.c b/lib/libzfs/libzfs_import.c index 0a8f0a1cca..4a7634a631 100644 --- a/lib/libzfs/libzfs_import.c +++ b/lib/libzfs/libzfs_import.c @@ -791,7 +791,7 @@ zpool_find_import_impl(libzfs_handle_t *hdl, int argc, char **argv, int i; DIR *dirp = NULL; struct dirent64 *dp; - char path[MAXPATHLEN], path2[MAXPATHLEN]; + char path[MAXPATHLEN]; char *end; size_t pathleft; struct stat64 statbuf; @@ -818,6 +818,7 @@ zpool_find_import_impl(libzfs_handle_t *hdl, int argc, char **argv, */ for (i = 0; i < argc; i++) { char *rdsk; + int dfd; /* use realpath to normalize the path */ if (realpath(argv[i], path) == 0) { @@ -841,7 +842,8 @@ zpool_find_import_impl(libzfs_handle_t *hdl, int argc, char **argv, else rdsk = path; - if ((dirp = opendir(rdsk)) == NULL) { + if ((dfd = open64(rdsk, O_RDONLY)) < 0 || + (dirp = fdopendir(dfd)) == NULL) { zfs_error_aux(hdl, strerror(errno)); (void) zfs_error_fmt(hdl, EZFS_BADPATH, dgettext(TEXT_DOMAIN, "cannot open '%s'"), @@ -858,19 +860,20 @@ zpool_find_import_impl(libzfs_handle_t *hdl, int argc, char **argv, (name[1] == 0 || (name[1] == '.' && name[2] == 0))) continue; - snprintf(path2, sizeof (path2), "%s%s", rdsk, name); + if ((fd = openat64(dfd, name, O_RDONLY)) < 0) + continue; /* * Ignore failed stats. We only want regular * files, character devs and block devs. */ - if (stat64(path2, &statbuf) != 0 || + if (fstat64(fd, &statbuf) != 0 || (!S_ISREG(statbuf.st_mode) && - !S_ISBLK(statbuf.st_mode))) - continue; - - if ((fd = open64(path2, O_RDONLY)) < 0) + !S_ISCHR(statbuf.st_mode) && + !S_ISBLK(statbuf.st_mode))) { + (void) close(fd); continue; + } if ((zpool_read_label(fd, &config)) != 0) { (void) close(fd); @@ -903,7 +906,9 @@ zpool_find_import_impl(libzfs_handle_t *hdl, int argc, char **argv, config = NULL; continue; } - if (add_config(hdl, &pools, path2, config) != 0) + /* use the non-raw path for the config */ + (void) strlcpy(end, name, pathleft); + if (add_config(hdl, &pools, path, config) != 0) goto error; } }