fix: fix possible race condition

This commit is contained in:
MusiKid 2021-07-28 12:16:09 +02:00 committed by musikid
parent 5503cfb4e2
commit 039217152d
No known key found for this signature in database
GPG key ID: 7567D43648C6E2F4

View file

@ -133,7 +133,7 @@ int identify(pam_handle_t *pamh, int flags, int argc, const char **argv,
string workaround = reader.GetString("core", "workaround", "input"); string workaround = reader.GetString("core", "workaround", "input");
// In this case, we are not asking for the password // In this case, we are not asking for the password
if (workaround == Workaround::Off) if (workaround == Workaround::Off && auth_tok)
auth_tok = false; auth_tok = false;
// Will contain PAM conversation function // Will contain PAM conversation function
@ -241,6 +241,8 @@ int identify(pam_handle_t *pamh, int flags, int argc, const char **argv,
mutex m; mutex m;
condition_variable cv; condition_variable cv;
Type confirmation_type; Type confirmation_type;
// TODO: Find a clean way to do this
Type final_type;
// This task wait for the status of the python subprocess (we don't want a // This task wait for the status of the python subprocess (we don't want a
// zombie process) // zombie process)
@ -278,14 +280,11 @@ int identify(pam_handle_t *pamh, int flags, int argc, const char **argv,
{ {
unique_lock<mutex> lk(m); unique_lock<mutex> lk(m);
cv.wait(lk); cv.wait(lk);
final_type = confirmation_type;
} }
if (workaround != Workaround::Native && auth_tok) { if (final_type == Type::Howdy) {
pass_task.stop(false); // We need to be sure that we're not going to block forever if the
}
if (confirmation_type == Type::Howdy) {
// This one is just to be sure that we're not going to block forever if the
// child has a problem // child has a problem
if (child_task.wait(3s) == future_status::timeout) { if (child_task.wait(3s) == future_status::timeout) {
kill(child_pid, SIGTERM); kill(child_pid, SIGTERM);
@ -317,13 +316,21 @@ int identify(pam_handle_t *pamh, int flags, int argc, const char **argv,
} else { } else {
return on_howdy_auth(howdy_status, conv_function); return on_howdy_auth(howdy_status, conv_function);
} }
} else { }
if (workaround != Workaround::Native) {
if (child_task.wait(1s) == future_status::timeout) { // The branch with Howdy confirmation type returns early, so we don't need an
// else statement
// Again, we need to be sure that we're not going to block forever if the
// child has a problem
if (child_task.wait(1.5s) == future_status::timeout) {
kill(child_pid, SIGTERM); kill(child_pid, SIGTERM);
} }
child_task.stop(false); child_task.stop(false);
} else {
// We just wait for the thread to stop since it's this one which sent us the
// confirmation type
if (workaround == Workaround::Input && auth_tok) {
pass_task.stop(false); pass_task.stop(false);
} }
@ -339,8 +346,8 @@ int identify(pam_handle_t *pamh, int flags, int argc, const char **argv,
if (!reader.GetBoolean("core", "no_confirmation", true)) { if (!reader.GetBoolean("core", "no_confirmation", true)) {
// Construct confirmation text from i18n string // Construct confirmation text from i18n string
string confirm_text = dgettext("pam", "Identified face as {}"); string confirm_text = dgettext("pam", "Identified face as {}");
string identify_msg(confirm_text.replace(confirm_text.find("{}"), 2, string identify_msg(
string(user_ptr))); confirm_text.replace(confirm_text.find("{}"), 2, string(user_ptr)));
// Send confirmation message to user // Send confirmation message to user
conv_function(PAM_TEXT_INFO, identify_msg.c_str()); conv_function(PAM_TEXT_INFO, identify_msg.c_str());
} }
@ -354,7 +361,6 @@ int identify(pam_handle_t *pamh, int flags, int argc, const char **argv,
// The password has been entered, we are passing it to PAM stack // The password has been entered, we are passing it to PAM stack
return PAM_IGNORE; return PAM_IGNORE;
} }
}
// Called by PAM when a user needs to be authenticated, for example by running // Called by PAM when a user needs to be authenticated, for example by running
// the sudo command // the sudo command