summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Ancell <robert.ancell@canonical.com>2013-09-10 23:39:27 +0000
committerTarmac <>2013-09-10 23:39:27 +0000
commit485644fbbf16e84a7620997f42fb97b8bd9c8b0f (patch)
treea389996c70789bdec933ca212a58d5662e9e488c
parentd6dd9f60064f429f63b63eb749d603f9f83dacb3 (diff)
parent8d667243eb63f3891a49eea2c3495ff50736e069 (diff)
downloadlightdm-485644fbbf16e84a7620997f42fb97b8bd9c8b0f.tar.gz
For xauthority use open() with a mode instead of chmod() after the open that can be intercepted.
Approved by PS Jenkins bot, Robert Ancell.
-rw-r--r--src/x-authority.c72
1 files changed, 37 insertions, 35 deletions
diff --git a/src/x-authority.c b/src/x-authority.c
index e9b42f82..8e986fc0 100644
--- a/src/x-authority.c
+++ b/src/x-authority.c
@@ -14,6 +14,8 @@
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <fcntl.h>
+#include <glib/gstdio.h>
#include "x-authority.h"
@@ -210,26 +212,26 @@ read_string (gchar *data, gsize data_length, gsize *offset, gchar **value)
return read_data (data, data_length, offset, length, (guint8 **) value);
}
-static void
-write_uint16 (FILE *file, guint16 value)
+static gboolean
+write_uint16 (int fd, guint16 value)
{
guint8 v[2];
v[0] = value >> 8;
v[1] = value & 0xFF;
- fwrite (v, 2, 1, file);
+ return write (fd, v, 2) == 2;
}
-static void
-write_data (FILE *file, const guint8 *value, gsize value_length)
+static gboolean
+write_data (int fd, const guint8 *value, gsize value_length)
{
- fwrite (value, value_length, 1, file);
+ return write (fd, value, value_length) == value_length;
}
-static void
-write_string (FILE *file, const gchar *value)
+static gboolean
+write_string (int fd, const gchar *value)
{
- write_uint16 (file, strlen (value));
- write_data (file, (guint8 *) value, strlen (value));
+ size_t value_length = strlen (value);
+ return write_uint16 (fd, value_length) && write_data (fd, (guint8 *) value, value_length);
}
gboolean
@@ -239,9 +241,9 @@ x_authority_write (XAuthority *auth, XAuthWriteMode mode, const gchar *filename,
gsize input_length = 0, input_offset = 0;
GList *link, *records = NULL;
XAuthority *a;
- gboolean result;
+ gboolean result = TRUE;
gboolean matched = FALSE;
- FILE *output;
+ int output_fd;
g_return_val_if_fail (auth != NULL, FALSE);
g_return_val_if_fail (filename != NULL, FALSE);
@@ -313,47 +315,47 @@ x_authority_write (XAuthority *auth, XAuthWriteMode mode, const gchar *filename,
/* Write records back */
errno = 0;
- output = fopen (filename, "w");
- if (output == NULL)
+ output_fd = g_open (filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
+ if (output_fd < 0)
{
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
- "Failed to write X authority %s: %s",
- filename,
- g_strerror (errno));
- return FALSE;
- }
-
- /* Only allow the file to be read by this user */
- if (chmod (filename, S_IRUSR | S_IWUSR) != 0)
- {
- g_set_error (error,
- G_FILE_ERROR,
- g_file_error_from_errno (errno),
- "Failed to set permissions on X authority %s: %s",
+ "Failed to open X authority %s: %s",
filename,
g_strerror (errno));
return FALSE;
}
+ errno = 0;
for (link = records; link && result; link = link->next)
{
XAuthority *a = link->data;
- write_uint16 (output, a->priv->family);
- write_uint16 (output, a->priv->address_length);
- write_data (output, a->priv->address, a->priv->address_length);
- write_string (output, a->priv->number);
- write_string (output, a->priv->authorization_name);
- write_uint16 (output, a->priv->authorization_data_length);
- write_data (output, a->priv->authorization_data, a->priv->authorization_data_length);
+ result = write_uint16 (output_fd, a->priv->family) &&
+ write_uint16 (output_fd, a->priv->address_length) &&
+ write_data (output_fd, a->priv->address, a->priv->address_length) &&
+ write_string (output_fd, a->priv->number) &&
+ write_string (output_fd, a->priv->authorization_name) &&
+ write_uint16 (output_fd, a->priv->authorization_data_length) &&
+ write_data (output_fd, a->priv->authorization_data, a->priv->authorization_data_length);
g_object_unref (a);
}
g_list_free (records);
- fclose (output);
+ close (output_fd);
+
+ if (!result)
+ {
+ g_set_error (error,
+ G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "Failed to write X authority %s: %s",
+ filename,
+ g_strerror (errno));
+ return FALSE;
+ }
return TRUE;
}