newrole: ensure password memory erasure

Compiler can optimize calls to memset(3), due to the as-if rule, away if
the object is not accessed later on.  Use a wrapper using volatile
pointers to ensure the memory is guaranteed to be erased.  Also erase
the encrypted password.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
This commit is contained in:
Christian Göttsche 2022-02-22 14:51:43 +01:00 committed by James Carter
parent 1af8089824
commit c71d14e824

View File

@ -333,6 +333,14 @@ static int read_pam_config(void)
#define PASSWORD_PROMPT _("Password:") /* prompt for getpass() */
static void memzero(void *ptr, size_t size)
{
volatile unsigned char * volatile p = ptr;
while (size--) {
*p++ = '\0';
}
}
/* authenticate_via_shadow_passwd()
*
* in: uname - the calling user's user name
@ -351,6 +359,7 @@ static int authenticate_via_shadow_passwd(const char *uname)
struct spwd *p_shadow_line;
char *unencrypted_password_s;
char *encrypted_password_s;
int ret;
setspent();
p_shadow_line = getspnam(uname);
@ -371,12 +380,15 @@ static int authenticate_via_shadow_passwd(const char *uname)
errno = 0;
encrypted_password_s = crypt(unencrypted_password_s,
p_shadow_line->sp_pwdp);
memset(unencrypted_password_s, 0, strlen(unencrypted_password_s));
memzero(unencrypted_password_s, strlen(unencrypted_password_s));
if (errno || !encrypted_password_s) {
fprintf(stderr, _("Cannot encrypt password.\n"));
return 0;
}
return (!strcmp(encrypted_password_s, p_shadow_line->sp_pwdp));
ret = !strcmp(encrypted_password_s, p_shadow_line->sp_pwdp);
memzero(encrypted_password_s, strlen(encrypted_password_s));
return ret;
}
#endif /* if/else USE_PAM */