]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
Handle over/underflows when reading from greeter
authorRobert Ancell <robert.ancell@canonical.com>
Mon, 18 Mar 2013 03:20:36 +0000 (16:20 +1300)
committerRobert Ancell <robert.ancell@canonical.com>
Mon, 18 Mar 2013 03:20:36 +0000 (16:20 +1300)
src/greeter.c

index 0e855b5ab726a95e39a1cee63892882d9a0a4f03..f3225b768455ae92d904ef3787744047b31fdc7e 100644 (file)
@@ -623,6 +623,24 @@ read_int (Greeter *greeter, gsize *offset)
     return value;
 }
 
+static int
+get_message_length (Greeter *greeter)
+{
+    gsize offset;
+    int payload_length;
+
+    offset = int_length ();
+    payload_length = read_int (greeter, &offset);
+
+    if (HEADER_SIZE + payload_length < HEADER_SIZE)
+    {
+        g_warning ("Payload length of %u octets too long", payload_length);
+        return 0;      
+    }
+
+    return HEADER_SIZE + payload_length;
+}
+
 static gchar *
 read_string_full (Greeter *greeter, gsize *offset, void* (*alloc_fn)(size_t n))
 {
@@ -680,8 +698,9 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
     n_to_read = HEADER_SIZE;
     if (greeter->priv->n_read >= HEADER_SIZE)
     {
-        offset = int_length ();
-        n_to_read += read_int (greeter, &offset);
+        n_to_read = get_message_length (greeter);
+        if (n_to_read == 0)
+            return FALSE;
     }
 
     status = g_io_channel_read_chars (greeter->priv->from_greeter_channel,
@@ -702,14 +721,13 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
     /* If have header, rerun for content */
     if (greeter->priv->n_read == HEADER_SIZE)
     {
-        gsize offset = int_length ();
-        n_to_read = read_int (greeter, &offset);
-        if (n_to_read > 0)
-        {
-            greeter->priv->read_buffer = secure_realloc (greeter, greeter->priv->read_buffer, HEADER_SIZE + n_to_read);
-            read_cb (source, condition, greeter);
-            return TRUE;
-        }
+        n_to_read = get_message_length (greeter);
+        if (n_to_read == 0)
+            return FALSE;
+
+        greeter->priv->read_buffer = secure_realloc (greeter, greeter->priv->read_buffer, n_to_read);
+        read_cb (source, condition, greeter);
+        return TRUE;
     }
   
     offset = 0;
@@ -740,6 +758,11 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
         break;
     case GREETER_MESSAGE_CONTINUE_AUTHENTICATION:
         n_secrets = read_int (greeter, &offset);
+        if (n_secrets + 1 < n_secrets)
+        {
+            g_warning ("Array length of %u elements too long", n_secrets);
+            return FALSE;
+        }
         secrets = g_malloc (sizeof (gchar *) * (n_secrets + 1));
         for (i = 0; i < n_secrets; i++)
             secrets[i] = read_secret (greeter, &offset);