]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2022-2127: winbindd: Fix WINBINDD_PAM_AUTH_CRAP length checks
authorVolker Lendecke <vl@samba.org>
Fri, 20 May 2022 08:55:23 +0000 (10:55 +0200)
committerJule Anger <janger@samba.org>
Fri, 14 Jul 2023 13:16:16 +0000 (15:16 +0200)
With WBFLAG_BIG_NTLMV2_BLOB being set plus lm_resp_len too large you
can crash winbind. We don't independently check lm_resp_len
sufficiently.

Discovered via Coverity ID 1504444 Out-of-bounds access

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15072

Signed-off-by: Volker Lendecke <vl@samba.org>
source3/winbindd/winbindd_pam_auth_crap.c

index fdb8120a6fe76cfcb7e11e1e497062b7254d401a..651d54b01d33c0e911e67532a69353ab204e07fd 100644 (file)
@@ -42,6 +42,9 @@ struct tevent_req *winbindd_pam_auth_crap_send(
        struct winbindd_pam_auth_crap_state *state;
        struct winbindd_domain *domain;
        const char *auth_domain = NULL;
+       bool lmlength_ok = false;
+       bool ntlength_ok = false;
+       bool pwlength_ok = false;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct winbindd_pam_auth_crap_state);
@@ -140,16 +143,24 @@ struct tevent_req *winbindd_pam_auth_crap_send(
                fstrcpy(request->data.auth_crap.workstation, lp_netbios_name());
        }
 
-       if (request->data.auth_crap.lm_resp_len > sizeof(request->data.auth_crap.lm_resp)
-               || request->data.auth_crap.nt_resp_len > sizeof(request->data.auth_crap.nt_resp)) {
-               if (!(request->flags & WBFLAG_BIG_NTLMV2_BLOB) ||
-                    request->extra_len != request->data.auth_crap.nt_resp_len) {
-                       DBG_ERR("Invalid password length %u/%u\n",
-                               request->data.auth_crap.lm_resp_len,
-                               request->data.auth_crap.nt_resp_len);
-                       tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return tevent_req_post(req, ev);
-               }
+       lmlength_ok = (request->data.auth_crap.lm_resp_len <=
+                      sizeof(request->data.auth_crap.lm_resp));
+
+       ntlength_ok = (request->data.auth_crap.nt_resp_len <=
+                      sizeof(request->data.auth_crap.nt_resp));
+
+       ntlength_ok |=
+               ((request->flags & WBFLAG_BIG_NTLMV2_BLOB) &&
+                (request->extra_len == request->data.auth_crap.nt_resp_len));
+
+       pwlength_ok = lmlength_ok && ntlength_ok;
+
+       if (!pwlength_ok) {
+               DBG_ERR("Invalid password length %u/%u\n",
+                       request->data.auth_crap.lm_resp_len,
+                       request->data.auth_crap.nt_resp_len);
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return tevent_req_post(req, ev);
        }
 
        subreq = wb_domain_request_send(state, global_event_context(), domain,