qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

hw/core: Fix fit_load_fdt() error API violations

fit_load_fdt() passes @errp to fit_image_addr(), then recovers from
ENOENT failures. Passing @errp is wrong, because it works only as
long as @errp is neither @error_fatal nor @error_abort. Error
recovery dereferences @errp. That's also wrong; see the big comment
in error.h. Error recovery can leave *errp pointing to a freed
Error object. Wrong, it must be null on success. Messed up in
commit 3eb99edb48 "loader-fit: Wean off error_printf()".

No caller actually passes such values, or uses *errp on success.

Fix anyway: splice in a local Error *err, and error_propagate().

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20191204093625.14836-8-armbru@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>

+8 -7
+8 -7
hw/core/loader-fit.c
··· 178 178 int cfg, void *opaque, const void *match_data, 179 179 hwaddr kernel_end, Error **errp) 180 180 { 181 + Error *err = NULL; 181 182 const char *name; 182 183 const void *data; 183 184 const void *load_data; 184 185 hwaddr load_addr; 185 - int img_off, err; 186 + int img_off; 186 187 size_t sz; 187 188 int ret; 188 189 ··· 197 198 return -EINVAL; 198 199 } 199 200 200 - err = fit_image_addr(itb, img_off, "load", &load_addr, errp); 201 - if (err == -ENOENT) { 201 + ret = fit_image_addr(itb, img_off, "load", &load_addr, &err); 202 + if (ret == -ENOENT) { 202 203 load_addr = ROUND_UP(kernel_end, 64 * KiB) + (10 * MiB); 203 - error_free(*errp); 204 - } else if (err) { 205 - error_prepend(errp, "unable to read FDT load address from FIT: "); 206 - ret = err; 204 + error_free(err); 205 + } else if (ret) { 206 + error_propagate_prepend(errp, err, 207 + "unable to read FDT load address from FIT: "); 207 208 goto out; 208 209 } 209 210