CVE-2020-27780.patch 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. From 30fdfb90d9864bcc254a62760aaa149d373fd4eb Mon Sep 17 00:00:00 2001
  2. From: Tomas Mraz <tmraz@fedoraproject.org>
  3. Date: Fri, 20 Nov 2020 13:38:23 +0100
  4. Subject: [PATCH] Second blank check with root for non-existent users must
  5. never return 1
  6. MIME-Version: 1.0
  7. Content-Type: text/plain; charset=UTF-8
  8. Content-Transfer-Encoding: 8bit
  9. The commit af0faf66 ("pam_unix: avoid determining if user exists") introduced
  10. a regression where the blank check could return 1 if root had an empty
  11. password hash because in the second case the password hash of root was
  12. used. We now always return 0 in this case.
  13. The issue was found by Johannes Löthberg.
  14. Fixes #284
  15. * modules/pam_unix/support.c (_unix_blankpasswd): Make the loop
  16. to cover the complete blank check so both existing and non existing
  17. cases are identical except for the possible return value.
  18. ---
  19. modules/pam_unix/support.c | 39 +++++++++++++-------------------------
  20. 1 file changed, 13 insertions(+), 26 deletions(-)
  21. diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c
  22. index d669e951..27ca7127 100644
  23. --- a/modules/pam_unix/support.c
  24. +++ b/modules/pam_unix/support.c
  25. @@ -601,8 +601,9 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned long long ctrl, const char *name
  26. char *salt = NULL;
  27. int daysleft;
  28. int retval;
  29. - int execloop = 1;
  30. - int nonexistent = 1;
  31. + int blank = 0;
  32. + int execloop;
  33. + int nonexistent_check = 1;
  34. D(("called"));
  35. @@ -632,43 +633,29 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned long long ctrl, const char *name
  36. * are equal, making it more difficult to differentiate existing from
  37. * non-existing users.
  38. */
  39. - while (execloop) {
  40. + for (execloop = 0; execloop < 2; ++execloop) {
  41. retval = get_pwd_hash(pamh, name, &pwd, &salt);
  42. if (retval == PAM_UNIX_RUN_HELPER) {
  43. - execloop = 0;
  44. - if(nonexistent) {
  45. - get_pwd_hash(pamh, "pam_unix_non_existent:", &pwd, &salt);
  46. - }
  47. - /* salt will not be set here so we can return immediately */
  48. if (_unix_run_helper_binary(pamh, NULL, ctrl, name) == PAM_SUCCESS)
  49. - return 1;
  50. - else
  51. - return 0;
  52. + blank = nonexistent_check;
  53. } else if (retval == PAM_USER_UNKNOWN) {
  54. name = "root";
  55. - nonexistent = 0;
  56. - } else {
  57. - execloop = 0;
  58. + nonexistent_check = 0;
  59. + continue;
  60. + } else if (salt != NULL) {
  61. + if (strlen(salt) == 0)
  62. + blank = nonexistent_check;
  63. }
  64. - }
  65. -
  66. - /* Does this user have a password? */
  67. - if (salt == NULL) {
  68. - retval = 0;
  69. - } else {
  70. - if (strlen(salt) == 0)
  71. - retval = 1;
  72. - else
  73. - retval = 0;
  74. + name = "pam_unix_non_existent:";
  75. + /* non-existent user check will not affect the blank value */
  76. }
  77. /* tidy up */
  78. -
  79. if (salt)
  80. _pam_delete(salt);
  81. - return retval;
  82. + return blank;
  83. }
  84. int _unix_verify_password(pam_handle_t * pamh, const char *name