From: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> Attempt to send very large clipboard data may easy cause OOM abort, either in gdk - some patch are proposed to improve the situation, or in spice-gtk itself. Let's have a property that blocks unreasonably big clipboard data from being processed (by default 100mb). Users willing to send larger data can use the send basic drag-drop send file instead, or tweak the property value. --- gtk/channel-main.c | 28 ++++++++++++++++++++++++++++ gtk/spice-gtk-session.c | 9 ++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/gtk/channel-main.c b/gtk/channel-main.c index 5c33e67..dbcaff8 100644 --- a/gtk/channel-main.c +++ b/gtk/channel-main.c @@ -106,6 +106,7 @@ struct _SpiceMainChannelPrivate { guint switch_host_delayed_id; guint migrate_delayed_id; spice_migrate *migrate_data; + int max_clipboard; }; struct spice_migrate { @@ -137,6 +138,7 @@ enum { PROP_DISPLAY_COLOR_DEPTH, PROP_DISABLE_DISPLAY_POSITION, PROP_DISABLE_DISPLAY_ALIGN, + PROP_MAX_CLIPBOARD, }; /* Signals */ @@ -253,6 +255,9 @@ static void spice_main_get_property(GObject *object, case PROP_DISABLE_DISPLAY_ALIGN: g_value_set_boolean(value, c->disable_display_align); break; + case PROP_MAX_CLIPBOARD: + g_value_set_int(value, c->max_clipboard); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -286,6 +291,9 @@ static void spice_main_set_property(GObject *gobject, guint prop_id, case PROP_DISABLE_DISPLAY_ALIGN: c->disable_display_align = g_value_get_boolean(value); break; + case PROP_MAX_CLIPBOARD: + c->max_clipboard = g_value_get_int(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); break; @@ -512,6 +520,24 @@ static void spice_main_channel_class_init(SpiceMainChannelClass *klass) G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + /** + * SpiceMainChannel:max-clipboard: + * + * Maximum size of clipboard operations in bytes (default 100MB, + * -1 for unlimited size); + * + * Since: 0.22 + **/ + g_object_class_install_property + (gobject_class, PROP_MAX_CLIPBOARD, + g_param_spec_int("max-clipboard", + "max clipboard", + "Maximum clipboard data size", + -1, G_MAXINT, 100 * 1024 * 1024, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + /* TODO use notify instead */ /** * SpiceMainChannel::main-mouse-update: @@ -1246,6 +1272,8 @@ static void agent_clipboard_notify(SpiceMainChannel *channel, guint selection, g_return_if_fail(VD_AGENT_HAS_CAPABILITY(c->agent_caps, G_N_ELEMENTS(c->agent_caps), VD_AGENT_CAP_CLIPBOARD_BY_DEMAND)); + g_return_if_fail(c->max_clipboard == -1 || size < c->max_clipboard); + msgsize = sizeof(VDAgentClipboard); if (HAS_CLIPBOARD_SELECTION(c)) msgsize += 4; diff --git a/gtk/spice-gtk-session.c b/gtk/spice-gtk-session.c index 71ed300..eab7e2f 100644 --- a/gtk/spice-gtk-session.c +++ b/gtk/spice-gtk-session.c @@ -748,16 +748,19 @@ static void clipboard_received_cb(GtkClipboard *clipboard, gchar* name; GdkAtom atom; int selection; + int max_clipboard; selection = get_selection_from_clipboard(s, clipboard); g_return_if_fail(selection != -1); + g_object_get(s->main, "max-clipboard", &max_clipboard, NULL); len = gtk_selection_data_get_length(selection_data); - if (len == -1) { + if (len == 0 || (max_clipboard != -1 && len > max_clipboard)) { + g_warning("discarded clipboard of size %d (max: %d)", len, max_clipboard); + return; + } else if (len == -1) { SPICE_DEBUG("empty clipboard"); len = 0; - } else if (len == 0) { - SPICE_DEBUG("TODO: what should be done here?"); } else { atom = gtk_selection_data_get_data_type(selection_data); name = gdk_atom_name(atom); -- 1.8.3.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel