diff options
author | Christian Göttsche <cgzones@googlemail.com> | 2023-01-30 17:56:58 +0100 |
---|---|---|
committer | Christian Göttsche <cgzones@googlemail.com> | 2023-02-28 15:13:15 +0100 |
commit | bcba17939e1b1a568cd4a764534cde74d37078cc (patch) | |
tree | 4f3630f53cd52c2afa59435f5d36db260c1bf4a1 /modules/pam_exec | |
parent | 87ff7a12a55c38873905636eb8d29b4542d828f5 (diff) | |
download | pam-bcba17939e1b1a568cd4a764534cde74d37078cc.tar.gz pam-bcba17939e1b1a568cd4a764534cde74d37078cc.tar.bz2 pam-bcba17939e1b1a568cd4a764534cde74d37078cc.zip |
modules: make use of secure memory erasure
Use empty initialization of structs to minimize the memset() usage, to
reduce the amount of calls which are not sensitive.
Non trivial changes:
- pam_env:
* erase environment variables where possible
- pam_exec:
* erase responce on error
* erase auth token
- pam_pwhistory:
* erase buffers containing old passwords
- pam_selinux: skip overwriting data structure consisting of only
pointers to insensitive data, which also gets free'd afterwards (so
it currently does not protect against double-free or use-after-free on
the member pointers)
- pam_unix: erase cipher data in more places
- pam_userdb: erase password hashes
Diffstat (limited to 'modules/pam_exec')
-rw-r--r-- | modules/pam_exec/pam_exec.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/modules/pam_exec/pam_exec.c b/modules/pam_exec/pam_exec.c index aeb98cdc..9d2145dc 100644 --- a/modules/pam_exec/pam_exec.c +++ b/modules/pam_exec/pam_exec.c @@ -184,6 +184,7 @@ call_exec (const char *pam_type, pam_handle_t *pamh, if (retval != PAM_SUCCESS) { + pam_overwrite_string (resp); _pam_drop (resp); if (retval == PAM_CONV_AGAIN) retval = PAM_INCOMPLETE; @@ -194,6 +195,7 @@ call_exec (const char *pam_type, pam_handle_t *pamh, { pam_set_item (pamh, PAM_AUTHTOK, resp); strncpy (authtok, resp, sizeof(authtok) - 1); + pam_overwrite_string (resp); _pam_drop (resp); } } @@ -202,6 +204,7 @@ call_exec (const char *pam_type, pam_handle_t *pamh, if (pipe(fds) != 0) { + pam_overwrite_array(authtok); pam_syslog (pamh, LOG_ERR, "Could not create pipe: %m"); return PAM_SYSTEM_ERR; } @@ -212,18 +215,21 @@ call_exec (const char *pam_type, pam_handle_t *pamh, { if (pipe(stdout_fds) != 0) { + pam_overwrite_array(authtok); pam_syslog (pamh, LOG_ERR, "Could not create pipe: %m"); return PAM_SYSTEM_ERR; } stdout_file = fdopen(stdout_fds[0], "r"); if (!stdout_file) { + pam_overwrite_array(authtok); pam_syslog (pamh, LOG_ERR, "Could not fdopen pipe: %m"); return PAM_SYSTEM_ERR; } } if (optargc >= argc) { + pam_overwrite_array(authtok); pam_syslog (pamh, LOG_ERR, "No path given as argument"); return PAM_SERVICE_ERR; } @@ -231,13 +237,16 @@ call_exec (const char *pam_type, pam_handle_t *pamh, memset(&newsa, '\0', sizeof(newsa)); newsa.sa_handler = SIG_DFL; if (sigaction(SIGCHLD, &newsa, &oldsa) == -1) { + pam_overwrite_array(authtok); pam_syslog(pamh, LOG_ERR, "failed to reset SIGCHLD handler: %m"); return PAM_SYSTEM_ERR; } pid = fork(); - if (pid == -1) + if (pid == -1) { + pam_overwrite_array(authtok); return PAM_SYSTEM_ERR; + } if (pid > 0) /* parent */ { int status = 0; @@ -255,6 +264,8 @@ call_exec (const char *pam_type, pam_handle_t *pamh, close(fds[1]); } + pam_overwrite_array(authtok); + if (use_stdout) { char buf[4096]; @@ -325,6 +336,8 @@ call_exec (const char *pam_type, pam_handle_t *pamh, enum pam_modutil_redirect_fd redirect_stdout = (use_stdout || logfile) ? PAM_MODUTIL_IGNORE_FD : PAM_MODUTIL_NULL_FD; + pam_overwrite_array(authtok); + /* First, move all the pipes off of stdin, stdout, and stderr, to ensure * that calls to dup2 won't close them. */ |