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 758361 - Crash in mail_client_check_auth_run_cb when goa_mail_auth_run fails
Crash in mail_client_check_auth_run_cb when goa_mail_auth_run fails
Status: RESOLVED FIXED
Product: gnome-online-accounts
Classification: Core
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: GNOME Online Accounts maintainer(s)
GNOME Online Accounts maintainer(s)
Depends on:
Blocks:
 
 
Reported: 2015-11-19 18:31 UTC by Debarshi Ray
Modified: 2015-11-26 13:00 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
smtp-auth: Plug leaks in error handling (1.46 KB, patch)
2015-11-19 18:33 UTC, Debarshi Ray
committed Details | Review
mail-auth: We want check_cancellable, not handle_cancellation (1.76 KB, patch)
2015-11-19 18:34 UTC, Debarshi Ray
committed Details | Review
imap-auth-login, smtp-auth: Always set the GError on failure (20.52 KB, patch)
2015-11-19 18:34 UTC, Debarshi Ray
none Details | Review
imap-auth-login, smtp-auth, utils: Always set the GError on failure (9.36 KB, patch)
2015-11-24 18:17 UTC, Debarshi Ray
committed Details | Review

Description Debarshi Ray 2015-11-19 18:31:38 UTC
I have been seeing crashes like this on my system for a while. If you look at the backtrace then it is obvious that this is a case of goa_main_auth_run_finish returning FALSE without setting the GError.

As far as I can see, this can only be caused by our use of g_data_input_stream_read_line, which can return NULL without setting the GError when there is nothing else to read. We are not handling this case, which can lead to this.

Backtrace:

Program terminated with signal SIGSEGV, Segmentation fault.
  • #0 mail_client_check_auth_run_cb
    at goamailclient.c line 147
  • #0 mail_client_check_auth_run_cb
    at goamailclient.c line 147
  • #1 g_simple_async_result_complete
    at gsimpleasyncresult.c line 801
  • #2 complete_in_idle_cb_for_thread
    at gsimpleasyncresult.c line 872
  • #3 g_main_context_dispatch
    at gmain.c line 3154
  • #4 g_main_context_dispatch
    at gmain.c line 3769
  • #5 g_main_context_iterate
    at gmain.c line 3840
  • #6 g_main_loop_run
    at gmain.c line 4034
  • #7 goa_mail_client_check_sync
    at goamailclient.c line 476
  • #8 ensure_credentials_sync
    at goaimapsmtpprovider.c line 371
  • #9 ensure_credentials_in_thread_func
    at goaprovider.c line 665
  • #10 run_in_thread
    at gsimpleasyncresult.c line 898
  • #11 io_job_thread
    at gioscheduler.c line 85
  • #12 g_task_thread_pool_thread
    at gtask.c line 1283
  • #13 g_thread_pool_thread_proxy
    at gthreadpool.c line 307
  • #14 g_thread_proxy
    at gthread.c line 778
  • #15 start_thread
    at pthread_create.c line 334
  • #16 clone
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S line 109
$1 = {cancellable = 0x0, input = 0x0, output = 0x0, tls_conn = 0x7fbd50347170 [GTlsClientConnectionGnutls], 
  res = 0x7fbd64003090 [GSimpleAsyncResult], socket = 0x7fbd2c415d00 [GSocket], sc = 0x7fbd3c004dc0 [GSocketClient], 
  conn = 0x7fbd800311e0 [GTcpWrapperConnection], cert_flags = 0, auth = 0x558777e212b0 [GoaImapAuthLogin], 
  tls_type = GOA_TLS_TYPE_STARTTLS, accept_ssl_errors = 1, host_and_port = 0x7fbd18165510 "mail.guillen.com.es", 
  default_port = 143}
