|
Bugzilla – Full Text Bug Listing |
| Summary: | nautilus dumps core in gtk_widget_get_sensitive() after bad password input | ||
|---|---|---|---|
| Product: | [openSUSE] openSUSE Distribution | Reporter: | Martin Wilck <martin.wilck> |
| Component: | GNOME | Assignee: | Martin Wilck <martin.wilck> |
| Status: | RESOLVED FIXED | QA Contact: | E-mail List <qa-bugs> |
| Severity: | Normal | ||
| Priority: | P5 - None | CC: | gnome-bugs, yfjiang |
| Version: | Leap 15.4 | ||
| Target Milestone: | --- | ||
| Hardware: | Other | ||
| OS: | Other | ||
| Whiteboard: | |||
| Found By: | --- | Services Priority: | |
| Business Priority: | Blocker: | --- | |
| Marketing QA Status: | --- | IT Deployment: | --- |
| Attachments: | proposed patch | ||
The pattern 0xaaaaaaaaaaaaaaaa is written when a widget is destroyed. So this is a use-after-free: the list operation->priv->user_widgets is not cleared, but it the elements point to already-freed widgets. Created attachment 867371 [details]
proposed patch
The code that I change here is ancient. No idea why this is hitting me now.
Jiang, please have a look. The patch from comment 2 fixes the issue for me. I've created a branch with the fix in https://build.suse.de/package/show/home:mwilck:branches:SUSE:SLE-15-SP4:Update/gtk3 Upstream merge request: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6049 The upstream MR has been merged. The problem has already been fixed (with basically the same patch) in GTK 4.7.2: https://gitlab.gnome.org/GNOME/gtk/-/commit/111929593aa995c3286b84ad118280357cfe6bdd (In reply to Martin Wilck from comment #3) > Jiang, please have a look. The patch from comment 2 fixes the issue for me. Hello Martin, Thanks! This looks a pretty safe fix to me. Could you please submit it to GNOME:STABLE:41 on OBS, which is our devel branch for 15SP4:Update. I will review, accept and forward it to 15SP4:Update. sr#1090886 |
nautilus crashes reproducably after trying to access an SMB share. steps to reproduce: ask nautilus to access SMB share. Click "Connect As → Registered User", enter wrong password, click "Connect". The crash happens when nautilus tries to display the login prompt again. (gdb) bt #0 0x00007fe31dc37a3d in gtk_widget_set_sensitive (widget=0x55696558a720, sensitive=0) at gtkwidget.c:9515 #1 0x00007fe31db05ba6 in pw_dialog_anonymous_toggled (widget=<optimized out>, operation=<optimized out>) at gtkmountoperation.c:474 #2 0x00007fe31c55f973 in g_closure_invoke (closure=0x55696502e830, return_value=0x0, n_param_values=1, param_values=0x7ffd0585dd20, invocation_hint=0x7ffd0585dca0) at ../gobject/gclosure.c:830 #3 0x00007fe31c573a7e in signal_emit_unlocked_R (node=node@entry=0x556964c0c170, detail=detail@entry=0, instance=instance@entry=0x55696524fe00, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7ffd0585dd20) at ../gobject/gsignal.c:3742 #4 0x00007fe31c57d684 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7ffd0585def0) at ../gobject/gsignal.c:3497 #5 0x00007fe31c57e11f in g_signal_emit (instance=<optimized out>, signal_id=<optimized out>, detail=detail@entry=0) at ../gobject/gsignal.c:3553 #6 0x00007fe31dbd5f6d in gtk_toggle_button_toggled (toggle_button=<optimized out>) at gtktogglebutton.c:527 #7 0x00007fe31db05fd1 in gtk_mount_operation_ask_password_do_gtk (default_domain=0x5569654ce990 "WILCKS", default_user=<optimized out>, message=0x55696524fc00 "", operation=0x556964a639f0) at gtkmountoperation.c:793 #8 gtk_mount_operation_ask_password (mount_op=0x556964a639f0, message=message@entry=0x556964d6c2c0 "Authentication Required\nEnter user and password for share “wilck” on “nashorn.local”:", default_user=default_user@entry=0x556964cfd740 "martin", default_domain=default_domain@entry=0x5569654ce990 "WILCKS", flags=<optimized out>) at gtkmountoperation.c:900 #9 0x00007fe31c6360b8 in _g_cclosure_marshal_VOID__STRING_STRING_STRING_FLAGSv (closure=0x5569653f59f0, return_value=<optimized out>, instance=<optimized out>, args=<optimized out>, marshal_data=<optimized out>, n_params=<optimized out>, param_types=0x556965007460) at ../gio/gmarshal-internal.c:2254 #10 0x00007fe31c55fb8c in _g_closure_invoke_va (closure=0x5569653f59f0, return_value=0x0, instance=0x556964a639f0, args=0x7ffd0585e458, n_params=4, param_types=0x556965007460) at ../gobject/gclosure.c:893 #11 0x00007fe31c57dbb1 in g_signal_emit_valist (instance=instance@entry=0x556964a639f0, signal_id=signal_id@entry=563, detail=detail@entry=0, var_args=var_args@entry=0x7ffd0585e458) at ../gobject/gsignal.c:3406 #12 0x00007fe31c57e5da in g_signal_emit_by_name (instance=<optimized out>, detailed_signal=detailed_signal@entry=0x7fe31279a71c "ask_password") at ../gobject/gsignal.c:3594 #13 0x00007fe312792b7d in handle_ask_password (object=<optimized out>, invocation=<optimized out>, arg_message_string=0x556965660ce0 "Authentication Required\nEnter user and password for share “wilck” on “nashorn.local”:", arg_default_user=0x55696535e310 "martin", arg_default_domain=0x55696505b820 "WILCKS", arg_flags_as_int=31, data=0x556964d757f0) at ../common/gmountoperationdbus.c:112 #14 0x00007fe3172956dd in ffi_call_unix64 () at ../src/x86/unix64.S:101 #15 0x00007fe317294bdf in ffi_call_int (cif=cif@entry=0x7ffd0585e810, fn=fn@entry=0x7fe312792b20 <handle_ask_password>, rvalue=<optimized out>, avalue=avalue@entry=0x7ffd0585e6e0, closure=closure@entry=0x0) at ../src/x86/ffi64.c:662 #16 0x00007fe31729521d in ffi_call (cif=cif@entry=0x7ffd0585e810, fn=fn@entry=0x7fe312792b20 <handle_ask_password>, rvalue=<optimized out>, avalue=avalue@entry=0x7ffd0585e6e0) at ../src/x86/ffi64.c:674 --Type <RET> for more, q to quit, c to continue without paging--c #17 0x00007fe31c5601f4 in g_cclosure_marshal_generic (closure=<optimized out>, return_gvalue=<optimized out>, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=<optimized out>) at ../gobject/gclosure.c:1534 #18 0x00007fe31c55f973 in g_closure_invoke (closure=0x55696537dd90, return_value=0x7ffd0585e9e0, n_param_values=6, param_values=0x5569653b0400, invocation_hint=0x7ffd0585e9c0) at ../gobject/gclosure.c:830 #19 0x00007fe31c573a7e in signal_emit_unlocked_R (node=node@entry=0x55696537e9b0, detail=detail@entry=0, instance=instance@entry=0x5569652b5550, emission_return=emission_return@entry=0x7ffd0585eb20, instance_and_params=instance_and_params@entry=0x5569653b0400) at ../gobject/gsignal.c:3742 #20 0x00007fe31c57cae2 in g_signal_emitv (instance_and_params=instance_and_params@entry=0x5569653b0400, signal_id=signal_id@entry=573, detail=detail@entry=0, return_value=return_value@entry=0x7ffd0585eb20) at ../gobject/gsignal.c:3227 #21 0x00007fe31278aa49 in _gvfs_dbus_mount_operation_skeleton_handle_method_call (connection=<optimized out>, sender=<optimized out>, object_path=<optimized out>, interface_name=0x5569654f5ff0 "org.gtk.vfs.MountOperation", method_name=0x556965453210 "AskPassword", parameters=<optimized out>, invocation=0x556964b57b50, user_data=0x5569652b5550) at common/gvfsdbus.c:8133 #22 0x00007fe31c6d55b7 in g_dbus_interface_method_dispatch_helper (interface=<optimized out>, method_call_func=0x7fe31278a890 <_gvfs_dbus_mount_operation_skeleton_handle_method_call>, invocation=0x556964b57b50) at ../gio/gdbusinterfaceskeleton.c:613 #23 0x00007fe31c6bc2fa in call_in_idle_cb (user_data=user_data@entry=0x556964b57b50) at ../gio/gdbusconnection.c:5010 #24 0x00007fe31e3184d7 in g_idle_dispatch (source=0x556964d6dfc0, callback=0x7fe31c6bc0e0 <call_in_idle_cb>, user_data=0x556964b57b50) at ../glib/gmain.c:5897 #25 0x00007fe31e31c82b in g_main_dispatch (context=0x556964a62920) at ../glib/gmain.c:3381 #26 g_main_context_dispatch (context=context@entry=0x556964a62920) at ../glib/gmain.c:4099 #27 0x00007fe31e31cbd0 in g_main_context_iterate (context=context@entry=0x556964a62920, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:4175 #28 0x00007fe31e31cc5c in g_main_context_iteration (context=context@entry=0x556964a62920, may_block=may_block@entry=1) at ../glib/gmain.c:4240 #29 0x00007fe31c69110d in g_application_run (application=0x556964a50210, argc=<optimized out>, argv=<optimized out>) at ../gio/gapplication.c:2569 #30 0x000055696373e1d7 in ?? () #31 0x00007fe31b85824d in __libc_start_main () from /lib64/libc.so.6 #32 0x000055696373e22a in ?? () (gdb) disas /s Dump of assembler code for function gtk_widget_set_sensitive: gtkwidget.c: 9512 { 0x00007fe31dc37a10 <+0>: push %rbp 0x00007fe31dc37a11 <+1>: push %rbx 0x00007fe31dc37a12 <+2>: mov %rdi,%rbx 0x00007fe31dc37a15 <+5>: mov %esi,%ebp 0x00007fe31dc37a17 <+7>: sub $0x28,%rsp 0x00007fe31dc37a1b <+11>: mov %fs:0x28,%rax 0x00007fe31dc37a24 <+20>: mov %rax,0x18(%rsp) 0x00007fe31dc37a29 <+25>: xor %eax,%eax 9513 GtkWidgetPrivate *priv; 9514 9515 g_return_if_fail (GTK_IS_WIDGET (widget)); 0x00007fe31dc37a2b <+27>: call 0x7fe31dc25f10 <gtk_widget_get_type> 0x00007fe31dc37a30 <+32>: test %rbx,%rbx 0x00007fe31dc37a33 <+35>: je 0x7fe31dc37a51 <gtk_widget_set_sensitive+65> 0x00007fe31dc37a35 <+37>: mov (%rbx),%rdx 0x00007fe31dc37a38 <+40>: test %rdx,%rdx 0x00007fe31dc37a3b <+43>: je 0x7fe31dc37a42 <gtk_widget_set_sensitive+50> => 0x00007fe31dc37a3d <+45>: cmp %rax,(%rdx) (gdb) info reg rax 0x556964a4d400 93911148450816 rbx 0x55696558a720 93911160235808 rcx 0x0 0 rdx 0xaaaaaaaaaaaaaaaa -6148914691236517206 rsi 0x0 0 rdi 0x55696558a720 93911160235808 rbp 0x0 0x0 rsp 0x7ffd0585db00 0x7ffd0585db00 r8 0x7fe31dad5100 140613432201472 r9 0x556964badae0 93911149894368 r10 0x0 0 r11 0xc 12 r12 0x1 1 r13 0x7ffd0585dd20 140724696112416 r14 0x7ffd0585dca0 140724696112288 r15 0x7fe31c561b90 140613409708944 %rdx has a bogus value. It is fetched from %rbx, which is the return value of gtk_widget_get_type(). Called from this code: 457 static void 458 pw_dialog_anonymous_toggled (GtkWidget *widget, 459 GtkMountOperation *operation) 460 { 461 GtkMountOperationPrivate *priv = operation->priv; 462 gboolean is_valid; 463 GList *l; 464 (gdb) 465 priv->anonymous = widget == priv->anonymous_toggle; 466 467 if (priv->anonymous) 468 is_valid = TRUE; 469 else 470 is_valid = pw_dialog_input_is_valid (operation); 471 472 for (l = priv->user_widgets; l != NULL; l = l->next) 473 { 474 gtk_widget_set_sensitive (GTK_WIDGET (l->data), !priv->anonymous); (gdb) 475 } It When the bug occurs, we're in the middle of the priv->user_widgets list, with l pointing the 8th member of 14. This element seems to be the only one with an invalid data pointer. (gdb) p *((GtkWidget*) priv->user_widgets->next->next->next->next->next->next->data) $33 = {parent_instance = {g_type_instance = {g_class = 0x556964e23340}, ref_count = 1, qdata = 0x0}, priv = 0x5569656899a0} (gdb) p *((GtkWidget*) priv->user_widgets->next->next->next->next->next->next->next->data) $31 = {parent_instance = {g_type_instance = {g_class = 0xaaaaaaaaaaaaaaaa}, ref_count = 2863311530, qdata = 0xaaaaaaaaaaaaaaaa}, priv = 0xaaaaaaaaaaaaaaaa} (gdb) p *((GtkWidget*) priv->user_widgets->next->next->next->next->next->next->next->next->data) $32 = {parent_instance = {g_type_instance = {g_class = 0x556964ea7400}, ref_count = 1, qdata = 0x55696555ae90}, The problem seems to be that the 2nd time gtk_mount_operation_ask_password_do_gtk() is called, operation->priv->user_widgets is not empty, but the "data" fields of all widgets have been overwritten with 0xaaaaaaaaaaaaaaaa. table_add_entry() then prepends new widgets to the user_widgets list. gtk_mount_operation_ask_password_do_gtk table_add_entry operation->priv->user_widgets = g_list_prepend (operation->priv->user_widgets, entry); When the list is later traversed in pw_dialog_anonymous_toggled(), the invalid previous first element with data == 0xaaaaaaaaaaaaaaaa will be encountered, causing the crash.