diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2020-07-10 22:48:35 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2020-07-10 22:48:35 +0400 |
commit | 873eb4a39737b36cea0db7fbe12d70919529060a (patch) | |
tree | 5e98ca0d7fb146f077bd70d4866bf436a30625cc /plugin | |
parent | 41221091f6541ea83eeec70732b92b94746a44e7 (diff) | |
download | mariadb-git-873eb4a39737b36cea0db7fbe12d70919529060a.tar.gz |
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.
Diffstat (limited to 'plugin')
-rw-r--r-- | plugin/auth_pam/auth_pam.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c index 4275b7d6750..c1c05bba216 100644 --- a/plugin/auth_pam/auth_pam.c +++ b/plugin/auth_pam/auth_pam.c @@ -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; |