From 77b5d99007cfef4d73d76fd6f0c26584891608e5 Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Tue, 25 Jun 2024 22:39:13 +0900 Subject: [PATCH] CVE-2024-38439,CVE-2024-38440,CVE-2024-38441: Harden user login * Check that input buffer can accommodate null terminator * Input buffer null pointer and length checks Signed-off-by: Daniel Markstedt --- etc/afpd/auth.c | 10 ++++++++++ etc/afpd/directory.c | 3 +++ etc/uams/uams_dhx_pam.c | 4 ++++ etc/uams/uams_pam.c | 2 ++ etc/uams/uams_passwd.c | 4 ++-- 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/etc/afpd/auth.c b/etc/afpd/auth.c index bba99dae562..d682ec51192 100644 --- a/etc/afpd/auth.c +++ b/etc/afpd/auth.c @@ -610,6 +610,9 @@ int afp_login(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbufl if (ibuflen < 2) return send_reply(obj, AFPERR_BADVERS ); + if (ibuf == NULL) + return send_reply(obj, AFPERR_PARAM); + ibuf++; len = (unsigned char) *ibuf++; ibuflen -= 2; @@ -664,6 +667,9 @@ int afp_login_ext(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *r if (ibuflen < 5) return send_reply(obj, AFPERR_BADVERS ); + if (ibuf == NULL) + return send_reply(obj, AFPERR_PARAM); + ibuf++; ibuf++; /* pad */ ibuf +=2; /* flag */ @@ -751,6 +757,10 @@ int afp_login_ext(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *r return send_reply(obj, AFPERR_PARAM); } #endif + if (ibuflen < len) { + LOG(log_error, logtype_afpd, "login_ext: Login failed. Invalid directory service name!" ); + return send_reply(obj, AFPERR_PARAM); + } ibuf += len; ibuflen -= len; diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index 42215b4acc1..30c754d28b8 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -2330,6 +2330,9 @@ int afp_mapname(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t return( AFPERR_PARAM ); } + if (len >= ibuflen - 1) + return AFPERR_PARAM; + ibuf[ len ] = '\0'; if ( len == 0 ) diff --git a/etc/uams/uams_dhx_pam.c b/etc/uams/uams_dhx_pam.c index 650059f1e04..c093eb5db5d 100644 --- a/etc/uams/uams_dhx_pam.c +++ b/etc/uams/uams_dhx_pam.c @@ -682,6 +682,8 @@ static int pam_changepw(void *obj, unsigned char *username, /* Set these things up for the conv function. the old password * is at the end. */ ibuf += KEYSIZE; + if (ibuflen <= PASSWDLEN + PASSWDLEN) + return AFPERR_PARAM; ibuf[PASSWDLEN + PASSWDLEN] = '\0'; PAM_password = ibuf + PASSWDLEN; @@ -712,6 +714,8 @@ static int pam_changepw(void *obj, unsigned char *username, /* new password */ PAM_password = ibuf; + if (ibuflen <= PASSWDLEN) + return AFPERR_PARAM; ibuf[PASSWDLEN] = '\0'; /* this really does need to be done as root */ diff --git a/etc/uams/uams_pam.c b/etc/uams/uams_pam.c index cade1a338c7..7b51cdbb8c8 100644 --- a/etc/uams/uams_pam.c +++ b/etc/uams/uams_pam.c @@ -141,6 +141,8 @@ static int login(void *obj, char *username, int ulen, struct passwd **uam_pwd, hostname = NULL; } + if (ibuflen <= PASSWDLEN) + return AFPERR_PARAM; ibuf[ PASSWDLEN ] = '\0'; if (( pwd = uam_getname(obj, username, ulen)) == NULL ) { diff --git a/etc/uams/uams_passwd.c b/etc/uams/uams_passwd.c index 6f0be909339..3d76261a77b 100644 --- a/etc/uams/uams_passwd.c +++ b/etc/uams/uams_passwd.c @@ -55,7 +55,7 @@ static int pwd_login(void *obj, char *username, int ulen, struct passwd **uam_pw struct spwd *sp; #endif /* SHADOWPW */ - if (ibuflen < PASSWDLEN) { + if (ibuflen <= PASSWDLEN) { return( AFPERR_PARAM ); } ibuf[ PASSWDLEN ] = '\0'; @@ -158,7 +158,7 @@ static int passwd_login_ext(void *obj, char *uname, struct passwd **uam_pwd, (void *) &username, &ulen) < 0) return AFPERR_MISC; - if (*uname != 3) + if (*uname != 3 || ibuflen < 2) return AFPERR_PARAM; uname++; memcpy(&temp16, uname, sizeof(temp16));