[systemd-devel] [PATCH 3/7] logind: close races on session state at logout
Djalal Harouni
tixxdz at opendz.org
Thu Feb 6 12:37:16 PST 2014
To get the state of the session, the session_get_state() is used.
This function will check if the session->scope_job is set then it will
automatically return SESSION_OPENING. This is buggy in the context of
session closing:
At logout or D-Bus TerminateSession() fifo_fd is removed:
=> session_get_state() == SESSION_CLOSING (correct)
Then we have session_stop() which calls session_stop_scope(), this
will queue the scope job to be removed and set the session->scope_job
=> session_get_state() == SESSION_OPENING (incorrect)
After the scope job is removed the state will be again correct
=> session_get_state() == SESSION_CLOSING (correct)
To fix this and make sure that the state will always be SESSION_CLOSING
we add a flag that is used to differentiate between SESSION_OPENING and
SESSION_CLOSING.
The 'scope_opening' flag will be set to true only during real session
opening in session_start_scope(), and it will be set to false just after
the session fifo fd was successfully created, which means that during
session closing it will be false.
And update session_get_state() to check if the 'scope_opening' is true
before returning the SESSION_OPENING, if it is not then SESSION_CLOSING
will be returned which is the correct behaviour.
---
src/login/logind-session-dbus.c | 3 +++
src/login/logind-session.c | 4 +++-
src/login/logind-session.h | 1 +
3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
index 54db864..099ade6 100644
--- a/src/login/logind-session-dbus.c
+++ b/src/login/logind-session-dbus.c
@@ -670,6 +670,9 @@ int session_send_create_reply(Session *s, sd_bus_error *error, bool opening) {
if (fifo_fd < 0)
return fifo_fd;
+ /* Clean this up as soon as we have the fifo_fd */
+ s->scope_opening = false;
+
/* Update the session state file before we notify the client
* about the result. */
session_save(s);
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index bec59c0..848e8a1 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -496,6 +496,8 @@ static int session_start_scope(Session *s) {
free(s->scope_job);
s->scope_job = job;
+ /* session scope is being created */
+ s->scope_opening = true;
}
}
@@ -880,7 +882,7 @@ void session_add_to_gc_queue(Session *s) {
SessionState session_get_state(Session *s) {
assert(s);
- if (s->scope_job)
+ if (s->scope_opening)
return SESSION_OPENING;
if (s->fifo_fd < 0)
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
index ebe3902..205491a 100644
--- a/src/login/logind-session.h
+++ b/src/login/logind-session.h
@@ -110,6 +110,7 @@ struct Session {
bool in_gc_queue:1;
bool started:1;
+ bool scope_opening:1; /* session scope is being created */
sd_bus_message *create_message;
--
1.8.3.1
More information about the systemd-devel
mailing list