From 5f223e0bd87aa93e5d68dc53766c0cfbbb063a26 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Fri, 18 Jan 2019 13:19:32 +0000 Subject: [PATCH] polkitAgent: Disconnect session signal handlers when destroying session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise the session could outlive the dialogue, emit a subsequent signal, and its callback would reference finalised objects/widgets from the dialogue. The PolkitSession object is implemented by libpolkit-gobject, so we have no guarantees about its reference counting — the session object could keep itself alive in another thread, or be a singleton. In all likelihood, the session hangs around for longer than the dialogue due to differences in when the two objects are garbage collected. This can be triggered by running `pkexec true` from a gnome-terminal window, then calling `pkill pkexec` from another terminal (on a different VT or via SSH). This causes the dialogue to be cancelled by polkitd. Signed-off-by: Philip Withnall https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/357 --- js/ui/components/polkitAgent.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/js/ui/components/polkitAgent.js b/js/ui/components/polkitAgent.js index 4b2a2cacb..4ea4efba4 100644 --- a/js/ui/components/polkitAgent.js +++ b/js/ui/components/polkitAgent.js @@ -169,10 +169,10 @@ var AuthenticationDialog = new Lang.Class({ this.destroySession(); this._session = new PolkitAgent.Session({ identity: this._identityToAuth, cookie: this._cookie }); - this._session.connect('completed', this._onSessionCompleted.bind(this)); - this._session.connect('request', this._onSessionRequest.bind(this)); - this._session.connect('show-error', this._onSessionShowError.bind(this)); - this._session.connect('show-info', this._onSessionShowInfo.bind(this)); + this._sessionCompletedId = this._session.connect('completed', this._onSessionCompleted.bind(this)); + this._sessionRequestId = this._session.connect('request', this._onSessionRequest.bind(this)); + this._sessionShowErrorId = this._session.connect('show-error', this._onSessionShowError.bind(this)); + this._sessionShowInfoId = this._session.connect('show-info', this._onSessionShowInfo.bind(this)); this._session.initiate(); }, @@ -311,6 +311,11 @@ var AuthenticationDialog = new Lang.Class({ if (!this._completed) this._session.cancel(); this._completed = false; + + this._session.disconnect(this._sessionCompletedId); + this._session.disconnect(this._sessionRequestId); + this._session.disconnect(this._sessionShowErrorId); + this._session.disconnect(this._sessionShowInfoId); this._session = null; } },