diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2017-08-21 21:41:14 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2017-08-21 21:41:14 +0000 |
commit | c2cdcf41ccf92e65434001bc73d5d81b4c4210dd (patch) | |
tree | b806cd4f2e6e8fcd9ec7d6f315a0aa469b48521d /usr.bin/passwd | |
parent | e9d6f86c3468c07e6b1b12c0dd0b46516528e450 (diff) |
Use waitpid()/EINTR idiom for the specific pid, rather than generic wait(),
in case the parent process was started with a dangling child. This style
ensures any potential parent:child interlock isn't disrupted due to the
"wrong" child being waited on first. Then the other other childs can safely
zombie.
ok millert jca brynet
Diffstat (limited to 'usr.bin/passwd')
-rw-r--r-- | usr.bin/passwd/pwd_check.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/usr.bin/passwd/pwd_check.c b/usr.bin/passwd/pwd_check.c index fcb3dfdeb41..cfdd1f65ed2 100644 --- a/usr.bin/passwd/pwd_check.c +++ b/usr.bin/passwd/pwd_check.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pwd_check.c,v 1.15 2015/12/09 19:39:10 mmcc Exp $ */ +/* $OpenBSD: pwd_check.c,v 1.16 2017/08/21 21:41:13 deraadt Exp $ */ /* * Copyright 2000 Niels Provos <provos@citi.umich.edu> @@ -138,12 +138,14 @@ pwd_check(login_cap_t *lc, char *password) err(1, "pledge"); for (i = 0; i < sizeof(patterns) / sizeof(*patterns); i++) { + int ret; + if (regcomp(&rgx, patterns[i].match, patterns[i].flags) != 0) continue; - res = regexec(&rgx, password, 0, NULL, 0); + ret = regexec(&rgx, password, 0, NULL, 0); regfree(&rgx); - if (res == 0) { + if (ret == 0) { printf("%s\n", patterns[i].response); exit(1); } @@ -181,8 +183,11 @@ pwd_check(login_cap_t *lc, char *password) } /* get the return value from the child */ - wait(&child); - if (WIFEXITED(child) && WEXITSTATUS(child) == 0) { + while (waitpid(child, &res, 0) == -1) { + if (errno != EINTR) + break; + } + if (WIFEXITED(res) && WEXITSTATUS(res) == 0) { free(checker); return (1); } |