summaryrefslogtreecommitdiff
path: root/libpam/include/pam_inline.h
diff options
context:
space:
mode:
Diffstat (limited to 'libpam/include/pam_inline.h')
-rw-r--r--libpam/include/pam_inline.h64
1 files changed, 62 insertions, 2 deletions
diff --git a/libpam/include/pam_inline.h b/libpam/include/pam_inline.h
index ec2f3bf0..7721c0b7 100644
--- a/libpam/include/pam_inline.h
+++ b/libpam/include/pam_inline.h
@@ -9,6 +9,7 @@
#define PAM_INLINE_H
#include "pam_cc_compat.h"
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
@@ -33,6 +34,12 @@
* 0, otherwise.
*/
#define PAM_MUST_BE_ARRAY(a_) PAM_FAIL_BUILD_ON_ZERO(!PAM_IS_NOT_ARRAY(a_))
+/*
+ * Evaluates to
+ * - a syntax error if the argument is an array,
+ * 0, otherwise.
+ */
+#define PAM_MUST_NOT_BE_ARRAY(a_) PAM_FAIL_BUILD_ON_ZERO(PAM_IS_NOT_ARRAY(a_))
/* Evaluates to the number of elements in the specified array. */
#define PAM_ARRAY_SIZE(a_) (sizeof(a_) / sizeof((a_)[0]) + PAM_MUST_BE_ARRAY(a_))
@@ -66,6 +73,59 @@ pam_str_skip_icase_prefix_len(const char *str, const char *prefix, size_t prefix
#define pam_str_skip_icase_prefix(str_, prefix_) \
pam_str_skip_icase_prefix_len((str_), (prefix_), sizeof(prefix_) - 1 + PAM_MUST_BE_ARRAY(prefix_))
+
+/*
+ * Macros to securely erase memory
+ */
+
+#ifdef HAVE_MEMSET_EXPLICIT
+static inline void pam_overwrite_n(void *ptr, size_t len)
+{
+ if (ptr)
+ memset_explicit(ptr, len);
+}
+#elif defined HAVE_EXPLICIT_BZERO
+static inline void pam_overwrite_n(void *ptr, size_t len)
+{
+ if (ptr)
+ explicit_bzero(ptr, len);
+}
+#else
+static inline void pam_overwrite_n(void *ptr, size_t len)
+{
+ if (ptr) {
+ ptr = memset(ptr, '\0', len);
+ __asm__ __volatile__ ("" : : "r"(ptr) : "memory");
+ }
+}
+#endif
+
+#define pam_overwrite_string(x) \
+do { \
+ char *xx__ = (x) + PAM_MUST_NOT_BE_ARRAY(x); \
+ if (xx__) \
+ pam_overwrite_n(xx__, strlen(xx__)); \
+} while(0)
+
+#define pam_overwrite_array(x) pam_overwrite_n(x, sizeof(x) + PAM_MUST_BE_ARRAY(x))
+
+#define pam_overwrite_object(x) pam_overwrite_n(x, sizeof(*(x)) + PAM_MUST_NOT_BE_ARRAY(x))
+
+static inline void
+pam_drop_response(struct pam_response *reply, int replies)
+{
+ int reply_i;
+
+ for (reply_i = 0; reply_i < replies; ++reply_i) {
+ if (reply[reply_i].resp) {
+ pam_overwrite_string(reply[reply_i].resp);
+ free(reply[reply_i].resp);
+ }
+ }
+ free(reply);
+}
+
+
static inline int
pam_read_passwords(int fd, int npass, char **passwords)
{
@@ -101,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;
@@ -109,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;