You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.5 KiB

  1. commit a873c161d251abd025008034c0ddef8cd7f39511
  2. Author: Willy Tarreau <w@1wt.eu>
  3. Date: Mon Oct 29 18:02:54 2018 +0100
  4. BUG/MEDIUM: auth/threads: use of crypt() is not thread-safe
  5. It was reported here that authentication may fail when threads are
  6. enabled :
  7. https://bugzilla.redhat.com/show_bug.cgi?id=1643941
  8. While I couldn't reproduce the issue, it's obvious that there is a
  9. problem with the use of the non-reentrant crypt() function there.
  10. On Linux systems there's crypt_r() but not on the vast majority of
  11. other ones. Thus a first approach consists in placing a lock around
  12. this crypt() call. Another patch may relax it when crypt_r() is
  13. available.
  14. This fix must be backported to 1.8. Thanks to Ryan O'Hara for the
  15. quick notification.
  16. (cherry picked from commit 34d4b525a129baa6f52a930ae629ddb1ba4255c2)
  17. Signed-off-by: Willy Tarreau <w@1wt.eu>
  18. diff --git a/include/common/hathreads.h b/include/common/hathreads.h
  19. index 44bd66d1..24fb1d1a 100644
  20. --- a/include/common/hathreads.h
  21. +++ b/include/common/hathreads.h
  22. @@ -373,6 +373,7 @@ enum lock_label {
  23. START_LOCK,
  24. TLSKEYS_REF_LOCK,
  25. PENDCONN_LOCK,
  26. + AUTH_LOCK,
  27. LOCK_LABELS
  28. };
  29. struct lock_stat {
  30. @@ -495,6 +496,7 @@ static inline const char *lock_label(enum lock_label label)
  31. case START_LOCK: return "START";
  32. case TLSKEYS_REF_LOCK: return "TLSKEYS_REF";
  33. case PENDCONN_LOCK: return "PENDCONN";
  34. + case AUTH_LOCK: return "AUTH";
  35. case LOCK_LABELS: break; /* keep compiler happy */
  36. };
  37. /* only way to come here is consecutive to an internal bug */
  38. diff --git a/src/auth.c b/src/auth.c
  39. index a2c689f7..e0fb1352 100644
  40. --- a/src/auth.c
  41. +++ b/src/auth.c
  42. @@ -28,6 +28,7 @@
  43. #include <types/global.h>
  44. #include <common/config.h>
  45. #include <common/errors.h>
  46. +#include <common/hathreads.h>
  47. #include <proto/acl.h>
  48. #include <proto/log.h>
  49. @@ -37,6 +38,10 @@
  50. struct userlist *userlist = NULL; /* list of all existing userlists */
  51. +#ifdef CONFIG_HAP_CRYPT
  52. +__decl_hathreads(static HA_SPINLOCK_T auth_lock);
  53. +#endif
  54. +
  55. /* find targets for selected gropus. The function returns pointer to
  56. * the userlist struct ot NULL if name is NULL/empty or unresolvable.
  57. */
  58. @@ -245,7 +250,9 @@ check_user(struct userlist *ul, const char *user, const char *pass)
  59. if (!(u->flags & AU_O_INSECURE)) {
  60. #ifdef CONFIG_HAP_CRYPT
  61. + HA_SPIN_LOCK(AUTH_LOCK, &auth_lock);
  62. ep = crypt(pass, u->pass);
  63. + HA_SPIN_UNLOCK(AUTH_LOCK, &auth_lock);
  64. #else
  65. return 0;
  66. #endif