From 8a969f3e2d07edd568d99a53137306d89d99120e Mon Sep 17 00:00:00 2001 From: Matthew Ahrens Date: Mon, 26 Jul 2021 12:51:39 -0700 Subject: [PATCH] Read past end of argv array in zpool_do_import() `zpool_do_import()` passes `argv[0]`, (optionally) `argv[1]`, and `pool_specified` to `import_pools()`. If `pool_specified==FALSE`, the `argv[]` arguments are not used. However, these values may be off the end of the `argv[]` array, so loading them could dereference unmapped memory. This error is reported by the asan build: ``` ================================================================= ==6003==ERROR: AddressSanitizer: heap-buffer-overflow READ of size 8 at 0x6030000004a8 thread T0 #0 0x562a078b50eb in zpool_do_import zpool_main.c:3796 #1 0x562a078858c5 in main zpool_main.c:10709 #2 0x7f5115231bf6 in __libc_start_main #3 0x562a07885eb9 in _start 0x6030000004a8 is located 0 bytes to the right of 24-byte region allocated by thread T0 here: #0 0x7f5116ac6b40 in __interceptor_malloc #1 0x562a07885770 in main zpool_main.c:10699 #2 0x7f5115231bf6 in __libc_start_main ``` This commit passes NULL for these arguments if they are off the end of the `argv[]` array. Reviewed-by: George Wilson Reviewed-by: John Kennedy Reviewed-by: Brian Behlendorf Reviewed-by: Allan Jude Signed-off-by: Matthew Ahrens Closes #12339 --- cmd/zpool/zpool_main.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index a8c3aedc03..87cb28ef89 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -3764,9 +3764,10 @@ zpool_do_import(int argc, char **argv) return (1); } - err = import_pools(pools, props, mntopts, flags, argv[0], - argc == 1 ? NULL : argv[1], do_destroyed, pool_specified, - do_all, &idata); + err = import_pools(pools, props, mntopts, flags, + argc >= 1 ? argv[0] : NULL, + argc >= 2 ? argv[1] : NULL, + do_destroyed, pool_specified, do_all, &idata); /* * If we're using the cachefile and we failed to import, then @@ -3786,9 +3787,10 @@ zpool_do_import(int argc, char **argv) nvlist_free(pools); pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops); - err = import_pools(pools, props, mntopts, flags, argv[0], - argc == 1 ? NULL : argv[1], do_destroyed, pool_specified, - do_all, &idata); + err = import_pools(pools, props, mntopts, flags, + argc >= 1 ? argv[0] : NULL, + argc >= 2 ? argv[1] : NULL, + do_destroyed, pool_specified, do_all, &idata); } error: