kdbus: Do not use fstat() to determinte memfd size 01/105201/1
authorKarol Lewandowski <k.lewandowsk@samsung.com>
Thu, 15 Dec 2016 13:13:14 +0000 (14:13 +0100)
committerINSUN PYO <insun.pyo@samsung.com>
Fri, 16 Dec 2016 03:01:39 +0000 (19:01 -0800)
Memfd size is available via kdbus metadata so there is no need to use fstat.

This fixes failure on Smack system:

    [ 5352.471226] audit: type=1400 audit(946690155.785:99): lsm=SMACK fn=smack_inode_getattr action=denied subject="USER::server" object="USER::client" requested=r pid=13139 comm="gkdbus" path=2F6D656D66643A6B64627573202864656C657465642

Original idea by Insun Pyo <insun.pyo@samsung.com>

Change-Id: Ia7fe30c9604277d5ccf7cafedb0909a2c62b0d59

gio/gkdbus.c
glib/gbytes.c
glib/gbytes.h

index d0bd75e..8a2d2c7 100755 (executable)
@@ -2793,10 +2793,10 @@ g_kdbus_decode_dbus_msg (GKDBusWorker      *worker,
             const guchar *data;
             gsize size;
 
-            vector.gbytes = g_bytes_new_take_zero_copy_fd (item->memfd.fd);
+            vector.gbytes = g_bytes_new_take_zero_copy_fd_size (item->memfd.fd, item->memfd.size);
             data = g_bytes_get_data (vector.gbytes, &size);
 
-            g_assert (item->memfd.start + item->memfd.size <= size);
+            g_assert (item->memfd.size == size);
 
             vector.data.pointer = data + item->memfd.start;
             vector.size = item->memfd.size;
index b087b1b..e8de538 100644 (file)
@@ -186,7 +186,6 @@ g_bytes_new (gconstpointer data,
  *
  * Returns: (transfer full): a new #GBytes
  *
- * Since: 2.44
  */
 #ifdef G_OS_UNIX
 GBytes *
@@ -195,20 +194,34 @@ g_bytes_new_take_zero_copy_fd (gint fd)
   GBytesData *bytes;
   struct stat buf;
 
-  g_return_val_if_fail_se (g_unix_fd_ensure_zero_copy_safe (fd), NULL);
-
   /* We already checked this is a memfd... */
   g_assert_se (fstat (fd, &buf) == 0);
 
+  bytes = g_bytes_new_take_zero_copy_fd_size(fd, buf.st_size);
+
   if (buf.st_size == 0)
     {
       g_assert_se (close (fd) == 0);
+    }
+
+  return (GBytes *) bytes;
+}
 
+GBytes *
+g_bytes_new_take_zero_copy_fd_size (gint fd, gsize size)
+{
+  GBytesData *bytes;
+
+  g_return_val_if_fail_se (g_unix_fd_ensure_zero_copy_safe (fd), NULL);
+
+  /* We already checked this is a memfd... */
+  if (size == 0)
+    {
       return g_bytes_new (NULL, 0);
     }
 
-  bytes = g_bytes_allocate (sizeof (GBytesData), fd, buf.st_size);
-  bytes->data = mmap (NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+  bytes = g_bytes_allocate (sizeof (GBytesData), fd, size);
+  bytes->data = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
   if (bytes->data == MAP_FAILED)
     /* this is similar to malloc() failing, so do the same... */
     g_error ("mmap() on memfd failed: %s\n", g_strerror (errno));
index 16f38aa..a53f581 100644 (file)
@@ -42,6 +42,10 @@ GBytes *        g_bytes_new_take                (gpointer        data,
 #ifdef G_OS_UNIX
 GLIB_AVAILABLE_IN_2_44
 GBytes *        g_bytes_new_take_zero_copy_fd   (gint            fd);
+
+GLIB_AVAILABLE_IN_2_44
+GBytes *        g_bytes_new_take_zero_copy_fd_size (gint fd,
+                                                    gsize           size);
 #endif
 
 GLIB_AVAILABLE_IN_ALL