summaryrefslogtreecommitdiff
path: root/liblightdm-gobject
diff options
context:
space:
mode:
authorMichael Terry <michael.terry@canonical.com>2012-04-02 11:34:53 -0400
committerMichael Terry <michael.terry@canonical.com>2012-04-02 11:34:53 -0400
commite5d9af2d4b7ce01b02d5ff2dc0ffbcb7f85b65dc (patch)
tree323378f91f3602dfd006f7b4c89164e670add4ef /liblightdm-gobject
parentb351b1bbe5be5f28492e1609b1ade8d60395851c (diff)
downloadlightdm-e5d9af2d4b7ce01b02d5ff2dc0ffbcb7f85b65dc.tar.gz
refuse to write malformed packets to lightdm daemon
Diffstat (limited to 'liblightdm-gobject')
-rw-r--r--liblightdm-gobject/greeter.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/liblightdm-gobject/greeter.c b/liblightdm-gobject/greeter.c
index ff129dc2..0a603240 100644
--- a/liblightdm-gobject/greeter.c
+++ b/liblightdm-gobject/greeter.c
@@ -121,22 +121,6 @@ int_length ()
}
static void
-write_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
-{
- LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
- GIOStatus status;
- GError *error = NULL;
-
- status = g_io_channel_write_chars (priv->to_server_channel, (gchar *) message, message_length, NULL, &error);
- if (error)
- g_warning ("Error writing to daemon: %s", error->message);
- g_clear_error (&error);
- if (status == G_IO_STATUS_NORMAL)
- g_debug ("Wrote %zi bytes to daemon", message_length);
- g_io_channel_flush (priv->to_server_channel, NULL);
-}
-
-static void
write_int (guint8 *buffer, gint buffer_length, guint32 value, gsize *offset)
{
if (*offset + 4 >= buffer_length)
@@ -226,6 +210,35 @@ get_message_length (guint8 *message, gsize message_length)
}
static void
+write_message (LightDMGreeter *greeter, guint8 *message, gsize message_length)
+{
+ LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
+ GIOStatus status;
+ GError *error = NULL;
+ guint32 stated_length;
+
+ /* Double check that we're sending well-formed messages. If we say we're
+ sending more than we do, we end up DOS'ing lightdm as it waits for the
+ rest. If we say we're sending less than we do, we confuse the heck out
+ of lightdm, as it starts reading headers from the middle of our
+ messages. */
+ stated_length = HEADER_SIZE + get_message_length (message, message_length);
+ if (stated_length != message_length)
+ {
+ g_warning ("Refusing to write malformed packet to daemon: declared size is %u, but actual size is %zu", stated_length, message_length);
+ return;
+ }
+
+ status = g_io_channel_write_chars (priv->to_server_channel, (gchar *) message, message_length, NULL, &error);
+ if (error)
+ g_warning ("Error writing to daemon: %s", error->message);
+ g_clear_error (&error);
+ if (status == G_IO_STATUS_NORMAL)
+ g_debug ("Wrote %zi bytes to daemon", message_length);
+ g_io_channel_flush (priv->to_server_channel, NULL);
+}
+
+static void
handle_connected (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
{
LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);