PolicyKit: protect session object during pam auth
Kay Sievers
kay.sievers at vrfy.org
Wed Mar 15 10:28:14 PST 2006
Fix segfault cause of use of session object by pam process handler
while the session is already finalized.
Thanks,
Kay
-------------- next part --------------
Index: ChangeLog
===================================================================
RCS file: /cvs/hal/PolicyKit/ChangeLog,v
retrieving revision 1.10
diff -u -p -r1.10 ChangeLog
--- ChangeLog 15 Mar 2006 16:11:33 -0000 1.10
+++ ChangeLog 15 Mar 2006 18:25:27 -0000
@@ -1,3 +1,16 @@
+2006-03-15 Kay Sievers <kay.sievers at vrfy.org>
+
+ Protect session object(refcount) during pam work, to not go
+ away until until the auth process has finished.
+
+ * polkitd/polkit-manager.c: (bus_name_owner_changed),
+ (session_finalized):
+
+ * polkitd/polkit-session.c: (polkit_session_init), (data_from_pam),
+ (polkit_session_initiate_auth), (polkit_session_close),
+ (polkit_session_new), (polkit_session_initiator_disconnected):
+
+
2006-03-15 David Zeuthen <davidz at redhat.com>
* polkitd/polkit-manager.h: Include sys/types.h; fixed fd.o
Index: polkitd/polkit-manager.c
===================================================================
RCS file: /cvs/hal/PolicyKit/polkitd/polkit-manager.c,v
retrieving revision 1.1
diff -u -p -r1.1 polkit-manager.c
--- polkitd/polkit-manager.c 14 Mar 2006 06:14:33 -0000 1.1
+++ polkitd/polkit-manager.c 15 Mar 2006 18:25:27 -0000
@@ -169,13 +169,10 @@ bus_name_owner_changed (DBusGProxy *bus
session = POLKIT_SESSION (g_hash_table_lookup (manager->priv->connection_name_to_session_object,
old_service_name));
if (session != NULL) {
- /* possibly revoke temporary privileges granted */
- polkit_session_initiator_disconnected (session);
-
- /* end the session */
- g_object_unref (session);
-
g_hash_table_remove (manager->priv->connection_name_to_session_object, old_service_name);
+
+ /* possibly revoke temporary privileges granted, and cleanup session */
+ polkit_session_initiator_disconnected (session);
}
}
@@ -201,7 +198,7 @@ session_finalized (gpointer data,
GObject *where_the_object_was)
{
PolicyKitManager *manager = POLKIT_MANAGER (data);
-
+
g_hash_table_foreach_remove (manager->priv->connection_name_to_session_object,
session_remover,
where_the_object_was);
Index: polkitd/polkit-session.c
===================================================================
RCS file: /cvs/hal/PolicyKit/polkitd/polkit-session.c,v
retrieving revision 1.1
diff -u -p -r1.1 polkit-session.c
--- polkitd/polkit-session.c 14 Mar 2006 06:14:33 -0000 1.1
+++ polkitd/polkit-session.c 15 Mar 2006 18:25:28 -0000
@@ -69,6 +69,7 @@ struct PolicyKitSessionPrivate
gboolean have_granted_temp_privileges;
int auth_state;
+ gboolean is_closed;
gboolean is_authenticated;
char *auth_denied_reason;
GSList *auth_questions;
@@ -96,6 +97,7 @@ polkit_session_init (PolicyKitSession *s
{
session->priv = g_new0 (PolicyKitSessionPrivate, 1);
session->priv->session_number = 42;
+ session->priv->is_closed = FALSE;
session->priv->is_authenticated = FALSE;
session->priv->auth_state = AUTH_STATE_NOT_STARTED;
}
@@ -676,10 +678,8 @@ data_from_pam (GIOChannel *source,
/* left intentionally blank */
break;
}
-
}
-
if (condition & G_IO_HUP) {
/*g_debug ("in %s - hangup", __FUNCTION__);*/
if (session->priv->child_pid != 0) {
@@ -688,6 +688,10 @@ data_from_pam (GIOChannel *source,
session->priv->child_pid = 0;
waitpid (session->priv->child_pid, &status, 0);
}
+
+ /* we held a ref for the session as long as we watched */
+ g_object_unref (session);
+
/* remove the source */
return FALSE;
}
@@ -748,12 +752,12 @@ polkit_session_initiate_auth (PolicyKitS
g_warning ("pipe() failed: %s", strerror (errno));
goto fail;
}
-
+
switch (pid = fork()) {
case -1:
g_warning ("fork() failed: %s", strerror (errno));
goto fail;
-
+
case 0:
/* child; close unused ends */
close (fds[0]);
@@ -761,7 +765,7 @@ polkit_session_initiate_auth (PolicyKitS
do_pam_auth (fds[1], fdsb[0], session->priv);
break;
-
+
default:
session->priv->auth_state = AUTH_STATE_IN_PROGRESS;
@@ -773,11 +777,13 @@ polkit_session_initiate_auth (PolicyKitS
session->priv->pam_channel_write = g_io_channel_unix_new (fdsb[1]);
session->priv->pam_channel = g_io_channel_unix_new (fds[0]);
- g_io_add_watch (session->priv->pam_channel,
+ /* we hold a ref for the session as long as we watch */
+ g_object_ref (session);
+
+ g_io_add_watch (session->priv->pam_channel,
G_IO_IN | G_IO_ERR | G_IO_HUP,
data_from_pam,
session);
-
break;
}
@@ -881,7 +887,6 @@ polkit_session_close (PolicyKitSession
return FALSE;
if (!do_not_revoke_privilege && session->priv->have_granted_temp_privileges) {
-
if (!polkit_manager_remove_temporary_privilege (session->priv->manager,
session->priv->grant_to_uid,
session->priv->grant_privilege,
@@ -895,7 +900,10 @@ polkit_session_close (PolicyKitSession
}
}
- g_object_unref (session);
+ if (!session->priv->is_closed) {
+ g_object_unref (session);
+ session->priv->is_closed = TRUE;
+ }
dbus_g_method_return (context);
return TRUE;
@@ -959,6 +967,7 @@ polkit_session_new (DBusGConnection *
static int session_number_base = 0;
session = POLKIT_SESSION (g_object_new (POLKIT_TYPE_SESSION, NULL));
+
session->priv->connection = dbus_g_connection_ref (connection);
session->priv->session_number = session_number_base++;
session->priv->manager = manager;
@@ -1000,4 +1009,10 @@ polkit_session_initiator_disconnected (P
session->priv->grant_pid_restriction);
}
}
+
+ /* cleanup session if orphaned */
+ if (!session->priv->is_closed) {
+ g_object_unref (session);
+ session->priv->is_closed = TRUE;
+ }
}
More information about the hal
mailing list