From 64dfdaba372f07f91a6eab598b3480693b1d14c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Sat, 22 May 2021 16:29:53 +0200 Subject: [PATCH] libzutil: import: filter out unsuitable files earlier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only accept the right type of file, if available, and reject too-small files before opening them on Linux Reviewed-by: John Kennedy Reviewed-by: Brian Behlendorf Reviewed-by: Ryan Moeller Signed-off-by: Ahelenia ZiemiaƄska Closes #12105 --- lib/libzutil/os/linux/zutil_import_os.c | 12 +++--------- lib/libzutil/zutil_import.c | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/libzutil/os/linux/zutil_import_os.c b/lib/libzutil/os/linux/zutil_import_os.c index 433a72282b..5defb526f2 100644 --- a/lib/libzutil/os/linux/zutil_import_os.c +++ b/lib/libzutil/os/linux/zutil_import_os.c @@ -114,9 +114,11 @@ zpool_open_func(void *arg) /* * Ignore failed stats. We only want regular files and block devices. + * Ignore files that are too small to hold a zpool. */ if (stat64(rn->rn_name, &statbuf) != 0 || - (!S_ISREG(statbuf.st_mode) && !S_ISBLK(statbuf.st_mode))) + (!S_ISREG(statbuf.st_mode) && !S_ISBLK(statbuf.st_mode)) || + (S_ISREG(statbuf.st_mode) && statbuf.st_size < SPA_MINDEVSIZE)) return; /* @@ -132,14 +134,6 @@ zpool_open_func(void *arg) if (fd < 0) return; - /* - * This file is too small to hold a zpool - */ - if (S_ISREG(statbuf.st_mode) && statbuf.st_size < SPA_MINDEVSIZE) { - (void) close(fd); - return; - } - error = zpool_read_label(fd, &config, &num_labels); if (error != 0) { (void) close(fd); diff --git a/lib/libzutil/zutil_import.c b/lib/libzutil/zutil_import.c index 9d7fcb8d96..871a75ab23 100644 --- a/lib/libzutil/zutil_import.c +++ b/lib/libzutil/zutil_import.c @@ -1243,10 +1243,21 @@ zpool_find_import_scan_dir(libpc_handle_t *hdl, pthread_mutex_t *lock, while ((dp = readdir64(dirp)) != NULL) { const char *name = dp->d_name; - if (name[0] == '.' && - (name[1] == 0 || (name[1] == '.' && name[2] == 0))) + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue; + switch (dp->d_type) { + case DT_UNKNOWN: + case DT_BLK: +#ifdef __FreeBSD__ + case DT_CHR: +#endif + case DT_REG: + break; + default: + continue; + } + zpool_find_import_scan_add_slice(hdl, lock, cache, path, name, order); }