diff --git a/.gitignore b/.gitignore index b53e493..e71c6e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -SOURCES/spice-vdagent-0.18.0.tar.bz2 +SOURCES/spice-vdagent-0.19.0.tar.bz2 +SOURCES/victortoso-E37A484F.keyring diff --git a/.spice-vdagent.metadata b/.spice-vdagent.metadata index 978d33a..f7be6b1 100644 --- a/.spice-vdagent.metadata +++ b/.spice-vdagent.metadata @@ -1 +1,2 @@ -2e18fc918c46cdca1f00a3ce3c139c93f68ab166 SOURCES/spice-vdagent-0.18.0.tar.bz2 +ba2297228f26c60fe33539f15dd7e9bf2d216888 SOURCES/spice-vdagent-0.19.0.tar.bz2 +da7a529db1ea28a1540c5892ea9836abeb378c3e SOURCES/victortoso-E37A484F.keyring diff --git a/SOURCES/0001-vdagent-Do-not-send-empty-screen-resolution-messages.patch b/SOURCES/0001-vdagent-Do-not-send-empty-screen-resolution-messages.patch deleted file mode 100644 index edde375..0000000 --- a/SOURCES/0001-vdagent-Do-not-send-empty-screen-resolution-messages.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 44592b47a60b943b0e0990ad82644e7b9a2091ad Mon Sep 17 00:00:00 2001 -From: Victor Toso -Date: Thu, 15 Nov 2018 16:47:33 +0100 -Subject: [PATCH] vdagent: Do not send empty screen resolution messages - -Easier to trigger on Wayland guest by running - -> xrandr --output XWAYLAND0 --rotate left - -In current master, this causes the spice-vdagentd to disconnect from -the client. In 0.18 branch (latest release), mouse becomes unusable as -mentioned in the referred bug below. - -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1641723 - -Signed-off-by: Victor Toso ---- - src/vdagent/x11-randr.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/src/vdagent/x11-randr.c b/src/vdagent/x11-randr.c -index 803cf73..708f060 100644 ---- a/src/vdagent/x11-randr.c -+++ b/src/vdagent/x11-randr.c -@@ -974,6 +974,12 @@ no_info: - } - } - -+ if (screen_count == 0) { -+ syslog(LOG_DEBUG, "Screen count is zero, are we on wayland?"); -+ g_free(res); -+ return; -+ } -+ - if (x11->debug) { - for (i = 0; i < screen_count; i++) - syslog(LOG_DEBUG, "Screen %d %dx%d%+d%+d", i, res[i].width, --- -2.19.1 - diff --git a/SOURCES/0001-vdagent-fix-memory-leak-of-g_memdup.patch b/SOURCES/0001-vdagent-fix-memory-leak-of-g_memdup.patch new file mode 100644 index 0000000..e236f16 --- /dev/null +++ b/SOURCES/0001-vdagent-fix-memory-leak-of-g_memdup.patch @@ -0,0 +1,57 @@ +From b6fde1641a47c13b151b20c8e0db03cf7da45d9f Mon Sep 17 00:00:00 2001 +From: Victor Toso +Date: Fri, 12 Jul 2019 11:12:37 +0200 +Subject: [PATCH 1/9] vdagent: fix memory leak of g_memdup() + +Found by covscan: + + | spice-vdagent-0.19.0/src/vdagent/vdagent.c:432:9: warning: Potential leak of memory pointed to by 'orig_argv' + | # g_printerr("Invalid arguments, %s\n", error->message); + | # ^ + | spice-vdagent-0.19.0/src/vdagent/vdagent.c:418:24: note: Memory is allocated + | # char **orig_argv = g_memdup(argv, sizeof(char*) * (argc+1)); + | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | spice-vdagent-0.19.0/src/vdagent/vdagent.c:431:9: note: Assuming 'error' is not equal to NULL + | # if (error != NULL) { + | # ^~~~~~~~~~~~~ + | spice-vdagent-0.19.0/src/vdagent/vdagent.c:431:5: note: Taking true branch + | # if (error != NULL) { + | # ^ + | spice-vdagent-0.19.0/src/vdagent/vdagent.c:432:9: note: Potential leak of memory pointed to by 'orig_argv' + | # g_printerr("Invalid arguments, %s\n", error->message); + | # ^ + | # 430| + | # 431| if (error != NULL) { + | # 432|-> g_printerr("Invalid arguments, %s\n", error->message); + | # 433| g_clear_error(&error); + | # 434| return -1; + +Signed-off-by: Victor Toso +Acked-by: Frediano Ziglio +--- + src/vdagent/vdagent.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c +index 13ef29f..d799d1f 100644 +--- a/src/vdagent/vdagent.c ++++ b/src/vdagent/vdagent.c +@@ -431,6 +431,7 @@ int main(int argc, char *argv[]) + if (error != NULL) { + g_printerr("Invalid arguments, %s\n", error->message); + g_clear_error(&error); ++ g_free(orig_argv); + return -1; + } + +@@ -446,6 +447,7 @@ int main(int argc, char *argv[]) + + if (!g_file_test(portdev, G_FILE_TEST_EXISTS)) { + g_debug("vdagent virtio channel %s does not exist, exiting", portdev); ++ g_free(orig_argv); + return 0; + } + +-- +2.21.0 + diff --git a/SOURCES/0002-udscs-Avoid-file-descriptor-leak.patch b/SOURCES/0002-udscs-Avoid-file-descriptor-leak.patch deleted file mode 100644 index 6fc77c4..0000000 --- a/SOURCES/0002-udscs-Avoid-file-descriptor-leak.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 248fb075d8b74ed2d2448822bbc69da4a2c1bb36 Mon Sep 17 00:00:00 2001 -From: Frediano Ziglio -Date: Thu, 15 Nov 2018 21:55:11 +0000 -Subject: [PATCH] udscs: Avoid file descriptor leak - -If connection fails the socket descriptor is not closed causing -a leak. - -Signed-off-by: Frediano Ziglio -Acked-by: Victor Toso ---- - src/udscs.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/udscs.c b/src/udscs.c -index c439f23..0c52af3 100644 ---- a/src/udscs.c -+++ b/src/udscs.c -@@ -109,6 +109,7 @@ struct udscs_connection *udscs_connect(const char *socketname, - if (conn->debug) { - syslog(LOG_DEBUG, "connect %s: %m", socketname); - } -+ close(conn->fd); - free(conn); - return NULL; - } --- -2.19.2 - diff --git a/SOURCES/0002-x11-randr-use-glib-s-MAX-and-MIN.patch b/SOURCES/0002-x11-randr-use-glib-s-MAX-and-MIN.patch new file mode 100644 index 0000000..c28db45 --- /dev/null +++ b/SOURCES/0002-x11-randr-use-glib-s-MAX-and-MIN.patch @@ -0,0 +1,54 @@ +From 70c5908f8c46a0cd53cca109ecc0c56ff5b33d77 Mon Sep 17 00:00:00 2001 +From: Victor Toso +Date: Fri, 12 Jul 2019 11:12:39 +0200 +Subject: [PATCH 2/9] x11-randr: use glib's MAX and MIN + +Since 2861868 "randr: remove monitors.xml on auto-configuration" in +2015-04-10 by Marc-Andre Lureau this +file includes glib.h and can remove those helpers. + +Signed-off-by: Victor Toso +Acked-by: Frediano Ziglio +--- + src/vdagent/x11-randr.c | 18 ++++-------------- + 1 file changed, 4 insertions(+), 14 deletions(-) + +diff --git a/src/vdagent/x11-randr.c b/src/vdagent/x11-randr.c +index 88857c8..d000e28 100644 +--- a/src/vdagent/x11-randr.c ++++ b/src/vdagent/x11-randr.c +@@ -555,16 +555,6 @@ int vdagent_x11_randr_handle_event(struct vdagent_x11 *x11, + return handled; + } + +-static int min_int(int x, int y) +-{ +- return x > y ? y : x; +-} +- +-static int max_int(int x, int y) +-{ +- return x > y ? x : y; +-} +- + static int constrain_to_range(int low, int *val, int high) + { + if (low <= *val && *val <= high) { +@@ -631,10 +621,10 @@ static void zero_base_monitors(struct vdagent_x11 *x11, + mon_width = (int *)&mon_config->monitors[i].width; + mon_height = (int *)&mon_config->monitors[i].height; + constrain_to_screen(x11, mon_width, mon_height); +- min_x = min_int(mon_config->monitors[i].x, min_x); +- min_y = min_int(mon_config->monitors[i].y, min_y); +- max_x = max_int(mon_config->monitors[i].x + *mon_width, max_x); +- max_y = max_int(mon_config->monitors[i].y + *mon_height, max_y); ++ min_x = MIN(mon_config->monitors[i].x, min_x); ++ min_y = MIN(mon_config->monitors[i].y, min_y); ++ max_x = MAX(mon_config->monitors[i].x + *mon_width, max_x); ++ max_y = MAX(mon_config->monitors[i].y + *mon_height, max_y); + } + if (min_x != 0 || min_y != 0) { + syslog(LOG_ERR, "%s: agent config %d,%d rooted, adjusting to 0,0.", +-- +2.21.0 + diff --git a/SOURCES/0003-x11-randr-simplest-fix-for-address-of-packed-member.patch b/SOURCES/0003-x11-randr-simplest-fix-for-address-of-packed-member.patch new file mode 100644 index 0000000..6320757 --- /dev/null +++ b/SOURCES/0003-x11-randr-simplest-fix-for-address-of-packed-member.patch @@ -0,0 +1,74 @@ +From 7976dc31af511315fa7b83cfbb1e3bf4b613f84b Mon Sep 17 00:00:00 2001 +From: Victor Toso +Date: Fri, 12 Jul 2019 11:12:41 +0200 +Subject: [PATCH 3/9] x11-randr: simplest fix for address-of-packed-member +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The struct type for width/height is uint32_t while we are trying to +access and change it with int* - code can be improved a bit in following +patches but this one fixes the warning by copying the value from the +struct and copying back new value afterwards. + +Also: +- Moved variables to internal scope; +- Added braces to inner if; + + > src/vdagent/x11-randr.c: In function ‘zero_base_monitors’: + > src/vdagent/x11-randr.c:621:28: error: taking address of packed member of + > ‘struct VDAgentMonConfig’ may result in an unaligned pointer value + > [-Werror=address-of-packed-member] + > 621 | mon_width = (int *)&mon_config->monitors[i].width; + > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + > src/vdagent/x11-randr.c:622:29: error: taking address of packed member of + > ‘struct VDAgentMonConfig’ may result in an unaligned pointer value + > [-Werror=address-of-packed-member] + > 622 | mon_height = (int *)&mon_config->monitors[i].height; + > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Victor Toso +Acked-by: Frediano Ziglio +--- + src/vdagent/x11-randr.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/src/vdagent/x11-randr.c b/src/vdagent/x11-randr.c +index d000e28..4b022d6 100644 +--- a/src/vdagent/x11-randr.c ++++ b/src/vdagent/x11-randr.c +@@ -611,20 +611,24 @@ static void zero_base_monitors(struct vdagent_x11 *x11, + int *width, int *height) + { + int i, min_x = INT_MAX, min_y = INT_MAX, max_x = INT_MIN, max_y = INT_MIN; +- int *mon_height, *mon_width; + + for (i = 0; i < mon_config->num_of_monitors; i++) { +- if (!monitor_enabled(&mon_config->monitors[i])) ++ int mon_height, mon_width; ++ ++ if (!monitor_enabled(&mon_config->monitors[i])) { + continue; ++ } + mon_config->monitors[i].x &= ~7; + mon_config->monitors[i].width &= ~7; +- mon_width = (int *)&mon_config->monitors[i].width; +- mon_height = (int *)&mon_config->monitors[i].height; +- constrain_to_screen(x11, mon_width, mon_height); ++ mon_width = mon_config->monitors[i].width; ++ mon_height = mon_config->monitors[i].height; ++ constrain_to_screen(x11, &mon_width, &mon_height); + min_x = MIN(mon_config->monitors[i].x, min_x); + min_y = MIN(mon_config->monitors[i].y, min_y); +- max_x = MAX(mon_config->monitors[i].x + *mon_width, max_x); +- max_y = MAX(mon_config->monitors[i].y + *mon_height, max_y); ++ max_x = MAX(mon_config->monitors[i].x + mon_width, max_x); ++ max_y = MAX(mon_config->monitors[i].y + mon_height, max_y); ++ mon_config->monitors[i].width = mon_width; ++ mon_config->monitors[i].height = mon_height; + } + if (min_x != 0 || min_y != 0) { + syslog(LOG_ERR, "%s: agent config %d,%d rooted, adjusting to 0,0.", +-- +2.21.0 + diff --git a/SOURCES/0004-vdagent-simple-fix-for-address-of-packed-member.patch b/SOURCES/0004-vdagent-simple-fix-for-address-of-packed-member.patch new file mode 100644 index 0000000..b9f3a0e --- /dev/null +++ b/SOURCES/0004-vdagent-simple-fix-for-address-of-packed-member.patch @@ -0,0 +1,53 @@ +From 6bfbd03e83fc8fcf783d4431607d7d6129af58b0 Mon Sep 17 00:00:00 2001 +From: Victor Toso +Date: Fri, 12 Jul 2019 11:12:42 +0200 +Subject: [PATCH 4/9] vdagent: simple fix for address-of-packed-member +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Seems to be a false positive but as this message only happens when user +client connects, we can copy this array to make compiling warn free. + + > src/vdagent/vdagent.c: In function ‘daemon_read_complete’: + > src/vdagent/vdagent.c:226:71: error: taking address of packed member of + > ‘struct VDAgentAudioVolumeSync’ may result in an unaligned pointer + > value [-Werror=address-of-packed-member] + > 226 | vdagent_audio_playback_sync(avs->mute, avs->nchannels, avs->volume); + > | ~~~^~~~~~~~ + > src/vdagent/vdagent.c:228:69: error: taking address of packed member of + > ‘struct VDAgentAudioVolumeSync’ may result in an unaligned pointer + > value [-Werror=address-of-packed-member] + > 228 | vdagent_audio_record_sync(avs->mute, avs->nchannels, avs->volume); + > | ~~~^~~~~~~~ + +Signed-off-by: Victor Toso +Acked-by: Frediano Ziglio +--- + src/vdagent/vdagent.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c +index d799d1f..0e2e73e 100644 +--- a/src/vdagent/vdagent.c ++++ b/src/vdagent/vdagent.c +@@ -222,11 +222,14 @@ static void daemon_read_complete(struct udscs_connection **connp, + break; + case VDAGENTD_AUDIO_VOLUME_SYNC: { + VDAgentAudioVolumeSync *avs = (VDAgentAudioVolumeSync *)data; ++ uint16_t *volume = g_memdup(avs->volume, sizeof(uint16_t) * avs->nchannels); ++ + if (avs->is_playback) { +- vdagent_audio_playback_sync(avs->mute, avs->nchannels, avs->volume); ++ vdagent_audio_playback_sync(avs->mute, avs->nchannels, volume); + } else { +- vdagent_audio_record_sync(avs->mute, avs->nchannels, avs->volume); ++ vdagent_audio_record_sync(avs->mute, avs->nchannels, volume); + } ++ g_free(volume); + break; + } + case VDAGENTD_FILE_XFER_DATA: +-- +2.21.0 + diff --git a/SOURCES/0005-x11-randr-Avoid-passing-XEvent-as-value.patch b/SOURCES/0005-x11-randr-Avoid-passing-XEvent-as-value.patch new file mode 100644 index 0000000..d6d6558 --- /dev/null +++ b/SOURCES/0005-x11-randr-Avoid-passing-XEvent-as-value.patch @@ -0,0 +1,69 @@ +From b6dfef73f2926c65ed146eea6ab061dd87d77f10 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Wed, 19 Dec 2018 18:25:51 +0000 +Subject: [PATCH 5/9] x11-randr: Avoid passing XEvent as value + +The structure is not that small and is not necessary to copy +the value. +This also removed a Coverity warning. + +Signed-off-by: Frediano Ziglio +Acked-by: Victor Toso +--- + src/vdagent/x11-priv.h | 2 +- + src/vdagent/x11-randr.c | 8 ++++---- + src/vdagent/x11.c | 2 +- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/vdagent/x11-priv.h b/src/vdagent/x11-priv.h +index 99676d2..730b9b3 100644 +--- a/src/vdagent/x11-priv.h ++++ b/src/vdagent/x11-priv.h +@@ -152,7 +152,7 @@ void vdagent_x11_send_daemon_guest_xorg_res(struct vdagent_x11 *x11, + void vdagent_x11_randr_handle_root_size_change(struct vdagent_x11 *x11, + int screen, int width, int height); + int vdagent_x11_randr_handle_event(struct vdagent_x11 *x11, +- XEvent event); ++ const XEvent *event); + void vdagent_x11_set_error_handler(struct vdagent_x11 *x11, + int (*handler)(Display *, XErrorEvent *)); + int vdagent_x11_restore_error_handler(struct vdagent_x11 *x11); +diff --git a/src/vdagent/x11-randr.c b/src/vdagent/x11-randr.c +index 4b022d6..3fb7a68 100644 +--- a/src/vdagent/x11-randr.c ++++ b/src/vdagent/x11-randr.c +@@ -529,14 +529,14 @@ void vdagent_x11_randr_handle_root_size_change(struct vdagent_x11 *x11, + } + + int vdagent_x11_randr_handle_event(struct vdagent_x11 *x11, +- XEvent event) ++ const XEvent *event) + { + int handled = TRUE; + +- switch (event.type - x11->xrandr_event_base) { ++ switch (event->type - x11->xrandr_event_base) { + case RRScreenChangeNotify: { +- XRRScreenChangeNotifyEvent *sce = +- (XRRScreenChangeNotifyEvent *) &event; ++ const XRRScreenChangeNotifyEvent *sce = ++ (const XRRScreenChangeNotifyEvent *) event; + vdagent_x11_randr_handle_root_size_change(x11, 0, + sce->width, sce->height); + break; +diff --git a/src/vdagent/x11.c b/src/vdagent/x11.c +index c2515a8..61d7c69 100644 +--- a/src/vdagent/x11.c ++++ b/src/vdagent/x11.c +@@ -545,7 +545,7 @@ static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event) + } + #endif + +- if (vdagent_x11_randr_handle_event(x11, event)) ++ if (vdagent_x11_randr_handle_event(x11, &event)) + return; + + switch (event.type) { +-- +2.21.0 + diff --git a/SOURCES/0006-x11-Avoid-passing-XEvent-as-value.patch b/SOURCES/0006-x11-Avoid-passing-XEvent-as-value.patch new file mode 100644 index 0000000..653ac05 --- /dev/null +++ b/SOURCES/0006-x11-Avoid-passing-XEvent-as-value.patch @@ -0,0 +1,158 @@ +From 3522667bfac147f4f959025ccf12ea1d99cc1f75 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Wed, 19 Dec 2018 18:28:38 +0000 +Subject: [PATCH 6/9] x11: Avoid passing XEvent as value + +The structure is not that small and is not necessary to copy +the value. +This also removed a Coverity warning. + +Signed-off-by: Frediano Ziglio +Acked-by: Victor Toso +--- + src/vdagent/x11.c | 42 +++++++++++++++++++++--------------------- + 1 file changed, 21 insertions(+), 21 deletions(-) + +diff --git a/src/vdagent/x11.c b/src/vdagent/x11.c +index 61d7c69..42f42e7 100644 +--- a/src/vdagent/x11.c ++++ b/src/vdagent/x11.c +@@ -494,23 +494,23 @@ static int vdagent_x11_get_clipboard_selection(struct vdagent_x11 *x11, + } + #endif + +-static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event) ++static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent *event) + { + int i, handled = 0; + #ifndef WITH_GTK + uint8_t selection; + +- if (event.type == x11->xfixes_event_base) { ++ if (event->type == x11->xfixes_event_base) { + union { + XEvent ev; + XFixesSelectionNotifyEvent xfev; + } ev; + +- if (vdagent_x11_get_clipboard_selection(x11, &event, &selection)) { ++ if (vdagent_x11_get_clipboard_selection(x11, event, &selection)) { + return; + } + +- ev.ev = event; ++ ev.ev = *event; + switch (ev.xfev.subtype) { + case XFixesSetSelectionOwnerNotify: + break; +@@ -521,7 +521,7 @@ static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event) + break; + default: + VSELPRINTF("unexpected xfix event subtype %d window %d", +- (int)ev.xfev.subtype, (int)event.xany.window); ++ (int)ev.xfev.subtype, (int)event->xany.window); + return; + } + VSELPRINTF("New selection owner: %u", (unsigned int)ev.xfev.owner); +@@ -545,20 +545,20 @@ static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event) + } + #endif + +- if (vdagent_x11_randr_handle_event(x11, &event)) ++ if (vdagent_x11_randr_handle_event(x11, event)) + return; + +- switch (event.type) { ++ switch (event->type) { + case ConfigureNotify: + for (i = 0; i < x11->screen_count; i++) +- if (event.xconfigure.window == x11->root_window[i]) ++ if (event->xconfigure.window == x11->root_window[i]) + break; + if (i == x11->screen_count) + break; + + handled = 1; + vdagent_x11_randr_handle_root_size_change(x11, i, +- event.xconfigure.width, event.xconfigure.height); ++ event->xconfigure.width, event->xconfigure.height); + break; + case MappingNotify: + /* These are uninteresting */ +@@ -566,21 +566,21 @@ static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event) + break; + #ifndef WITH_GTK + case SelectionNotify: +- if (event.xselection.target == x11->targets_atom) +- vdagent_x11_handle_targets_notify(x11, &event); ++ if (event->xselection.target == x11->targets_atom) ++ vdagent_x11_handle_targets_notify(x11, event); + else +- vdagent_x11_handle_selection_notify(x11, &event, 0); ++ vdagent_x11_handle_selection_notify(x11, event, 0); + + handled = 1; + break; + case PropertyNotify: + if (x11->expect_property_notify && +- event.xproperty.state == PropertyNewValue) { +- vdagent_x11_handle_selection_notify(x11, &event, 1); ++ event->xproperty.state == PropertyNewValue) { ++ vdagent_x11_handle_selection_notify(x11, event, 1); + } + if (x11->selection_req_data && +- event.xproperty.state == PropertyDelete) { +- vdagent_x11_handle_property_delete_notify(x11, &event); ++ event->xproperty.state == PropertyDelete) { ++ vdagent_x11_handle_property_delete_notify(x11, event); + } + /* Always mark as handled, since we cannot unselect input for property + notifications once we are done with handling the incr transfer. */ +@@ -594,7 +594,7 @@ static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event) + case SelectionRequest: { + struct vdagent_x11_selection_request *req, *new_req; + +- if (vdagent_x11_get_clipboard_selection(x11, &event, &selection)) { ++ if (vdagent_x11_get_clipboard_selection(x11, event, &selection)) { + return; + } + +@@ -606,7 +606,7 @@ static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event) + + handled = 1; + +- new_req->event = event; ++ new_req->event = *event; + new_req->selection = selection; + new_req->next = NULL; + +@@ -628,7 +628,7 @@ static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event) + } + if (!handled && x11->debug) + syslog(LOG_DEBUG, "unhandled x11 event, type %d, window %d", +- (int)event.type, (int)event.xany.window); ++ (int)event->type, (int)event->xany.window); + } + + void vdagent_x11_do_read(struct vdagent_x11 *x11) +@@ -637,7 +637,7 @@ void vdagent_x11_do_read(struct vdagent_x11 *x11) + + while (XPending(x11->display)) { + XNextEvent(x11->display, &event); +- vdagent_x11_handle_event(x11, event); ++ vdagent_x11_handle_event(x11, &event); + } + } + +@@ -1370,7 +1370,7 @@ void vdagent_x11_clipboard_release(struct vdagent_x11 *x11, uint8_t selection) + XSync(x11->display, False); + while (XCheckTypedEvent(x11->display, x11->xfixes_event_base, + &event)) +- vdagent_x11_handle_event(x11, event); ++ vdagent_x11_handle_event(x11, &event); + + /* Note no need to do a set_clipboard_owner(owner_none) here, as that is + already done by processing the XFixesSetSelectionOwnerNotify event. */ +-- +2.21.0 + diff --git a/SOURCES/0007-x11-Constify-XEvent-argument.patch b/SOURCES/0007-x11-Constify-XEvent-argument.patch new file mode 100644 index 0000000..18e6426 --- /dev/null +++ b/SOURCES/0007-x11-Constify-XEvent-argument.patch @@ -0,0 +1,106 @@ +From af8d1948b1acc7baeb24f58efd52e5bbe9aa2441 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Wed, 19 Dec 2018 22:37:56 +0000 +Subject: [PATCH 7/9] x11: Constify XEvent argument + +No reasons to have it mutable. + +Signed-off-by: Frediano Ziglio +Acked-by: Victor Toso +--- + src/vdagent/x11.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +diff --git a/src/vdagent/x11.c b/src/vdagent/x11.c +index 42f42e7..966ea62 100644 +--- a/src/vdagent/x11.c ++++ b/src/vdagent/x11.c +@@ -59,12 +59,12 @@ int vdagent_x11_caught_error; + + #ifndef WITH_GTK + static void vdagent_x11_handle_selection_notify(struct vdagent_x11 *x11, +- XEvent *event, int incr); ++ const XEvent *event, int incr); + static void vdagent_x11_handle_selection_request(struct vdagent_x11 *x11); + static void vdagent_x11_handle_targets_notify(struct vdagent_x11 *x11, +- XEvent *event); ++ const XEvent *event); + static void vdagent_x11_handle_property_delete_notify(struct vdagent_x11 *x11, +- XEvent *del_event); ++ const XEvent *del_event); + static void vdagent_x11_send_selection_notify(struct vdagent_x11 *x11, + Atom prop, struct vdagent_x11_selection_request *request); + static void vdagent_x11_set_clipboard_owner(struct vdagent_x11 *x11, +@@ -465,12 +465,13 @@ static int vdagent_x11_get_clipboard_atom(struct vdagent_x11 *x11, uint8_t selec + } + + static int vdagent_x11_get_clipboard_selection(struct vdagent_x11 *x11, +- XEvent *event, uint8_t *selection) ++ const XEvent *event, uint8_t *selection) + { + Atom atom; + + if (event->type == x11->xfixes_event_base) { +- XFixesSelectionNotifyEvent *xfev = (XFixesSelectionNotifyEvent *)event; ++ const XFixesSelectionNotifyEvent *xfev = ++ (const XFixesSelectionNotifyEvent *)event; + atom = xfev->selection; + } else if (event->type == SelectionNotify) { + atom = event->xselection.selection; +@@ -494,7 +495,7 @@ static int vdagent_x11_get_clipboard_selection(struct vdagent_x11 *x11, + } + #endif + +-static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent *event) ++static void vdagent_x11_handle_event(struct vdagent_x11 *x11, const XEvent *event) + { + int i, handled = 0; + #ifndef WITH_GTK +@@ -650,7 +651,7 @@ static const char *vdagent_x11_get_atom_name(struct vdagent_x11 *x11, Atom a) + return XGetAtomName(x11->display, a); + } + +-static int vdagent_x11_get_selection(struct vdagent_x11 *x11, XEvent *event, ++static int vdagent_x11_get_selection(struct vdagent_x11 *x11, const XEvent *event, + uint8_t selection, Atom type, Atom prop, int format, + unsigned char **data_ret, int incr) + { +@@ -842,7 +843,7 @@ static void vdagent_x11_handle_conversion_request(struct vdagent_x11 *x11) + } + + static void vdagent_x11_handle_selection_notify(struct vdagent_x11 *x11, +- XEvent *event, int incr) ++ const XEvent *event, int incr) + { + int len = 0; + unsigned char *data = NULL; +@@ -927,7 +928,7 @@ static void vdagent_x11_print_targets(struct vdagent_x11 *x11, + } + + static void vdagent_x11_handle_targets_notify(struct vdagent_x11 *x11, +- XEvent *event) ++ const XEvent *event) + { + int i, len; + Atom atom, *atoms = NULL; +@@ -1026,7 +1027,7 @@ static void vdagent_x11_send_selection_notify(struct vdagent_x11 *x11, + } + + static void vdagent_x11_send_targets(struct vdagent_x11 *x11, +- uint8_t selection, XEvent *event) ++ uint8_t selection, const XEvent *event) + { + Atom prop, targets[256] = { x11->targets_atom, }; + int i, j, k, target_count = 1; +@@ -1123,7 +1124,7 @@ static void vdagent_x11_handle_selection_request(struct vdagent_x11 *x11) + } + + static void vdagent_x11_handle_property_delete_notify(struct vdagent_x11 *x11, +- XEvent *del_event) ++ const XEvent *del_event) + { + XEvent *sel_event; + int len; +-- +2.21.0 + diff --git a/SOURCES/0008-device-info-remove-g_list_length-on-compare_addresse.patch b/SOURCES/0008-device-info-remove-g_list_length-on-compare_addresse.patch new file mode 100644 index 0000000..590f6d5 --- /dev/null +++ b/SOURCES/0008-device-info-remove-g_list_length-on-compare_addresse.patch @@ -0,0 +1,264 @@ +From 66935d134e1f359eda5cfac053b0bf716811670a Mon Sep 17 00:00:00 2001 +From: Victor Toso +Date: Fri, 12 Jul 2019 11:12:36 +0200 +Subject: [PATCH 8/9] device-info: remove g_list_length() on + compare_addresses() + +The g_list_length() function does iterate over both lists to compare +its length. Considering that we use this to check for true/false and +we will iterate again on both lists, we can do so once. + +This also avoids covscan/clang warnings: + + | spice-vdagent-0.19.0/src/vdagent/device-info.c:216:27: warning: Access to field 'data' results in a dereference of a null pointer (loaded from variable 'lb') + | # PciDevice *devb = lb->data; + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:397:5: note: Taking false branch + | # if (!user_pci_addr) { + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:407:22: note: Calling 'find_device_at_pci_address' + | # char *dev_path = find_device_at_pci_address(user_pci_addr, &vendor_id, &device_id); + | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:329:5: note: Taking true branch + | # g_return_val_if_fail(pci_addr != NULL, NULL); + | # ^ + | /usr/include/glib-2.0/glib/gmessages.h:594:9: note: expanded from macro 'g_return_val_if_fail' + | # if G_LIKELY(expr) { } else \ + | # ^ + | /usr/include/glib-2.0/glib/gmacros.h:385:43: note: expanded from macro 'G_LIKELY' + | ##define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR((expr)), 1)) + | # ^ + | /usr/include/glib-2.0/glib/gmacros.h:379:4: note: expanded from macro '_G_BOOLEAN_EXPR' + | # if (expr) \ + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:329:5: note: Taking true branch + | /usr/include/glib-2.0/glib/gmessages.h:594:6: note: expanded from macro 'g_return_val_if_fail' + | # if G_LIKELY(expr) { } else \ + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:329:5: note: Loop condition is false. Exiting loop + | /usr/include/glib-2.0/glib/gmessages.h:593:40: note: expanded from macro 'g_return_val_if_fail' + | ##define g_return_val_if_fail(expr,val) G_STMT_START{ \ + | # ^ + | /usr/include/glib-2.0/glib/gmacros.h:346:23: note: expanded from macro 'G_STMT_START' + | ##define G_STMT_START do + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:330:5: note: Taking true branch + | # g_return_val_if_fail(device_id != NULL, NULL); + | # ^ + | /usr/include/glib-2.0/glib/gmessages.h:594:9: note: expanded from macro 'g_return_val_if_fail' + | # if G_LIKELY(expr) { } else \ + | # ^ + | /usr/include/glib-2.0/glib/gmacros.h:385:43: note: expanded from macro 'G_LIKELY' + | ##define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR((expr)), 1)) + | # ^ + | /usr/include/glib-2.0/glib/gmacros.h:379:4: note: expanded from macro '_G_BOOLEAN_EXPR' + | # if (expr) \ + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:330:5: note: Taking true branch + | /usr/include/glib-2.0/glib/gmessages.h:594:6: note: expanded from macro 'g_return_val_if_fail' + | # if G_LIKELY(expr) { } else \ + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:330:5: note: Loop condition is false. Exiting loop + | /usr/include/glib-2.0/glib/gmessages.h:593:40: note: expanded from macro 'g_return_val_if_fail' + | ##define g_return_val_if_fail(expr,val) G_STMT_START{ \ + | # ^ + | /usr/include/glib-2.0/glib/gmacros.h:346:23: note: expanded from macro 'G_STMT_START' + | ##define G_STMT_START do + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:331:5: note: Taking true branch + | # g_return_val_if_fail(vendor_id != NULL, NULL); + | # ^ + | /usr/include/glib-2.0/glib/gmessages.h:594:9: note: expanded from macro 'g_return_val_if_fail' + | # if G_LIKELY(expr) { } else \ + | # ^ + | /usr/include/glib-2.0/glib/gmacros.h:385:43: note: expanded from macro 'G_LIKELY' + | ##define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR((expr)), 1)) + | # ^ + | /usr/include/glib-2.0/glib/gmacros.h:379:4: note: expanded from macro '_G_BOOLEAN_EXPR' + | # if (expr) \ + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:331:5: note: Taking true branch + | /usr/include/glib-2.0/glib/gmessages.h:594:6: note: expanded from macro 'g_return_val_if_fail' + | # if G_LIKELY(expr) { } else \ + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:331:5: note: Loop condition is false. Exiting loop + | /usr/include/glib-2.0/glib/gmessages.h:593:40: note: expanded from macro 'g_return_val_if_fail' + | ##define g_return_val_if_fail(expr,val) G_STMT_START{ \ + | # ^ + | /usr/include/glib-2.0/glib/gmacros.h:346:23: note: expanded from macro 'G_STMT_START' + | ##define G_STMT_START do + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:334:5: note: Loop condition is true. Entering loop body + | # for (int i = 0; i < 10; ++i) { + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:340:13: note: Assuming the condition is false + | # if (stat(dev_path, &buf) != 0) { + | # ^~~~~~~~~~~~~~~~~~~~~~~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:340:9: note: Taking false branch + | # if (stat(dev_path, &buf) != 0) { + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:355:13: note: Assuming the condition is false + | # if (realpath(sys_path, device_link) == NULL) { + | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:355:9: note: Taking false branch + | # if (realpath(sys_path, device_link) == NULL) { + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:361:36: note: Calling 'parse_pci_address_from_sysfs_path' + | # PciAddress *drm_pci_addr = parse_pci_address_from_sysfs_path(device_link); + | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:129:9: note: Assuming 'pos' is non-null + | # if (!pos) { + | # ^~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:129:5: note: Taking false branch + | # if (!pos) { + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:136:9: note: Assuming 'pos' is non-null + | # if (!pos) { + | # ^~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:136:5: note: Taking false branch + | # if (!pos) { + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:142:9: note: Assuming 'pos' is non-null + | # if (!pos) { + | # ^~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:142:5: note: Taking false branch + | # if (!pos) { + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:146:27: note: Calling 'pci_address_new' + | # PciAddress *address = pci_address_new(); + | # ^~~~~~~~~~~~~~~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:61:12: note: Taking false branch + | # return g_new0(PciAddress, 1); + | # ^ + | /usr/include/glib-2.0/glib/gmem.h:279:42: note: expanded from macro 'g_new0' + | ##define g_new0(struct_type, n_structs) _G_NEW (struct_type, n_structs, malloc0) + | # ^ + | /usr/include/glib-2.0/glib/gmem.h:211:4: note: expanded from macro '_G_NEW' + | # if (__s == 1) \ + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:61:12: note: Left side of '&&' is false + | /usr/include/glib-2.0/glib/gmem.h:279:42: note: expanded from macro 'g_new0' + | ##define g_new0(struct_type, n_structs) _G_NEW (struct_type, n_structs, malloc0) + | # ^ + | /usr/include/glib-2.0/glib/gmem.h:213:40: note: expanded from macro '_G_NEW' + | # else if (__builtin_constant_p (__n) && \ + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:61:12: note: Null pointer value stored to field 'devices' + | # return g_new0(PciAddress, 1); + | # ^~~~~~~~~~~~~~~~~~~~~ + | /usr/include/glib-2.0/glib/gmem.h:279:42: note: expanded from macro 'g_new0' + | ##define g_new0(struct_type, n_structs) _G_NEW (struct_type, n_structs, malloc0) + | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | /usr/include/glib-2.0/glib/gmem.h:217:12: note: expanded from macro '_G_NEW' + | # __p = g_##func##_n (__n, __s); \ + | # ^~~~~~~~~~~~~~~~~~~~~~~ + | :76:1: note: expanded from here + | #g_malloc0_n + | #^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:146:27: note: Returning from 'pci_address_new' + | # PciAddress *address = pci_address_new(); + | # ^~~~~~~~~~~~~~~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:149:5: note: Loop condition is true. Entering loop body + | # while (pos) { + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:150:26: note: Taking false branch + | # PciDevice *dev = g_new0(PciDevice, 1); + | # ^ + | /usr/include/glib-2.0/glib/gmem.h:279:42: note: expanded from macro 'g_new0' + | ##define g_new0(struct_type, n_structs) _G_NEW (struct_type, n_structs, malloc0) + | # ^ + | /usr/include/glib-2.0/glib/gmem.h:211:4: note: expanded from macro '_G_NEW' + | # if (__s == 1) \ + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:150:26: note: Left side of '&&' is false + | /usr/include/glib-2.0/glib/gmem.h:279:42: note: expanded from macro 'g_new0' + | ##define g_new0(struct_type, n_structs) _G_NEW (struct_type, n_structs, malloc0) + | # ^ + | /usr/include/glib-2.0/glib/gmem.h:213:40: note: expanded from macro '_G_NEW' + | # else if (__builtin_constant_p (__n) && \ + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:152:9: note: Taking true branch + | # if (!parse_pci_device(pos + 1, next, dev)) { + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:154:13: note: Execution continues on line 159 + | # break; + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:361:36: note: Returning from 'parse_pci_address_from_sysfs_path' + | # PciAddress *drm_pci_addr = parse_pci_address_from_sysfs_path(device_link); + | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:362:9: note: Taking false branch + | # if (!drm_pci_addr) { + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:367:14: note: Calling 'compare_addresses' + | # if (!compare_addresses(pci_addr, drm_pci_addr)) { + | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:207:11: note: Assuming the condition is true + | # if (!(a->domain == b->domain + | # ^~~~~~~~~~~~~~~~~~~~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:207:11: note: Left side of '&&' is true + | spice-vdagent-0.19.0/src/vdagent/device-info.c:208:12: note: Assuming the condition is true + | # && g_list_length(a->devices) == g_list_length(b->devices))) { + | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:207:5: note: Taking false branch + | # if (!(a->domain == b->domain + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:212:35: note: 'lb' initialized to a null pointer value + | # for (GList *la = a->devices, *lb = b->devices; + | # ^~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:213:10: note: Assuming 'la' is not equal to NULL + | # la != NULL; + | # ^~~~~~~~~~ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:212:5: note: Loop condition is true. Entering loop body + | # for (GList *la = a->devices, *lb = b->devices; + | # ^ + | spice-vdagent-0.19.0/src/vdagent/device-info.c:216:27: note: Access to field 'data' results in a dereference of a null pointer (loaded from variable 'lb') + | # PciDevice *devb = lb->data; + | # ^~ + | # 214| la = la->next, lb = lb->next) { + | # 215| PciDevice *deva = la->data; + | # 216|-> PciDevice *devb = lb->data; + | # 217| + | # 218| if (deva->slot != devb->slot + +Signed-off-by: Victor Toso +Acked-by: Frediano Ziglio +--- + src/vdagent/device-info.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/src/vdagent/device-info.c b/src/vdagent/device-info.c +index 4983543..6b0e28f 100644 +--- a/src/vdagent/device-info.c ++++ b/src/vdagent/device-info.c +@@ -204,13 +204,13 @@ static PciAddress* parse_pci_address_from_spice(char *input) + static bool compare_addresses(PciAddress *a, PciAddress *b) + { + // only check domain, slot, and function +- if (!(a->domain == b->domain +- && g_list_length(a->devices) == g_list_length(b->devices))) { ++ if (a->domain != b->domain) { + return false; + } + +- for (GList *la = a->devices, *lb = b->devices; +- la != NULL; ++ const GList *la, *lb; ++ for (la = a->devices, lb = b->devices; ++ la != NULL && lb != NULL; + la = la->next, lb = lb->next) { + PciDevice *deva = la->data; + PciDevice *devb = lb->data; +@@ -220,7 +220,9 @@ static bool compare_addresses(PciAddress *a, PciAddress *b) + return false; + } + } +- return true; ++ ++ /* True only if both have the same length */ ++ return (la == NULL && lb == NULL); + } + + // Connector type names from xorg modesetting driver +-- +2.21.0 + diff --git a/SOURCES/0009-x11-Change-check-to-make-code-scanners-not-giving-wa.patch b/SOURCES/0009-x11-Change-check-to-make-code-scanners-not-giving-wa.patch new file mode 100644 index 0000000..274b73b --- /dev/null +++ b/SOURCES/0009-x11-Change-check-to-make-code-scanners-not-giving-wa.patch @@ -0,0 +1,54 @@ +From 0b94306d2c1305aee1c56bc9f927f95371484844 Mon Sep 17 00:00:00 2001 +From: Frediano Ziglio +Date: Sat, 20 Jul 2019 14:42:10 +0100 +Subject: [PATCH 9/9] x11: Change check to make code scanners not giving + warning + +Some code scanners (both Coverity and clang one) report that +prev_sel/prev_cond could be unreferenced while NULL. +Change condition to make clear a NULL pointer is not used. + +Signed-off-by: Frediano Ziglio +Acked-by: Victor Toso +--- + src/vdagent/x11.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/src/vdagent/x11.c b/src/vdagent/x11.c +index 966ea62..6f83849 100644 +--- a/src/vdagent/x11.c ++++ b/src/vdagent/x11.c +@@ -392,7 +392,7 @@ static void vdagent_x11_set_clipboard_owner(struct vdagent_x11 *x11, + once = 0; + } + vdagent_x11_send_selection_notify(x11, None, curr_sel); +- if (curr_sel == x11->selection_req) { ++ if (prev_sel == NULL) { + x11->selection_req = next_sel; + free(x11->selection_req_data); + x11->selection_req_data = NULL; +@@ -400,7 +400,6 @@ static void vdagent_x11_set_clipboard_owner(struct vdagent_x11 *x11, + x11->selection_req_data_size = 0; + x11->selection_req_atom = None; + } else { +- // coverity[var_deref_op] if it is not the first there's a previous + prev_sel->next = next_sel; + } + free(curr_sel); +@@ -424,12 +423,11 @@ static void vdagent_x11_set_clipboard_owner(struct vdagent_x11 *x11, + if (x11->vdagentd) + udscs_write(x11->vdagentd, VDAGENTD_CLIPBOARD_DATA, selection, + VD_AGENT_CLIPBOARD_NONE, NULL, 0); +- if (curr_conv == x11->conversion_req) { ++ if (prev_conv == NULL) { + x11->conversion_req = next_conv; + x11->clipboard_data_size = 0; + x11->expect_property_notify = 0; + } else { +- // coverity[var_deref_op] if it is not the first there's a previous + prev_conv->next = next_conv; + } + free(curr_conv); +-- +2.21.0 + diff --git a/SOURCES/0010-covscan-initialize-argv-s-copy.patch b/SOURCES/0010-covscan-initialize-argv-s-copy.patch new file mode 100644 index 0000000..38421f4 --- /dev/null +++ b/SOURCES/0010-covscan-initialize-argv-s-copy.patch @@ -0,0 +1,87 @@ +From c1a2ef0efed557a3c7808e491a6b2638666ecd9e Mon Sep 17 00:00:00 2001 +From: Victor Toso +Date: Mon, 26 Aug 2019 17:03:22 +0200 +Subject: [PATCH 10/11] covscan: initialize argv's copy + +Otherwise we get a CLANG_WARNING due accessing garbage. + +Covscan report: + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:471:9: warning: 1st function call argument is an uninitialized value + > # execvp(orig_argv[0], orig_argv); + > # ^ ~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:421:24: note: Storing uninitialized value + > # char **orig_argv = g_memdup(argv, sizeof(char*) * (argc+1)); + > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:434:9: note: Assuming 'error' is equal to NULL + > # if (error != NULL) { + > # ^~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:434:5: note: Taking false branch + > # if (error != NULL) { + > # ^ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:442:9: note: Assuming 'portdev' is not equal to NULL + > # if (portdev == NULL) + > # ^~~~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:442:5: note: Taking false branch + > # if (portdev == NULL) + > # ^ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:445:9: note: Assuming 'vdagentd_socket' is not equal to NULL + > # if (vdagentd_socket == NULL) + > # ^~~~~~~~~~~~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:445:5: note: Taking false branch + > # if (vdagentd_socket == NULL) + > # ^ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:448:30: note: Assuming 'do_daemonize' is 0 + > # openlog("spice-vdagent", do_daemonize ? LOG_PID : (LOG_PID | LOG_PERROR), + > # ^~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:448:30: note: '?' condition is false + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:451:9: note: Assuming the condition is false + > # if (!g_file_test(portdev, G_FILE_TEST_EXISTS)) { + > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:451:5: note: Taking false branch + > # if (!g_file_test(portdev, G_FILE_TEST_EXISTS)) { + > # ^ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:457:9: note: Assuming 'do_daemonize' is 0 + > # if (do_daemonize) + > # ^~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:457:5: note: Taking false branch + > # if (do_daemonize) + > # ^ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:468:9: note: Assuming 'version_mismatch' is not equal to 0 + > # if (version_mismatch) { + > # ^~~~~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:468:5: note: Taking true branch + > # if (version_mismatch) { + > # ^ + > spice-vdagent-0.19.0/src/vdagent/vdagent.c:471:9: note: 1st function call argument is an uninitialized value + > # execvp(orig_argv[0], orig_argv); + > # ^ ~~~~~~~~~~~~ + > # 469| syslog(LOG_INFO, "Version mismatch, restarting"); + > # 470| sleep(1); + > # 471|-> execvp(orig_argv[0], orig_argv); + > # 472| } + > # 473| + +Signed-off-by: Victor Toso +--- + src/vdagent/vdagent.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c +index 0e2e73e..5b146db 100644 +--- a/src/vdagent/vdagent.c ++++ b/src/vdagent/vdagent.c +@@ -418,7 +418,10 @@ int main(int argc, char *argv[]) + GOptionContext *context; + GError *error = NULL; + VDAgent *agent; +- char **orig_argv = g_memdup(argv, sizeof(char*) * (argc+1)); ++ char **orig_argv; ++ ++ orig_argv = g_memdup(argv, sizeof(char*) * (argc+1)); ++ orig_argv[argc] = NULL; + + context = g_option_context_new(NULL); + g_option_context_add_main_entries(context, entries, NULL); +-- +2.21.0 + diff --git a/SOURCES/0011-covscan-avoid-false-positive-on-g_clear_pointer.patch b/SOURCES/0011-covscan-avoid-false-positive-on-g_clear_pointer.patch new file mode 100644 index 0000000..a9b749e --- /dev/null +++ b/SOURCES/0011-covscan-avoid-false-positive-on-g_clear_pointer.patch @@ -0,0 +1,141 @@ +From fb30924e6f5c4e98aaa2c4e4d95b00b237289cb3 Mon Sep 17 00:00:00 2001 +From: Victor Toso +Date: Tue, 27 Aug 2019 10:59:30 +0200 +Subject: [PATCH 11/11] covscan: avoid false positive on g_clear_pointer() + +This is a CLANG_WARNING found by covscan. It is a false positive as +g_clear_pointer() does set vportp to NULL, meaning that the situation +described by covscan below should not be reached. Moving away from +g_clear_pointer() in this specific case just to make our tool happy. + +Covscan report: + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:458:9: warning: Use of memory after it is freed + > # if (wbuf->write_pos != wbuf->size) { + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:268:12: note: Assuming the condition is true + > # while (*vportp && (*vportp)->write_buf) + > # ^~~~~~~ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:268:12: note: Left side of '&&' is true + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:268:5: note: Loop condition is true. Entering loop body + > # while (*vportp && (*vportp)->write_buf) + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:269:9: note: Calling 'vdagent_virtio_port_do_write' + > # vdagent_virtio_port_do_write(vportp); + > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:453:5: note: Taking false branch + > # if (!wbuf) { + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:458:9: note: Assuming the condition is false + > # if (wbuf->write_pos != wbuf->size) { + > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:458:5: note: Taking false branch + > # if (wbuf->write_pos != wbuf->size) { + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:465:9: note: Assuming 'n' is < 0 + > # if (n < 0) { + > # ^~~~~ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:465:5: note: Taking true branch + > # if (n < 0) { + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:466:13: note: Assuming the condition is false + > # if (errno == EINTR) + > # ^~~~~~~~~~~~~~ + > /usr/include/errno.h:38:16: note: expanded from macro 'errno' + > ## define errno (*__errno_location ()) + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:466:9: note: Taking false branch + > # if (errno == EINTR) + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:469:9: note: Calling 'vdagent_virtio_port_destroy' + > # vdagent_virtio_port_destroy(vportp); + > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:130:5: note: Taking false branch + > # if (!vport) + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:133:9: note: Assuming the condition is false + > # if (vport->disconnect_callback) + > # ^~~~~~~~~~~~~~~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:133:5: note: Taking false branch + > # if (vport->disconnect_callback) + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:137:5: note: Loop condition is true. Entering loop body + > # while (wbuf) { + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:140:9: note: Memory is released + > # g_free(wbuf); + > # ^~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:137:5: note: Loop condition is false. Execution continues on line 144 + > # while (wbuf) { + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:144:5: note: Loop condition is true. Entering loop body + > # for (i = 0; i < VDP_END_PORT; i++) { + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:144:5: note: Loop condition is true. Entering loop body + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:144:5: note: Loop condition is true. Entering loop body + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:144:5: note: Loop condition is false. Execution continues on line 148 + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:149:5: note: Assuming '_p' is null + > # g_clear_pointer(vportp, g_free); + > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + > /usr/include/glib-2.0/glib/gmem.h:124:9: note: expanded from macro 'g_clear_pointer' + > # if (_p) \ + > # ^~ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:149:5: note: Taking false branch + > /usr/include/glib-2.0/glib/gmem.h:124:5: note: expanded from macro 'g_clear_pointer' + > # if (_p) \ + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:149:5: note: Loop condition is false. Exiting loop + > /usr/include/glib-2.0/glib/gmem.h:114:3: note: expanded from macro 'g_clear_pointer' + > # G_STMT_START { \ + > # ^ + > /usr/include/glib-2.0/glib/gmacros.h:346:23: note: expanded from macro 'G_STMT_START' + > ##define G_STMT_START do + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:469:9: note: Returning; memory was released + > # vdagent_virtio_port_destroy(vportp); + > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:269:9: note: Returning; memory was released + > # vdagent_virtio_port_do_write(vportp); + > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:268:12: note: Left side of '&&' is true + > # while (*vportp && (*vportp)->write_buf) + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:268:5: note: Loop condition is true. Entering loop body + > # while (*vportp && (*vportp)->write_buf) + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:269:9: note: Calling 'vdagent_virtio_port_do_write' + > # vdagent_virtio_port_do_write(vportp); + > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:453:5: note: Taking false branch + > # if (!wbuf) { + > # ^ + > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:458:9: note: Use of memory after it is freed + > # if (wbuf->write_pos != wbuf->size) { + > # ^~~~~~~~~~~~~~~ + > # 456| } + > # 457| + > # 458|-> if (wbuf->write_pos != wbuf->size) { + > # 459| syslog(LOG_ERR, "do_write: buffer is incomplete!!"); + > # 460| return; + +Signed-off-by: Victor Toso +--- + src/vdagentd/virtio-port.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/vdagentd/virtio-port.c b/src/vdagentd/virtio-port.c +index b0556ce..3ae7f22 100644 +--- a/src/vdagentd/virtio-port.c ++++ b/src/vdagentd/virtio-port.c +@@ -146,7 +146,8 @@ void vdagent_virtio_port_destroy(struct vdagent_virtio_port **vportp) + } + + close(vport->fd); +- g_clear_pointer(vportp, g_free); ++ g_free(vport); ++ *vportp = NULL; + } + + int vdagent_virtio_port_fill_fds(struct vdagent_virtio_port *vport, +-- +2.21.0 + diff --git a/SOURCES/spice-vdagent-0.19.0.tar.bz2.sig b/SOURCES/spice-vdagent-0.19.0.tar.bz2.sig new file mode 100644 index 0000000..b85d924 Binary files /dev/null and b/SOURCES/spice-vdagent-0.19.0.tar.bz2.sig differ diff --git a/SPECS/spice-vdagent.spec b/SPECS/spice-vdagent.spec index 02752b0..868bb3c 100644 --- a/SPECS/spice-vdagent.spec +++ b/SPECS/spice-vdagent.spec @@ -1,18 +1,30 @@ Name: spice-vdagent -Version: 0.18.0 +Version: 0.19.0 Release: 3%{?dist} Summary: Agent for Spice guests Group: Applications/System License: GPLv3+ URL: https://spice-space.org/ Source0: https://spice-space.org/download/releases/%{name}-%{version}.tar.bz2 -Patch00001: 0001-vdagent-Do-not-send-empty-screen-resolution-messages.patch -Patch00002: 0002-udscs-Avoid-file-descriptor-leak.patch -BuildRequires: git-core +Source1: https://spice-space.org/download/releases/%{name}-%{version}.tar.bz2.sig +Source2: victortoso-E37A484F.keyring +Patch0001: 0001-vdagent-fix-memory-leak-of-g_memdup.patch +Patch0002: 0002-x11-randr-use-glib-s-MAX-and-MIN.patch +Patch0003: 0003-x11-randr-simplest-fix-for-address-of-packed-member.patch +Patch0004: 0004-vdagent-simple-fix-for-address-of-packed-member.patch +Patch0005: 0005-x11-randr-Avoid-passing-XEvent-as-value.patch +Patch0006: 0006-x11-Avoid-passing-XEvent-as-value.patch +Patch0007: 0007-x11-Constify-XEvent-argument.patch +Patch0008: 0008-device-info-remove-g_list_length-on-compare_addresse.patch +Patch0009: 0009-x11-Change-check-to-make-code-scanners-not-giving-wa.patch +Patch0010: 0010-covscan-initialize-argv-s-copy.patch +Patch0011: 0011-covscan-avoid-false-positive-on-g_clear_pointer.patch + +BuildRequires: git-core gnupg2 BuildRequires: systemd-devel glib2-devel spice-protocol >= 0.12.13 BuildRequires: libpciaccess-devel libXrandr-devel libXinerama-devel BuildRequires: libXfixes-devel systemd desktop-file-utils libtool -BuildRequires: alsa-lib-devel dbus-devel +BuildRequires: alsa-lib-devel dbus-devel libdrm-devel %{?systemd_requires} %description @@ -29,6 +41,7 @@ Features: %prep +gpgv2 --quiet --keyring %{SOURCE2} %{SOURCE1} %{SOURCE0} %autosetup -S git_am #autoreconf -fi @@ -53,7 +66,7 @@ make install DESTDIR=$RPM_BUILD_ROOT V=2 %files -%doc COPYING ChangeLog README TODO +%doc COPYING CHANGELOG.md README.md /usr/lib/udev/rules.d/70-spice-vdagentd.rules %{_unitdir}/spice-vdagentd.service %{_unitdir}/spice-vdagentd.socket @@ -69,6 +82,19 @@ make install DESTDIR=$RPM_BUILD_ROOT V=2 %changelog +* Tue Aug 27 2019 Victor Toso 0.19.0-3 +- Fix two new covscan warnings + Resolves: rhbz#1660566 + +* Mon Aug 19 2019 Victor Toso 0.19.0-2 +- Fix some covscan warnings from latest build + Resolves: rhbz#1660566 + +* Mon May 20 2019 Victor Toso 0.19.0-1 +- Update to 0.19.0 + Resolves: rhbz#1711975 +- Validate tarball with gpg + * Tue Dec 18 2018 Victor Toso 0.18.0-3 - Fix leak of unix sockets. Resolves: rhbz#1660108