From f9967d24d1e20cf2640fb4917c21614903f07427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gl=C3=A4=C3=9Fle?= Date: Mon, 6 Jul 2015 18:04:42 +0200 Subject: [PATCH] Change udisks_spawned_job_new:input_string param to GString --- src/udisksdaemon.c | 7 +++++- src/udisksspawnedjob.c | 68 +++++++++++++++++++++++++++++++++++++++----------- src/udisksspawnedjob.h | 4 ++- 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/src/udisksdaemon.c b/src/udisksdaemon.c index 1910596..1ba0047 100644 --- a/src/udisksdaemon.c +++ b/src/udisksdaemon.c @@ -651,16 +651,21 @@ udisks_daemon_launch_spawned_job (UDisksDaemon *daemon, UDisksSpawnedJob *job; UDisksObjectSkeleton *job_object; gchar *job_object_path; + GString *input_string_as_gstring = NULL; g_return_val_if_fail (UDISKS_IS_DAEMON (daemon), NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (command_line_format != NULL, NULL); + if (input_string != NULL) + input_string_as_gstring = g_string_new (input_string); + va_start (var_args, command_line_format); command_line = g_strdup_vprintf (command_line_format, var_args); va_end (var_args); - job = udisks_spawned_job_new (command_line, input_string, run_as_uid, run_as_euid, daemon, cancellable); + job = udisks_spawned_job_new (command_line, input_string_as_gstring, run_as_uid, run_as_euid, daemon, cancellable); g_free (command_line); + udisks_string_wipe_and_free(input_string_as_gstring); if (object != NULL) udisks_base_job_add_object (UDISKS_BASE_JOB (job), object); diff --git a/src/udisksspawnedjob.c b/src/udisksspawnedjob.c index ba8b2d4..9a5ffbd 100644 --- a/src/udisksspawnedjob.c +++ b/src/udisksspawnedjob.c @@ -34,6 +34,7 @@ #include "udisksspawnedjob.h" #include "udisks-daemon-marshal.h" #include "udisksdaemon.h" +#include "udisksdaemonutil.h" /** * SECTION:udisksspawnedjob @@ -130,6 +131,15 @@ static void udisks_spawned_job_release_resources (UDisksSpawnedJob *job); G_DEFINE_TYPE_WITH_CODE (UDisksSpawnedJob, udisks_spawned_job, UDISKS_TYPE_BASE_JOB, G_IMPLEMENT_INTERFACE (UDISKS_TYPE_JOB, job_iface_init)); +typedef GString AutowipeBuffer; +static GType autowipe_buffer_get_type (void); +static void autowipe_buffer_free (gpointer data); +static gpointer autowipe_buffer_copy (gpointer data); + +G_DEFINE_BOXED_TYPE (AutowipeBuffer, autowipe_buffer, + autowipe_buffer_copy, + autowipe_buffer_free); + static void udisks_spawned_job_finalize (GObject *object) { @@ -142,12 +152,8 @@ udisks_spawned_job_finalize (GObject *object) g_free (job->command_line); - /* input string may contain key material - nuke contents */ if (job->input_string != NULL) - { - memset (job->input_string->str, '\0', job->input_string->len); - g_string_free(job->input_string, TRUE); - } + g_boxed_free(autowipe_buffer_get_type(), (gpointer) job->input_string); if (G_OBJECT_CLASS (udisks_spawned_job_parent_class)->finalize != NULL) G_OBJECT_CLASS (udisks_spawned_job_parent_class)->finalize (object); @@ -180,7 +186,6 @@ udisks_spawned_job_set_property (GObject *object, GParamSpec *pspec) { UDisksSpawnedJob *job = UDISKS_SPAWNED_JOB (object); - const gchar* str; switch (prop_id) { @@ -191,11 +196,11 @@ udisks_spawned_job_set_property (GObject *object, case PROP_INPUT_STRING: g_assert (job->input_string == NULL); - str = g_value_get_string (value); - if (str != NULL) { - job->input_string = g_string_new (str); - job->input_string_cursor = job->input_string->str; - } + job->input_string = (GString*) g_value_dup_boxed(value); + if (job->input_string != NULL) + { + job->input_string_cursor = job->input_string->str; + } break; case PROP_RUN_AS_UID: @@ -601,13 +606,16 @@ udisks_spawned_job_class_init (UDisksSpawnedJobClass *klass) * * String that will be written to stdin of the spawned program or * %NULL to not write anything. + * + * This is passed as autowipe_buffer (rather than G_TYPE_GSTRING) to nuke + * the contents after usage since the input string may contain key material. */ g_object_class_install_property (gobject_class, PROP_INPUT_STRING, - g_param_spec_string ("input-string", + g_param_spec_boxed ("input-string", "Input String", "String to write to stdin of the spawned program", - NULL, + autowipe_buffer_get_type(), G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); @@ -706,7 +714,7 @@ udisks_spawned_job_class_init (UDisksSpawnedJobClass *klass) */ UDisksSpawnedJob * udisks_spawned_job_new (const gchar *command_line, - const gchar *input_string, + GString *input_string, uid_t run_as_uid, uid_t run_as_euid, UDisksDaemon *daemon, @@ -997,3 +1005,35 @@ udisks_spawned_job_release_resources (UDisksSpawnedJob *job) } } + +/* manage strings with potentially unsafe content */ + +void udisks_string_wipe_and_free(GString* string) +{ + if (string != NULL) + { + memset (string->str, '\0', string->len); + g_string_free(string, TRUE); + } +} + +static gpointer +autowipe_buffer_copy (gpointer data) +{ + GString *orig = (GString*) data; + GString *copy = NULL; + + if (orig != NULL) + { + copy = g_string_new_len (orig->str, orig->len); + } + + return (gpointer) copy; +} + +static void +autowipe_buffer_free (gpointer data) +{ + GString *string = (GString*) data; + udisks_string_wipe_and_free(string); +} diff --git a/src/udisksspawnedjob.h b/src/udisksspawnedjob.h index 311931a..e239e39 100644 --- a/src/udisksspawnedjob.h +++ b/src/udisksspawnedjob.h @@ -31,13 +31,15 @@ G_BEGIN_DECLS GType udisks_spawned_job_get_type (void) G_GNUC_CONST; UDisksSpawnedJob *udisks_spawned_job_new (const gchar *command_line, - const gchar *input_string, + GString *input_string, uid_t run_as_uid, uid_t run_as_euid, UDisksDaemon *daemon, GCancellable *cancellable); const gchar *udisks_spawned_job_get_command_line (UDisksSpawnedJob *job); +void udisks_string_wipe_and_free(GString*); + G_END_DECLS #endif /* __UDISKS_SPAWNED_JOB_H__ */ -- 2.10.2