Skip to content

Commit 33a9e80

Browse files
authored
frontend: Disconnect dbus signals to avoid use-after-free (#90)
cpdbDeletePrinterObj() free's the struct passed to the GDBus signal handlers without making sure that these are not going to be called anymore. g_dbus_connection_close_sync() is not enough because there may have bene signals already received and awaiting to be dispatched in the next iteration of the mainloop.
1 parent 8d39193 commit 33a9e80

2 files changed

Lines changed: 13 additions & 3 deletions

File tree

cpdb/cpdb-frontend.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,15 @@ GDBusConnection *cpdbGetDbusConnection()
183183
void cpdbConnectToDBus(cpdb_frontend_obj_t *f)
184184
{
185185
GError *error = NULL;
186+
guint id;
186187

187188
if ((f->connection = cpdbGetDbusConnection()) == NULL)
188189
{
189190
loginfo("Couldn't connect to DBus\n");
190191
return;
191192
}
192193

193-
g_dbus_connection_signal_subscribe(f->connection,
194+
id = g_dbus_connection_signal_subscribe(f->connection,
194195
NULL, //Sender name
195196
"org.openprinting.PrintBackend", //Sender interface
196197
CPDB_SIGNAL_PRINTER_ADDED, //Signal name
@@ -200,8 +201,9 @@ void cpdbConnectToDBus(cpdb_frontend_obj_t *f)
200201
cpdbOnPrinterAdded, //callback
201202
f, //user_data
202203
NULL);
204+
f->dbus_subscriptions = g_slist_prepend(f->dbus_subscriptions, GUINT_TO_POINTER(id));
203205

204-
g_dbus_connection_signal_subscribe(f->connection,
206+
id = g_dbus_connection_signal_subscribe(f->connection,
205207
NULL, //Sender name
206208
"org.openprinting.PrintBackend", //Sender interface
207209
CPDB_SIGNAL_PRINTER_REMOVED, //Signal name
@@ -211,7 +213,9 @@ void cpdbConnectToDBus(cpdb_frontend_obj_t *f)
211213
cpdbOnPrinterRemoved, //callback
212214
f, //user_data
213215
NULL);
214-
g_dbus_connection_signal_subscribe(f->connection,
216+
f->dbus_subscriptions = g_slist_prepend(f->dbus_subscriptions, GUINT_TO_POINTER(id));
217+
218+
id = g_dbus_connection_signal_subscribe(f->connection,
215219
NULL, //Sender name
216220
"org.openprinting.PrintBackend", //Sender interface
217221
CPDB_SIGNAL_PRINTER_STATE_CHANGED, //Signal name
@@ -221,6 +225,7 @@ void cpdbConnectToDBus(cpdb_frontend_obj_t *f)
221225
cpdbOnPrinterStateChanged, //callback
222226
f, //user_data
223227
NULL);
228+
f->dbus_subscriptions = g_slist_prepend(f->dbus_subscriptions, GUINT_TO_POINTER(id));
224229

225230

226231
if (error)
@@ -250,6 +255,10 @@ void cpdbDisconnectFromDBus(cpdb_frontend_obj_t *f)
250255
logwarn("Already disconnected from DBus\n");
251256
return;
252257
}
258+
259+
for (GSList *sub = f->dbus_subscriptions; sub; sub = sub->next)
260+
g_dbus_connection_signal_unsubscribe (f->connection, GPOINTER_TO_UINT(sub->data));
261+
g_clear_pointer(&f->dbus_subscriptions, g_slist_free);
253262
g_hash_table_foreach(f->backend, stopListingLookup, NULL);
254263
g_dbus_connection_flush_sync(f->connection, NULL, NULL);
255264
g_dbus_connection_close_sync(f->connection, NULL, NULL);

cpdb/cpdb-frontend.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct cpdb_frontend_obj_s
8888
cpdb_settings_t *last_saved_settings; /** The last saved settings to disk */
8989

9090
GThread *background_thread;
91+
GSList *dbus_subscriptions;
9192
};
9293

9394
/**

0 commit comments

Comments
 (0)