Skip to content

Commit 67395be

Browse files
authored
Fix userland dereference NULL return value bugs
* `zstream_do_token()` does not handle failures from `libzfs_init()` * `ztest_global_vars_to_zdb_args()` does not handle failures from `calloc()`. * `zfs_snapshot_nvl()` will pass an offset to a NULL pointer as a source to `strlcpy()` if the provided nvlist is `NULL`. We handle these by doing what the existing error handling does for other errors involving these functions. Coverity complained about these. It had complained about several more, but one was fixed by 570ca44 and another was a false positive. The remaining complaints labelled "dereferece null return vaue" involve fetching things stored in in-kernel data structures via `list_head()/list_next()`, `AVL_PREV()/AVL_NEXT()` and `zfs_btree_find()`. Most of them occur in void functions that have no error handling. They are much harder to analyze than the two fixed in this patch, so they are left for a follow-up patch. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Signed-off-by: Richard Yao <richard.yao@alumni.stonybrook.edu> Closes #13971
1 parent a36b37d commit 67395be

File tree

3 files changed

+13
-1
lines changed

3 files changed

+13
-1
lines changed

cmd/zstream/zstream_token.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ int
4949
zstream_do_token(int argc, char *argv[])
5050
{
5151
char *resume_token = NULL;
52+
libzfs_handle_t *hdl;
5253

5354
if (argc < 2) {
5455
(void) fprintf(stderr, "Need to pass the resume token\n");
@@ -57,7 +58,10 @@ zstream_do_token(int argc, char *argv[])
5758

5859
resume_token = argv[1];
5960

60-
libzfs_handle_t *hdl = libzfs_init();
61+
if ((hdl = libzfs_init()) == NULL) {
62+
(void) fprintf(stderr, "%s\n", libzfs_error_init(errno));
63+
return (1);
64+
}
6165

6266
nvlist_t *resume_nvl =
6367
zfs_send_resume_token_to_nvlist(hdl, resume_token);

cmd/ztest.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6637,6 +6637,8 @@ ztest_global_vars_to_zdb_args(void)
66376637
{
66386638
char **args = calloc(2*ztest_opts.zo_gvars_count + 1, sizeof (char *));
66396639
char **cur = args;
6640+
if (args == NULL)
6641+
return (NULL);
66406642
for (size_t i = 0; i < ztest_opts.zo_gvars_count; i++) {
66416643
*cur++ = (char *)"-o";
66426644
*cur++ = ztest_opts.zo_gvars[i];
@@ -6906,6 +6908,10 @@ ztest_run_zdb(const char *pool)
69066908
ztest_get_zdb_bin(bin, len);
69076909

69086910
char **set_gvars_args = ztest_global_vars_to_zdb_args();
6911+
if (set_gvars_args == NULL) {
6912+
fatal(B_FALSE, "Failed to allocate memory in "
6913+
"ztest_global_vars_to_zdb_args(). Cannot run zdb.\n");
6914+
}
69096915
char *set_gvars_args_joined = join_strings(set_gvars_args, " ");
69106916
free(set_gvars_args);
69116917

lib/libzfs/libzfs_dataset.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4164,6 +4164,8 @@ zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
41644164
* same pool, as does lzc_snapshot (below).
41654165
*/
41664166
elem = nvlist_next_nvpair(snaps, NULL);
4167+
if (elem == NULL)
4168+
return (-1);
41674169
(void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
41684170
pool[strcspn(pool, "/@")] = '\0';
41694171
zpool_hdl = zpool_open(hdl, pool);

0 commit comments

Comments
 (0)