OpenSolaris

Printable Version Enter a New Search
Bug ID 6588264
Synopsis zpool_get_errlog() can attempt to calloc size 0
State 10-Fix Delivered (Fix available in build)
Category:Subcategory utility:zfs
Keywords
Responsible Engineer Eric Kustarz
Reported Against
Duplicate Of
Introduced In solaris_nevada
Commit to Fix snv_72
Fixed In snv_72
Release Fixed solaris_nevada(snv_72) , solaris_10u6(s10u6_01) (Bug ID:2156442)
Related Bugs
Submit Date 2-August-2007
Last Update Date 29-April-2008
Description
Part of what 'zpool status' does in status_callback() is:
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
                    &nerr) == 0) {
                        nvlist_t *nverrlist = NULL;

                        /*
                         * If the approximate error count is small, get a
                         * precise count by fetching the entire log and
                         * uniquifying the results.
                         */
                        if (nerr < 100 && !cbp->cb_verbose &&
                            zpool_get_errlog(zhp, &nverrlist) == 0) {
                                nvpair_t *elem;

                                elem = NULL;
                                nerr = 0;
                                while ((elem = nvlist_next_nvpair(nverrlist,
                                    elem)) != NULL) {
                                        nerr++;
                                }
                        }
                        nvlist_free(nverrlist);


And in zpool_get_errlog(), we do:
verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT,
    &count) == 0);
if ((zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl,
    count * sizeof (zbookmark_t))) == (uintptr_t)NULL)
	return (-1);

Note, in most cases, there won't be any errors, so 'count' will be zero.  We will then
try to alloc size 0.  That's pretty ugly.

Further, looking at zfs_alloc():
void *
zfs_alloc(libzfs_handle_t *hdl, size_t size)
{
        void *data;

        if ((data = calloc(1, size)) == NULL)
                (void) no_memory(hdl);

        return (data);
}

If calloc() returns NULL, we don't just simply return an error up the stack, we bail
completely.

This works ok on OpenSolaris (partly because we're using libumem), but if another platform
say had a different underlying calloc() routine that returned NULL if size was 0, then
we'd have badness.

It also unnecessary for us to call zpool_get_errlog() in the first place if 'nerr' is 0.
Work Around
N/A
Comments
N/A