CVE-2021-4115.patch 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. diff --git a/src/polkit/polkitsystembusname.c b/src/polkit/polkitsystembusname.c
  2. index 8ed1363..2fbf5f1 100644
  3. --- a/src/polkit/polkitsystembusname.c
  4. +++ b/src/polkit/polkitsystembusname.c
  5. @@ -62,6 +62,10 @@ enum
  6. PROP_NAME,
  7. };
  8. +
  9. +guint8 dbus_call_respond_fails; // has to be global because of callback
  10. +
  11. +
  12. static void subject_iface_init (PolkitSubjectIface *subject_iface);
  13. G_DEFINE_TYPE_WITH_CODE (PolkitSystemBusName, polkit_system_bus_name, G_TYPE_OBJECT,
  14. @@ -364,6 +368,7 @@ on_retrieved_unix_uid_pid (GObject *src,
  15. if (!v)
  16. {
  17. data->caught_error = TRUE;
  18. + dbus_call_respond_fails += 1;
  19. }
  20. else
  21. {
  22. @@ -405,6 +410,8 @@ polkit_system_bus_name_get_creds_sync (PolkitSystemBusName *system_bus
  23. tmp_context = g_main_context_new ();
  24. g_main_context_push_thread_default (tmp_context);
  25. + dbus_call_respond_fails = 0;
  26. +
  27. /* Do two async calls as it's basically as fast as one sync call.
  28. */
  29. g_dbus_connection_call (connection,
  30. @@ -432,11 +439,34 @@ polkit_system_bus_name_get_creds_sync (PolkitSystemBusName *system_bus
  31. on_retrieved_unix_uid_pid,
  32. &data);
  33. - while (!((data.retrieved_uid && data.retrieved_pid) || data.caught_error))
  34. - g_main_context_iteration (tmp_context, TRUE);
  35. + while (TRUE)
  36. + {
  37. + /* If one dbus call returns error, we must wait until the other call
  38. + * calls _call_finish(), otherwise fd leak is possible.
  39. + * Resolves: GHSL-2021-077
  40. + */
  41. - if (data.caught_error)
  42. - goto out;
  43. + if ( (dbus_call_respond_fails > 1) )
  44. + {
  45. + // we got two faults, we can leave
  46. + goto out;
  47. + }
  48. +
  49. + if ((data.caught_error && (data.retrieved_pid || data.retrieved_uid)))
  50. + {
  51. + // we got one fault and the other call finally finished, we can leave
  52. + goto out;
  53. + }
  54. +
  55. + if ( !(data.retrieved_uid && data.retrieved_pid) )
  56. + {
  57. + g_main_context_iteration (tmp_context, TRUE);
  58. + }
  59. + else
  60. + {
  61. + break;
  62. + }
  63. + }
  64. if (out_uid)
  65. *out_uid = data.uid;