diff options
author | Christian Göttsche <cgzones@googlemail.com> | 2023-01-30 17:55:27 +0100 |
---|---|---|
committer | Christian Göttsche <cgzones@googlemail.com> | 2023-02-28 15:13:15 +0100 |
commit | e2d01a42c16e0d074764c3e8d2f6a2e6c0ceafc4 (patch) | |
tree | 77a5a3305062243a0a9e76cd52be77a83bb0da76 | |
parent | 19a29268178951988eca29a7830f24bfef300c3c (diff) | |
download | pam-e2d01a42c16e0d074764c3e8d2f6a2e6c0ceafc4.tar.gz pam-e2d01a42c16e0d074764c3e8d2f6a2e6c0ceafc4.tar.bz2 pam-e2d01a42c16e0d074764c3e8d2f6a2e6c0ceafc4.zip |
libpam: make use of secure memory erasure
Non trivial changes:
- erase responses in pam_get_authtok_internal() on error branch
-rw-r--r-- | libpam/include/pam_inline.h | 4 | ||||
-rw-r--r-- | libpam/pam_end.c | 31 | ||||
-rw-r--r-- | libpam/pam_env.c | 9 | ||||
-rw-r--r-- | libpam/pam_get_authtok.c | 17 | ||||
-rw-r--r-- | libpam/pam_handlers.c | 2 | ||||
-rw-r--r-- | libpam/pam_item.c | 20 | ||||
-rw-r--r-- | libpam/pam_vprompt.c | 6 |
7 files changed, 48 insertions, 41 deletions
diff --git a/libpam/include/pam_inline.h b/libpam/include/pam_inline.h index 6fe37857..7721c0b7 100644 --- a/libpam/include/pam_inline.h +++ b/libpam/include/pam_inline.h @@ -161,7 +161,7 @@ pam_read_passwords(int fd, int npass, char **passwords) if (npass > 0) { memcpy(passwords[i], pptr, rbytes); } - memset(pptr, '\0', rbytes); + pam_overwrite_n(pptr, rbytes); } } offset += rbytes; @@ -169,7 +169,7 @@ pam_read_passwords(int fd, int npass, char **passwords) /* clear up */ if (offset > 0 && npass > 0) { - memset(passwords[i], '\0', offset); + pam_overwrite_n(passwords[i], offset); } return i; diff --git a/libpam/pam_end.c b/libpam/pam_end.c index 406b1478..9179a915 100644 --- a/libpam/pam_end.c +++ b/libpam/pam_end.c @@ -5,6 +5,7 @@ */ #include "pam_private.h" +#include "pam_inline.h" #include <stdlib.h> @@ -41,34 +42,34 @@ int pam_end(pam_handle_t *pamh, int pam_status) _pam_drop_env(pamh); /* purge the environment */ - _pam_overwrite(pamh->authtok); /* blank out old token */ + pam_overwrite_string(pamh->authtok); /* blank out old token */ _pam_drop(pamh->authtok); - _pam_overwrite(pamh->oldauthtok); /* blank out old token */ + pam_overwrite_string(pamh->oldauthtok); /* blank out old token */ _pam_drop(pamh->oldauthtok); - _pam_overwrite(pamh->former.prompt); + pam_overwrite_string(pamh->former.prompt); _pam_drop(pamh->former.prompt); /* drop saved prompt */ - _pam_overwrite(pamh->service_name); + pam_overwrite_string(pamh->service_name); _pam_drop(pamh->service_name); - _pam_overwrite(pamh->user); + pam_overwrite_string(pamh->user); _pam_drop(pamh->user); - _pam_overwrite(pamh->confdir); + pam_overwrite_string(pamh->confdir); _pam_drop(pamh->confdir); - _pam_overwrite(pamh->prompt); + pam_overwrite_string(pamh->prompt); _pam_drop(pamh->prompt); /* prompt for pam_get_user() */ - _pam_overwrite(pamh->tty); + pam_overwrite_string(pamh->tty); _pam_drop(pamh->tty); - _pam_overwrite(pamh->rhost); + pam_overwrite_string(pamh->rhost); _pam_drop(pamh->rhost); - _pam_overwrite(pamh->ruser); + pam_overwrite_string(pamh->ruser); _pam_drop(pamh->ruser); _pam_drop(pamh->pam_conversation); @@ -76,16 +77,16 @@ int pam_end(pam_handle_t *pamh, int pam_status) _pam_drop(pamh->former.substates); - _pam_overwrite(pamh->xdisplay); + pam_overwrite_string(pamh->xdisplay); _pam_drop(pamh->xdisplay); - _pam_overwrite(pamh->xauth.name); + pam_overwrite_string(pamh->xauth.name); _pam_drop(pamh->xauth.name); - _pam_overwrite_n(pamh->xauth.data, (unsigned int)pamh->xauth.datalen); + pam_overwrite_n(pamh->xauth.data, (unsigned int)pamh->xauth.datalen); _pam_drop(pamh->xauth.data); - _pam_overwrite_n((char *)&pamh->xauth, sizeof(pamh->xauth)); + pam_overwrite_object(&pamh->xauth); - _pam_overwrite(pamh->authtok_type); + pam_overwrite_string(pamh->authtok_type); _pam_drop(pamh->authtok_type); /* and finally liberate the memory for the pam_handle structure */ diff --git a/libpam/pam_env.c b/libpam/pam_env.c index 1c8403d6..bfeb57ab 100644 --- a/libpam/pam_env.c +++ b/libpam/pam_env.c @@ -11,6 +11,7 @@ */ #include "pam_private.h" +#include "pam_inline.h" #include <string.h> #include <stdlib.h> @@ -100,7 +101,7 @@ void _pam_drop_env(pam_handle_t *pamh) for (i=pamh->env->requested-1; i-- > 0; ) { D(("dropping #%3d>%s<", i, pamh->env->list[i])); - _pam_overwrite(pamh->env->list[i]); /* clean */ + pam_overwrite_string(pamh->env->list[i]); /* clean */ _pam_drop(pamh->env->list[i]); /* forget */ } pamh->env->requested = 0; @@ -227,7 +228,7 @@ int pam_putenv(pam_handle_t *pamh, const char *name_value) } else { /* replace old */ D(("replacing item: %s\n with: %s" , pamh->env->list[item], name_value)); - _pam_overwrite(pamh->env->list[item]); + pam_overwrite_string(pamh->env->list[item]); _pam_drop(pamh->env->list[item]); } @@ -261,7 +262,7 @@ int pam_putenv(pam_handle_t *pamh, const char *name_value) */ D(("deleting: env#%3d:[%s]", item, pamh->env->list[item])); - _pam_overwrite(pamh->env->list[item]); + pam_overwrite_string(pamh->env->list[item]); _pam_drop(pamh->env->list[item]); --(pamh->env->requested); D(("mmove: item[%d]+%d -> item[%d]" @@ -341,7 +342,7 @@ static char **_copy_env(pam_handle_t *pamh) /* out of memory */ while (dump[++i]) { - _pam_overwrite(dump[i]); + pam_overwrite_string(dump[i]); _pam_drop(dump[i]); } _pam_drop(dump); diff --git a/libpam/pam_get_authtok.c b/libpam/pam_get_authtok.c index 3fa7f7df..3f383339 100644 --- a/libpam/pam_get_authtok.c +++ b/libpam/pam_get_authtok.c @@ -33,6 +33,7 @@ #include "config.h" #include "pam_private.h" +#include "pam_inline.h" #include <security/pam_ext.h> @@ -174,6 +175,10 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item, (chpass > 1 && resp[1] == NULL)) { /* We want to abort */ + pam_overwrite_string (resp[0]); + _pam_drop (resp[0]); + pam_overwrite_string (resp[1]); + _pam_drop (resp[1]); if (chpass) pam_error (pamh, _("Password change has been aborted.")); return PAM_AUTHTOK_ERR; @@ -182,18 +187,18 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item, if (chpass > 1 && strcmp (resp[0], resp[1]) != 0) { pam_error (pamh, MISTYPED_PASS); - _pam_overwrite (resp[0]); + pam_overwrite_string (resp[0]); _pam_drop (resp[0]); - _pam_overwrite (resp[1]); + pam_overwrite_string (resp[1]); _pam_drop (resp[1]); return PAM_TRY_AGAIN; } - _pam_overwrite (resp[1]); + pam_overwrite_string (resp[1]); _pam_drop (resp[1]); retval = pam_set_item (pamh, item, resp[0]); - _pam_overwrite (resp[0]); + pam_overwrite_string (resp[0]); _pam_drop (resp[0]); if (retval != PAM_SUCCESS) return retval; @@ -263,13 +268,13 @@ pam_get_authtok_verify (pam_handle_t *pamh, const char **authtok, { pam_set_item (pamh, PAM_AUTHTOK, NULL); pam_error (pamh, MISTYPED_PASS); - _pam_overwrite (resp); + pam_overwrite_string (resp); _pam_drop (resp); return PAM_TRY_AGAIN; } retval = pam_set_item (pamh, PAM_AUTHTOK, resp); - _pam_overwrite (resp); + pam_overwrite_string (resp); _pam_drop (resp); if (retval != PAM_SUCCESS) return retval; diff --git a/libpam/pam_handlers.c b/libpam/pam_handlers.c index 6629480e..1f1917b5 100644 --- a/libpam/pam_handlers.c +++ b/libpam/pam_handlers.c @@ -1033,7 +1033,7 @@ void _pam_free_handlers_aux(struct handler **hp) _pam_drop(h->argv); /* This is all allocated in a single chunk */ _pam_drop(h->mod_name); h = h->next; - memset(last, 0, sizeof(*last)); + pam_overwrite_object(last); free(last); } diff --git a/libpam/pam_item.c b/libpam/pam_item.c index d6af710b..42857da5 100644 --- a/libpam/pam_item.c +++ b/libpam/pam_item.c @@ -5,6 +5,7 @@ */ #include "pam_private.h" +#include "pam_inline.h" #include <ctype.h> #include <stdlib.h> @@ -79,7 +80,7 @@ int pam_set_item (pam_handle_t *pamh, int item_type, const void *item) */ if (__PAM_FROM_MODULE(pamh)) { if (pamh->authtok != item) { - _pam_overwrite(pamh->authtok); + pam_overwrite_string(pamh->authtok); TRY_SET(pamh->authtok, item); } } else { @@ -95,7 +96,7 @@ int pam_set_item (pam_handle_t *pamh, int item_type, const void *item) */ if (__PAM_FROM_MODULE(pamh)) { if (pamh->oldauthtok != item) { - _pam_overwrite(pamh->oldauthtok); + pam_overwrite_string(pamh->oldauthtok); TRY_SET(pamh->oldauthtok, item); } } else { @@ -139,24 +140,23 @@ int pam_set_item (pam_handle_t *pamh, int item_type, const void *item) if (&pamh->xauth == item) break; if (pamh->xauth.namelen) { - _pam_overwrite(pamh->xauth.name); + pam_overwrite_string(pamh->xauth.name); free(pamh->xauth.name); } if (pamh->xauth.datalen) { - _pam_overwrite_n(pamh->xauth.data, - (unsigned int) pamh->xauth.datalen); + pam_overwrite_n(pamh->xauth.data, (unsigned int) pamh->xauth.datalen); free(pamh->xauth.data); } pamh->xauth = *((const struct pam_xauth_data *) item); if ((pamh->xauth.name=_pam_strdup(pamh->xauth.name)) == NULL) { - memset(&pamh->xauth, '\0', sizeof(pamh->xauth)); + pam_overwrite_object(&pamh->xauth); return PAM_BUF_ERR; } if ((pamh->xauth.data=_pam_memdup(pamh->xauth.data, pamh->xauth.datalen)) == NULL) { - _pam_overwrite(pamh->xauth.name); + pam_overwrite_string(pamh->xauth.name); free(pamh->xauth.name); - memset(&pamh->xauth, '\0', sizeof(pamh->xauth)); + pam_overwrite_object(&pamh->xauth); return PAM_BUF_ERR; } break; @@ -330,7 +330,7 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt) /* ok, we can resume where we left off last time */ pamh->former.want_user = PAM_FALSE; - _pam_overwrite(pamh->former.prompt); + pam_overwrite_string(pamh->former.prompt); _pam_drop(pamh->former.prompt); } @@ -388,7 +388,7 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt) * note 'resp' is allocated by the application and is * correctly free()'d here */ - _pam_drop_reply(resp, 1); + pam_drop_response(resp, 1); } D(("completed")); diff --git a/libpam/pam_vprompt.c b/libpam/pam_vprompt.c index c53079b5..8c9d63d5 100644 --- a/libpam/pam_vprompt.c +++ b/libpam/pam_vprompt.c @@ -40,10 +40,10 @@ #include <errno.h> #include <security/pam_modules.h> -#include <security/_pam_macros.h> #include <security/pam_ext.h> #include "pam_private.h" +#include "pam_inline.h" int pam_vprompt (pam_handle_t *pamh, int style, char **response, @@ -88,10 +88,10 @@ pam_vprompt (pam_handle_t *pamh, int style, char **response, *response = pam_resp == NULL ? NULL : pam_resp->resp; else if (pam_resp && pam_resp->resp) { - _pam_overwrite (pam_resp->resp); + pam_overwrite_string (pam_resp->resp); _pam_drop (pam_resp->resp); } - _pam_overwrite (msgbuf); + pam_overwrite_string (msgbuf); _pam_drop (pam_resp); free (msgbuf); if (retval != PAM_SUCCESS) |