This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 0/4] explicit_bzero, this time for sure
- From: Zack Weinberg <zackw at panix dot com>
- To: libc-alpha at sourceware dot org
- Cc: fweimer at redhat dot com
- Date: Wed, 17 Aug 2016 13:19:13 -0400
- Subject: [PATCH 0/4] explicit_bzero, this time for sure
- Authentication-results: sourceware.org; auth=none
Now that we're in full swing on 2.25 (and I'm not trying to hit a
conference deadline), here is an updated version of the explicit_bzero
patchset. I came up with a better implementation strategy:
void explicit_bzero (void *s, size_t n)
{
memset (s, 0, n);
__glibc_read_memory (s, n);
}
where __glibc_read_memory (const void *, size_t) is a function that
does nothing -- but the compiler is not allowed to see its definition
(while compiling anything else). Experimenting with this set of source
files
/* a.c */
#include <stddef.h>
extern void explicit_bzero(void *s, size_t len)
__attribute__((nothrow, leaf));
int main(void)
{
char buf[24];
explicit_bzero(buf, sizeof buf);
return 0;
}
/* b.c */
#include <string.h>
extern void __glibc_read_memory(const void *s, size_t len)
__attribute__((noinline, nothrow, leaf));
void __attribute__((nothrow, leaf))
explicit_bzero(void *s, size_t len)
{
memset(s, 0, len);
__glibc_read_memory(s, len);
}
/* c.c */
#include <stddef.h>
void __attribute__((noinline, nothrow, leaf))
__glibc_read_memory(const void *s, size_t len)
{
}
I find that, with the current generation of compilers, `buf` and the
clearing thereof will not be deleted as long as c.c is *not* subject
to -flto; it is OK to apply -flto + -O2 to the entire rest of the
program.
Compared to the previous implementation, this involves neither
monkeying around with questionable GCC extensions nor the severe
optimization barrier applied by asm ("" ::: "memory"), and
fortification is much simpler. It generates slightly worse machine
code in that there will be an unremovable call to __glibc_read_memory
after every explicit_bzero operation, even if the clear itself is
inlined, but I think that will be best addressed by compilers that
actually understand what one is trying to do here.
I have also reorganized the patch series -- 1/4 is logically
independent, adding tests for bcopy and bzero fortification, and I'd
like to go ahead and land that ahead of the rest of the series;
fortification logic has been split from the core as requested by
Florian.
If anyone knows whether or not the `asm volatile ("");` in the
definition of __glibc_read_memory actually makes any difference to
anything I would like to hear about it. If anyone has any ideas for
how to write a test that will start failing if a compiler ever learns
to "see through" __glibc_read_memory, I would like to hear about that,
too. (I can imagine a way to do it with gcc's scan-assembler tests,
but we don't have those here.)
zw
Zack Weinberg (4):
Add tests for fortification of bcopy and bzero.
Add new string function, explicit_bzero (from OpenBSD).
Add fortification support for explicit_bzero.
Use explicit_bzero where appropriate,
crypt/crypt-entry.c | 11 +++
crypt/md5-crypt.c | 8 +-
crypt/sha256-crypt.c | 14 +--
crypt/sha512-crypt.c | 14 +--
debug/tst-chk1.c | 89 ++++++++++++++++++
include/string.h | 2 +
manual/string.texi | 101 +++++++++++++++++++++
string/Makefile | 10 +-
string/Versions | 7 ++
string/bits/string2.h | 14 ++-
string/bits/string3.h | 7 ++
string/explicit_bzero.c | 30 ++++++
string/read_memory.c | 41 +++++++++
string/string.h | 9 ++
string/test-explicit_bzero.c | 20 ++++
string/test-memset.c | 10 +-
sysdeps/arm/nacl/libc.abilist | 2 +
sysdeps/unix/sysv/linux/aarch64/libc.abilist | 2 +
sysdeps/unix/sysv/linux/alpha/libc.abilist | 2 +
sysdeps/unix/sysv/linux/arm/libc.abilist | 2 +
sysdeps/unix/sysv/linux/hppa/libc.abilist | 2 +
sysdeps/unix/sysv/linux/i386/libc.abilist | 2 +
sysdeps/unix/sysv/linux/ia64/libc.abilist | 2 +
sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist | 2 +
sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist | 2 +
sysdeps/unix/sysv/linux/microblaze/libc.abilist | 2 +
.../unix/sysv/linux/mips/mips32/fpu/libc.abilist | 2 +
.../unix/sysv/linux/mips/mips32/nofpu/libc.abilist | 2 +
.../unix/sysv/linux/mips/mips64/n32/libc.abilist | 2 +
.../unix/sysv/linux/mips/mips64/n64/libc.abilist | 2 +
sysdeps/unix/sysv/linux/nios2/libc.abilist | 2 +
.../sysv/linux/powerpc/powerpc32/fpu/libc.abilist | 2 +
.../linux/powerpc/powerpc32/nofpu/libc.abilist | 2 +
.../sysv/linux/powerpc/powerpc64/libc-le.abilist | 2 +
.../unix/sysv/linux/powerpc/powerpc64/libc.abilist | 2 +
sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist | 2 +
sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist | 2 +
sysdeps/unix/sysv/linux/sh/libc.abilist | 2 +
sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist | 2 +
sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist | 2 +
.../sysv/linux/tile/tilegx/tilegx32/libc.abilist | 2 +
.../sysv/linux/tile/tilegx/tilegx64/libc.abilist | 2 +
sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist | 2 +
sysdeps/unix/sysv/linux/x86_64/64/libc.abilist | 2 +
sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist | 2 +
45 files changed, 423 insertions(+), 22 deletions(-)
create mode 100644 string/explicit_bzero.c
create mode 100644 string/read_memory.c
create mode 100644 string/test-explicit_bzero.c
--
2.9.3