(gdb)
Comment 1 Debarshi Ray 2015-11-19 18:33:58 UTC
Created attachment 315916 [details] [review]
smtp-auth: Plug leaks in error handling
Comment 2 Debarshi Ray 2015-11-19 18:34:28 UTC
Created attachment 315917 [details] [review]
mail-auth: We want check_cancellable, not handle_cancellation
Comment 3 Debarshi Ray 2015-11-19 18:34:55 UTC
Created attachment 315918 [details] [review]
imap-auth-login, smtp-auth: Always set the GError on failure
Comment 4 Debarshi Ray 2015-11-23 16:10:31 UTC
Comment on attachment 315916 [details] [review]
smtp-auth: Plug leaks in error handling

Pushed to master.
Comment 5 Christophe Fergeau 2015-11-23 16:24:43 UTC
Review of attachment 315916 [details] [review]:

Already pushed, but ACK.
Comment 6 Christophe Fergeau 2015-11-23 16:25:34 UTC
Review of attachment 315917 [details] [review]:

Isn't it roughly equivalent as g_simple_async_result_run_in_thread() is used with these cancellables ?
Comment 7 Debarshi Ray 2015-11-23 16:41:16 UTC
(In reply to Christophe Fergeau from comment #6)
> Review of attachment 315917 [details] [review] [review]:
> 
> Isn't it roughly equivalent as g_simple_async_result_run_in_thread() is used
> with these cancellables ?

I think g_simple_async_result_set_handle_cancellation is the equivalent of g_task_set_return_on_cancel, which "allows you to create a cancellable wrapper around an uninterruptable function". I don't think we need that here because all the internal methods are cancellable.

What we do want is to always return an error when the operation was cancelled.
Comment 8 Christophe Fergeau 2015-11-23 16:55:33 UTC
Review of attachment 315918 [details] [review]:

Looks good to me. I would probably have introduced a small g_data_input_stream_read_line() setting an error every time this returns NULL so that the 'if (!ret && local_error == NULL)' checks you added can get a g_warn_if_reached() in case there are other places reaching out: without setting local_error.

::: src/goabackend/goaimapauthlogin.c
@@ +475,3 @@
       if (credentials == NULL)
         {
+          g_prefix_error (&local_error, "Error looking up credentials for IMAP LOGIN in keyring: ");

g_prefix_error documentation says "If *err is NULL (ie: an error variable is present but there is no error condition) then also do nothing."
Is 'local_error' guaranteed to be non-NULL when credentials == NULL? (probably as  goa_utils_lookup_credentials_sync is roughly credentials = g_variant_parse (..., &local_error);
Comment 9 Debarshi Ray 2015-11-24 18:16:36 UTC
(In reply to Christophe Fergeau from comment #8)
> Review of attachment 315918 [details] [review] [review]:
> 
> Looks good to me. I would probably have introduced a small
> g_data_input_stream_read_line() setting an error every time this returns
> NULL so that the 'if (!ret && local_error == NULL)' checks you added can get
> a g_warn_if_reached() in case there are other places reaching out: without
> setting local_error.

Excellent idea!
Comment 10 Debarshi Ray 2015-11-24 18:17:39 UTC
Created attachment 316192 [details] [review]
imap-auth-login, smtp-auth, utils: Always set the GError on failure
Comment 11 Debarshi Ray 2015-11-24 18:28:05 UTC
(In reply to Christophe Fergeau from comment #8)
> Review of attachment 315918 [details] [review] [review]:
> ::: src/goabackend/goaimapauthlogin.c
> @@ +475,3 @@
>        if (credentials == NULL)
>          {
> +          g_prefix_error (&local_error, "Error looking up credentials for
> IMAP LOGIN in keyring: ");
> 
> g_prefix_error documentation says "If *err is NULL (ie: an error variable is
> present but there is no error condition) then also do nothing."
> Is 'local_error' guaranteed to be non-NULL when credentials == NULL?

Yes, and looking at the back trace confirms that self->password is already set, so we are not hitting the code path. In fact, these self->password == NULL code paths are totally unused, so maybe we should delete them to avoid useless complexity?