After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 733485 - Crashes after typing screen lock password
Crashes after typing screen lock password
Status: RESOLVED FIXED
Product: gdm
Classification: Core
Component: general
3.12.x
Other Linux
: Normal blocker
: ---
Assigned To: GDM maintainers
GDM maintainers
Depends on:
Blocks:
 
 
Reported: 2014-07-21 09:21 UTC by Bastien Nocera
Modified: 2014-07-22 15:31 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
daemon: Fix crash when typing password at screen lock (1.83 KB, patch)
2014-07-21 16:22 UTC, Bastien Nocera
needs-work Details | Review
daemon: Fix crash when typing password at screen lock (1.68 KB, patch)
2014-07-21 22:07 UTC, Bastien Nocera
accepted-commit_now Details | Review
daemon: Fix crash when typing password at screen lock (1.77 KB, patch)
2014-07-22 15:29 UTC, Bastien Nocera
committed Details | Review

Description Bastien Nocera 2014-07-21 09:21:12 UTC
gdm-3.12.2-2.fc21.x86_64

gdm crashes after typing my screen lock password.

  • #0 g_type_check_instance_is_fundamentally_a
    at gtype.c line 3977
  • #1 g_object_unref
    at gobject.c line 3067
  • #2 g_hash_table_remove_internal
    at ghash.c line 1300
  • #3 ffi_call_unix64
  • #4 ffi_call
  • #5 g_cclosure_marshal_generic_va
    at gclosure.c line 1541
  • #6 _g_closure_invoke_va
    at gclosure.c line 831
  • #7 g_signal_emit_valist
    at gsignal.c line 3218
  • #8 g_signal_emit
    at gsignal.c line 3365
  • #9 on_reauthentication_started_cb
    at gdm-session.c line 889
  • #10 g_simple_async_result_complete
    at gsimpleasyncresult.c line 763
  • #11 reply_cb
    at gdbusproxy.c line 2623
  • #12 g_simple_async_result_complete
    at gsimpleasyncresult.c line 763
  • #13 g_dbus_connection_call_done
    at gdbusconnection.c line 5508
  • #14 g_simple_async_result_complete
    at gsimpleasyncresult.c line 763
  • #15 complete_in_idle_cb
    at gsimpleasyncresult.c line 775
  • #16 g_main_context_dispatch
    at gmain.c line 3064
  • #17 g_main_context_dispatch
    at gmain.c line 3663
  • #18 g_main_context_iterate
    at gmain.c line 3734
  • #19 g_main_loop_run
    at gmain.c line 3928
  • #20 main
    at main.c line 413

Comment 1 Bastien Nocera 2014-07-21 16:22:45 UTC
Created attachment 281325 [details] [review]
daemon: Fix crash when typing password at screen lock

open_reauthentication_requests is a hashtable which contains
GDBusMethodInvocations as values. We insert them in the hashtable with
only one reference, the one coming from the D-Bus method call.

But when a reauthentication starts,
gdm_dbus_manager_complete_open_reauthentication_channel() is called
which internally calls g_dbus_method_invocation_return_value().
This will eat the only reference, and we'll then try to remove the
invocation from the hash table, unref'ing a dead object.

Instead, remove the invocation from the hashtable without unref'ing
(once too much).
Comment 2 Bastien Nocera 2014-07-21 16:44:14 UTC
Tested on top of Fedora 21's gdm package, and it fixes the crash for me.
Comment 3 Ray Strode [halfline] 2014-07-21 19:19:02 UTC
Review of attachment 281325 [details] [review]:

Hey thanks for this.

::: daemon/gdm-manager.c
@@ +1802,3 @@
+        } else {
+                g_hash_table_remove (manager->priv->open_reauthentication_requests,
+                                     source_tag);

So I'm not sure this is right, you steal if the look up succeeds but remove if the lookup fails.  If it fails, though, then remove is going to be a noop! So, the remove call added here is dead code.  You could just always steal, but then the question is, why are we using a destroy function to unref when removing from the hash table if we're just going to steal instead of remove? I think one of these two fixes is more right than the above fix:

1) don't pass g_object_unref to g_hash_table_new_full
2) ref the invocation request when inserting it

Either way seems like it should work.
Comment 4 Bastien Nocera 2014-07-21 22:07:09 UTC
(In reply to comment #3)
<snip>
> 1) don't pass g_object_unref to g_hash_table_new_full
> 2) ref the invocation request when inserting it

No, because you want all the pending invocations to be deleted/cancelled/unref'ed when finalizing the object. Just stealing is probably fine, or we could remove the unref as a destructor, get all the values on finalize, and unref them one-by-one.
Comment 5 Bastien Nocera 2014-07-21 22:07:31 UTC
Created attachment 281351 [details] [review]
daemon: Fix crash when typing password at screen lock

open_reauthentication_requests is a hashtable which contains
GDBusMethodInvocations as values. We insert them in the hashtable with
only one reference, the one coming from the D-Bus method call.

But when a reauthentication starts,
gdm_dbus_manager_complete_open_reauthentication_channel() is called
which internally calls g_dbus_method_invocation_return_value().
This will eat the only reference, and we'll then try to remove the
invocation from the hash table, unref'ing a dead object.

Instead, remove the invocation from the hashtable without unref'ing
(once too much).
Comment 6 Ray Strode [halfline] 2014-07-22 15:25:13 UTC
Review of attachment 281351 [details] [review]:

looks good. thanks, agin. i'd do one minor tweak..

::: daemon/gdm-manager.c
@@ +1799,3 @@
                                                                          address);
+                g_hash_table_steal (manager->priv->open_reauthentication_requests,
+                                    source_tag);

I'd put this above the complete call.  it doesn't matter in practice because we aren't dereferencing the pointer, but it reads better (in my mind anyway)
Comment 7 Bastien Nocera 2014-07-22 15:29:53 UTC
Created attachment 281398 [details] [review]
daemon: Fix crash when typing password at screen lock

open_reauthentication_requests is a hashtable which contains
GDBusMethodInvocations as values. We insert them in the hashtable with
only one reference, the one coming from the D-Bus method call.

But when a reauthentication starts,
gdm_dbus_manager_complete_open_reauthentication_channel() is called
which internally calls g_dbus_method_invocation_return_value().
This will eat the only reference, and we'll then try to remove the
invocation from the hash table, unref'ing a dead object.

Instead, remove the invocation from the hashtable without unref'ing
(once too much).
Comment 8 Bastien Nocera 2014-07-22 15:31:20 UTC
Attachment 281398 [details] pushed as 52e5154 - daemon: Fix crash when typing password at screen lock