[glib: 1/2] Fix possible integer overflow of g_socket_send_message()




commit 7197ad3c4006fc26a6438c9ec062c450dd2ea4a2
Author: Emmanuel Fleury <emmanuel fleury gmail com>
Date:   Tue Jan 12 00:11:20 2021 +0100

    Fix possible integer overflow of g_socket_send_message()
    
    The explanation of this bug has been mentioned in !1823, basically
    it fixes some possible integer overflow when message buffer size
    is more than G_MAXSSIZE.

 gio/gsocket.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)
---
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 69fc72825..b86eaab60 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -4754,6 +4754,11 @@ input_message_from_msghdr (const struct msghdr  *msg,
  * notified of a %G_IO_OUT condition. (On Windows in particular, this is
  * very common due to the way the underlying APIs work.)
  *
+ * Finally, it must be mentioned that the whole message buffer cannot
+ * exceed %G_MAXSSIZE, if the message can be more than this, then it
+ * is mandatory to use the g_socket_send_message_with_timeout()
+ * function.
+ *
  * On error -1 is returned and @error is set accordingly.
  *
  * Returns: Number of bytes written (which may be less than @size), or -1
@@ -4774,6 +4779,29 @@ g_socket_send_message (GSocket                *socket,
 {
   GPollableReturn res;
   gsize bytes_written = 0;
+  gsize vectors_size = 0;
+
+  for (gsize i = 0; i < num_vectors; i++)
+    {
+      /* No wrap-around for vectors_size */
+      if (vectors_size > vectors_size + vectors[i].size)
+        {
+          g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+                       _("Unable to send message: %s"),
+                       _("Message too large"));
+          return -1;
+        }
+
+      vectors_size += vectors[i].size;
+    }
+  /* Check if vectors buffers are too big for gssize */
+  if (vectors_size > G_MAXSSIZE)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+                   _("Unable to send message: %s"),
+                   _("Message too large"));
+      return -1;
+    }
 
   res = g_socket_send_message_with_timeout (socket, address,
                                             vectors, num_vectors,
@@ -4782,6 +4810,8 @@ g_socket_send_message (GSocket                *socket,
                                             &bytes_written,
                                             cancellable, error);
 
+  g_assert (res != G_POLLABLE_RETURN_OK || bytes_written <= G_MAXSSIZE);
+
   if (res == G_POLLABLE_RETURN_WOULD_BLOCK)
     {
 #ifndef G_OS_WIN32
@@ -4791,7 +4821,7 @@ g_socket_send_message (GSocket                *socket,
 #endif
     }
 
-  return res == G_POLLABLE_RETURN_OK ? bytes_written : -1;
+  return res == G_POLLABLE_RETURN_OK ? (gssize) bytes_written : -1;
 }
 
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]