+2020-05-27 Daiki Ueno <ueno@gnu.org>
+
+ read-file: add RF_SENSITIVE flag
+ * lib/read-file.h (RF_SENSITIVE): New define.
+ * lib/read-file.c (fread_file, read_file): Take into account of
+ RF_SENSITIVE flag.
+ * modules/read-file (Depends-on): Add explicit_bzero.
+ This adds an alternative behavior of those functions to explicitly
+ clear the internal memory block when it becomes unused. This is
+ useful for reading sensitive information from a file.
+
2020-05-27 Daiki Ueno <ueno@gnu.org>
read-file: add flags to modify reading behavior
/* Get malloc, realloc, free. */
#include <stdlib.h>
+/* Get explicit_bzero, memcpy. */
+#include <string.h>
+
/* Get errno. */
#include <errno.h>
and set *LENGTH to the length of the string. The string is
zero-terminated, but the terminating zero byte is not counted in
*LENGTH. On errors, *LENGTH is undefined, errno preserves the
- values set by system functions (if any), and NULL is returned. */
+ values set by system functions (if any), and NULL is returned.
+
+ If the RF_SENSITIVE flag is set in FLAGS, the memory buffer
+ internally allocated will be cleared upon failure. */
char *
-fread_file (FILE *stream, int flags _GL_UNUSED, size_t *length)
+fread_file (FILE *stream, int flags, size_t *length)
{
char *buf = NULL;
size_t alloc = BUFSIZ;
/* Shrink the allocated memory if possible. */
if (size < alloc - 1)
{
- char *smaller_buf = realloc (buf, size + 1);
- if (smaller_buf != NULL)
- buf = smaller_buf;
+ if (flags & RF_SENSITIVE)
+ {
+ char *smaller_buf = malloc (size + 1);
+ if (smaller_buf == NULL)
+ explicit_bzero (buf + size, alloc - size);
+ else
+ {
+ memcpy (smaller_buf, buf, size);
+ explicit_bzero (buf, alloc);
+ free (buf);
+ buf = smaller_buf;
+ }
+ }
+ else
+ {
+ char *smaller_buf = realloc (buf, size + 1);
+ if (smaller_buf != NULL)
+ buf = smaller_buf;
+ }
}
buf[size] = '\0';
{
char *new_buf;
+ size_t save_alloc = alloc;
if (alloc == PTRDIFF_MAX)
{
else
alloc = PTRDIFF_MAX;
- if (!(new_buf = realloc (buf, alloc)))
+ if (flags & RF_SENSITIVE)
+ {
+ new_buf = malloc (alloc);
+ if (!new_buf)
+ {
+ /* BUF should be cleared below after the loop. */
+ save_errno = errno;
+ break;
+ }
+ memcpy (new_buf, buf, save_alloc);
+ explicit_bzero (buf, save_alloc);
+ free (buf);
+ buf = new_buf;
+ }
+ else if (!(new_buf = realloc (buf, alloc)))
{
save_errno = errno;
break;
}
}
+ if (flags & RF_SENSITIVE)
+ explicit_bzero (buf, alloc);
+
free (buf);
errno = save_errno;
return NULL;
any), and NULL is returned.
If the RF_BINARY flag is set in FLAGS, the file is opened in binary
- mode. */
+ mode. If the RF_SENSITIVE flag is set in FLAGS, the memory buffer
+ internally allocated will be cleared upon failure. */
char *
read_file (const char *filename, int flags, size_t *length)
{
if (out)
{
save_errno = errno;
+ if (flags & RF_SENSITIVE)
+ explicit_bzero (out, *length);
free (out);
}
errno = save_errno;