summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2013-11-06 20:14:50 +0100
committerMarc-André Lureau <marcandre.lureau@redhat.com>2013-11-19 15:33:27 +0100
commitbc2139629a57b6ff4567c4194e24f58191361a2a (patch)
tree1bd3555ad5da24c4c6031af4d5d6b41f8dc903c4
parent4642a31a1e5c4c0a68398fd51549f1e6c4146d9f (diff)
Block sending clipboard data > max-clipboard
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.
-rw-r--r--gtk/channel-main.c28
-rw-r--r--gtk/spice-gtk-session.c9
2 files changed, 34 insertions, 3 deletions
diff --git a/gtk/channel-main.c b/gtk/channel-main.c
index 24f7428..d4b4416 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);