Check the return value for malloc(), avoiding a NULL pointer
dereference, and propagate error in function callers.
Found with GCC 13 and -fanalyzer:
../subprojects/libvhost-user/libvhost-user.c: In function ‘virtqueue_alloc_element’:
../subprojects/libvhost-user/libvhost-user.c:2556:19: error: dereference of possibly-NULL ‘elem’ [CWE-690] [-Werror=analyzer-possible-null-dereference]
2556 | elem->out_num = out_num;
| ~~~~~~~~~~~~~~^~~~~~~~~
‘virtqueue_alloc_element’: event 1
|
| 2554 | assert(sz >= sizeof(VuVirtqElement));
| | ^~~~~~
| | |
| | (1) following ‘true’ branch (when ‘sz > 31’)...
|
‘virtqueue_alloc_element’: events 2-4
|
| 2555 | elem = malloc(out_sg_end);
| | ^~~~ ~~~~~~~~~~~~~~~~~~
| | | |
| | | (3) this call could return NULL
| | (2) ...to here
| 2556 | elem->out_num = out_num;
| | ~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (4) ‘elem’ could be NULL: unchecked value from (3)
|
Signed-off-by: Carlos López <clopez@suse.de>
Message-Id: <
20230210112514.16858-1-clopez@suse.de>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
assert(sz >= sizeof(VuVirtqElement));
elem = malloc(out_sg_end);
+ if (!elem) {
+ DPRINT("%s: failed to malloc virtqueue element\n", __func__);
+ return NULL;
+ }
elem->out_num = out_num;
elem->in_num = in_num;
elem->in_sg = (void *)elem + in_sg_ofs;
/* Now copy what we have collected and mapped */
elem = virtqueue_alloc_element(sz, out_num, in_num);
+ if (!elem) {
+ return NULL;
+ }
elem->index = idx;
for (i = 0; i < out_num; i++) {
elem->out_sg[i] = iov[i];