summaryrefslogtreecommitdiff
path: root/manual
diff options
context:
space:
mode:
authorJoseph Myers <josmyers@redhat.com>2025-10-01 15:14:09 +0000
committerJoseph Myers <josmyers@redhat.com>2025-10-01 15:14:09 +0000
commit0f201f4a817e39c01c502f523d4ea3c91f242767 (patch)
tree363f693dbff6fd086faf1bfd89e014346837436e /manual
parenta8ad2e9e431bac3ea207be07c64cddb72c290cde (diff)
Implement C23 memset_explicit (bug 32378)
Add the C23 memset_explicit function to glibc. Everything here is closely based on the approach taken for explicit_bzero. This includes the bits that relate to internal uses of explicit_bzero within glibc (although we don't currently have any such internal uses of memset_explicit), and also includes the nonnull attribute (when we move to nonnull_if_nonzero for various functions following C2y, this function should be included in that change). The function is declared both for __USE_MISC and for __GLIBC_USE (ISOC23) (so by default not just for compilers defaulting to C23 mode). Tested for x86_64 and x86.
Diffstat (limited to 'manual')
-rw-r--r--manual/maint.texi2
-rw-r--r--manual/string.texi39
2 files changed, 33 insertions, 8 deletions
diff --git a/manual/maint.texi b/manual/maint.texi
index 58479ec723..2d540ced9b 100644
--- a/manual/maint.texi
+++ b/manual/maint.texi
@@ -323,6 +323,8 @@ The following functions and macros are fortified in @theglibc{}:
@item @code{memset}
+@item @code{memset_explicit}
+
@item @code{mq_open}
@item @code{obstack_printf}
diff --git a/manual/string.texi b/manual/string.texi
index feba0b7ae3..85318973d8 100644
--- a/manual/string.texi
+++ b/manual/string.texi
@@ -2436,8 +2436,8 @@ heap object containing the sensitive data after it's deallocated.
Since erasure is a precaution against bugs, this optimization is
inappropriate.
-The function @code{explicit_bzero} erases a block of memory, and
-guarantees that the compiler will not remove the erasure as
+The functions @code{explicit_bzero} and @code{memset_explicit} erase a
+block of memory, and guarantee that the compiler will not remove the erasure as
``unnecessary.''
@smallexample
@@ -2463,16 +2463,18 @@ void encrypt_with_phrase (const char *phrase, const char *in,
In this example, if @code{memset}, @code{bzero}, or a hand-written
loop had been used, the compiler might remove them as ``unnecessary.''
-@strong{Warning:} @code{explicit_bzero} does not guarantee that
+@strong{Warning:} @code{explicit_bzero} and @code{memset_explicit} do
+not guarantee that
sensitive data is @emph{completely} erased from the computer's memory.
There may be copies in temporary storage areas, such as registers and
``scratch'' stack space; since these are invisible to the source code,
a library function cannot erase them.
-Also, @code{explicit_bzero} only operates on RAM. If a sensitive data
-object never needs to have its address taken other than to call
-@code{explicit_bzero}, it might be stored entirely in CPU registers
-@emph{until} the call to @code{explicit_bzero}. Then it will be
+Also, @code{explicit_bzero} and @code{memset_explicit} only operate on
+RAM. If a sensitive data object never needs to have its address taken
+other than to call @code{explicit_bzero} or @code{memset_explicit}, it
+might be stored entirely in CPU registers @emph{until} the call to
+@code{explicit_bzero} or @code{memset_explicit}. Then it will be
copied into RAM, the copy will be erased, and the original will remain
intact. Data in RAM is more likely to be exposed by a bug than data
in registers, so this creates a brief window where the data is at
@@ -2489,10 +2491,12 @@ variable itself is not @code{volatile}, some compilers will ignore the
qualification on the pointer and remove the erasure anyway.
Having said all that, in most situations, using @code{explicit_bzero}
+or @code{memset_explicit}
is better than not using it. At present, the only way to do a more
thorough job is to write the entire sensitive operation in assembly
language. We anticipate that future compilers will recognize calls to
-@code{explicit_bzero} and take appropriate steps to erase all the
+@code{explicit_bzero} or @code{memset_explicit} and take appropriate
+steps to erase all the
copies of the affected data, wherever they may be.
@deftypefun void explicit_bzero (void *@var{block}, size_t @var{len})
@@ -2520,6 +2524,25 @@ functionality under a different name, such as @code{explicit_memset},
systems it may be in @file{strings.h} instead.
@end deftypefun
+@deftypefun {void *} memset_explicit (void *@var{block}, int @var{c}, size_t @var{size})
+@standards{C23, string.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+
+This function copies the value of @var{c} (converted to an
+@code{unsigned char}) into each of the first @var{size} bytes of the
+object beginning at @var{block}, just as @code{memset} would. It
+returns the value of @var{block}. The bytes are always written, even
+if the compiler could determine that this is ``unnecessary'' because
+no correct program could read them back.
+
+@strong{Note:} The @emph{only} optimization that @code{memset_explicit}
+disables is removal of ``unnecessary'' writes to memory. The compiler
+can perform all the other optimizations that it could for a call to
+@code{memset}. For instance, it may replace the function call with
+inline memory writes, and it may assume that @var{block} cannot be a
+null pointer.
+@end deftypefun
+
@node Shuffling Bytes
@section Shuffling Bytes