Commit 873eb4a3 authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-21385 PAM v2 plugin produces lots of zombie processes.

The auth_pam_tool that is executed from pam_auth() can be still
not finished by the time we do the waitpid() there.
As we use WNOHANG option for the waitpid(), it didn't wait and
left the zombie process. So let's do the loop of waitpid() with the
limited number of sleeps.
parent 41221091
......@@ -36,12 +36,20 @@ static char *opt_plugin_dir; /* To be dynamically linked. */
static const char *tool_name= "auth_pam_tool_dir/auth_pam_tool";
static const int tool_name_len= 31;
/*
sleep_limit is now 5 meaning up to 1 second sleep.
each step means 10 times longer sleep, so 6 would mean 10 seconds.
*/
static const unsigned int sleep_limit= 5;
static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
{
int p_to_c[2], c_to_p[2]; /* Parent-to-child and child-to-parent pipes. */
pid_t proc_id;
int result= CR_ERROR, pkt_len= 0;
unsigned char field, *pkt;
unsigned int n_sleep= 0;
useconds_t sleep_time= 100;
PAM_DEBUG((stderr, "PAM: opening pipes.\n"));
if (pipe(p_to_c) < 0 || pipe(c_to_p) < 0)
......@@ -190,7 +198,24 @@ static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
error_ret:
close(p_to_c[1]);
close(c_to_p[0]);
waitpid(proc_id, NULL, WNOHANG);
while (waitpid(proc_id, NULL, WNOHANG) != (int) proc_id)
{
if (n_sleep++ == sleep_limit)
{
/*
The auth_pam_tool application doesn't terminate.
Means something wrong happened there like pam_xxx.so hanged.
*/
kill(proc_id, SIGKILL);
sleep_time= 1000000; /* 1 second wait should be enough. */
PAM_DEBUG((stderr, "PAM: auth_pam_tool doesn't terminate,"
" have to kill it.\n"));
}
else if (n_sleep > sleep_limit)
break;
usleep(sleep_time);
sleep_time*= 10;
}
PAM_DEBUG((stderr, "PAM: auth result %d.\n", result));
return result;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment