Skip to content

Commit

Permalink
Make C memory safe like Rust
Browse files Browse the repository at this point in the history
This change enables Address Sanitizer systemically w/ `make MODE=dbg`.
Our version of Rust's `unsafe` keyword is named `noasan` which is used
for two functions that do aligned memory chunking, like `strcpy.c` and
we need to fix the tiny DEFLATE code, but that's it everything else is
fabulous you can have all the fischer price security blankets you need

Best of all is we're now able to use the ASAN data in Blinkenlights to
colorize the memory dumps. See the screenshot below of a test program:

  https://justine.lol/blinkenlights/asan.png

Which is operating on float arrays stored on the stack, with red areas
indicating poisoned memory, and the green areas indicate valid memory.
  • Loading branch information
jart committed Feb 1, 2021
1 parent fdc3fa9 commit 1ff9ab9
Show file tree
Hide file tree
Showing 153 changed files with 2,539 additions and 2,071 deletions.
7 changes: 6 additions & 1 deletion ape/lib/apelib.mk
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@ APE_LIB_A_OBJS = \
$(APE_LIB_A_SRCS_S:%.S=o/$(MODE)/%.o) \
$(APE_LIB_A_SRCS_C:%.c=o/$(MODE)/%.o)

APE_LIB_A_DIRECTDEPS = \
LIBC_NEXGEN32E \
LIBC_INTRIN \
LIBC_STR \
LIBC_STUBS

APE_LIB_A_CHECKS = $(APE_LIB_A_HDRS:%=o/$(MODE)/%.ok)
APE_LIB_A_DIRECTDEPS = LIBC_STR LIBC_NEXGEN32E LIBC_STUBS
APE_LIB_A_DEPS = $(call uniq,$(foreach x,$(APE_LIB_A_DIRECTDEPS),$($(x))))

$(APE_LIB_A): ape/lib/ $(APE_LIB_A).pkg $(APE_LIB_A_OBJS)
Expand Down
3 changes: 3 additions & 0 deletions build/compile
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ for x; do
-mno-vzeroupper)
set -- "$@" "$x" -Wa,-msse2avx -D__MNO_VZEROUPPER__
;;
-fsanitize=address)
set -- "$@" "$x" -D__FSANITIZE_ADDRESS__
;;
-fsanitize=undefined)
set -- "$@" "$x" -D__FSANITIZE_UNDEFINED__
COUNTERMAND="$COUNTERMAND -fno-data-sections" # sqlite.o
Expand Down
4 changes: 1 addition & 3 deletions build/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,13 @@ CONFIG_CPPFLAGS += \
CONFIG_CCFLAGS += \
$(BACKTRACES) \
$(FTRACE) \
-O1 \
-fno-inline

CONFIG_COPTS += \
$(SECURITY_BLANKETS) \
$(SANITIZER)

CONFIG_COPTS += \
-ftrapv

TARGET_ARCH ?= \
-msse3

Expand Down
5 changes: 3 additions & 2 deletions build/definitions.mk
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,15 @@ FTRACE = \

SANITIZER = \
-fsanitize=leak \
-fsanitize=undefined \
-fsanitize=address \
-fsanitize=implicit-signed-integer-truncation \
-fsanitize=implicit-integer-sign-change

NO_MAGIC = \
-mno-fentry \
-fno-stack-protector \
-fno-sanitize=all
-fno-sanitize=all \
-fwrapv

OLD_CODE = \
-fno-strict-aliasing \
Expand Down
8 changes: 4 additions & 4 deletions build/mkdeps
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐
#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘

if [ -x "o/$MODE/tool/build/mkdeps.com" ]; then
set -- "o/$MODE/tool/build/mkdeps.com" "$@"
else
#if [ -x "o/$MODE/tool/build/mkdeps.com" ]; then
# set -- "o/$MODE/tool/build/mkdeps.com" "$@"
#else
if [ ! -x o/build/bootstrap/mkdeps.com ]; then
mkdir -p o/build/bootstrap &&
cp -a build/bootstrap/mkdeps.com \
o/build/bootstrap/mkdeps.com || exit
fi
set -- o/build/bootstrap/mkdeps.com "$@"
fi
#fi

if [ "$SILENT" = "0" ]; then
printf "%s\n" "$*" >&2
Expand Down
7 changes: 1 addition & 6 deletions dsp/core/core.mk
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ DSP_CORE_A_CHECKS = \
DSP_CORE_A_DIRECTDEPS = \
LIBC_NEXGEN32E \
LIBC_MEM \
LIBC_INTRIN \
LIBC_TINYMATH \
LIBC_STUBS

Expand Down Expand Up @@ -57,12 +58,6 @@ o/$(MODE)/dsp/core/det3.o: \
OVERRIDE_CFLAGS += \
-ffast-math

# ifeq (,$(MODE))
# $(DSP_CORE_OBJS): \
# OVERRIDE_CFLAGS += \
# -fsanitize=address
# endif

DSP_CORE_LIBS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)))
DSP_CORE_SRCS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)_SRCS))
DSP_CORE_HDRS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)_HDRS))
Expand Down
2 changes: 1 addition & 1 deletion dsp/tty/hidecursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
static int ttysetcursor(int fd, bool visible) {
struct NtConsoleCursorInfo ntcursor;
char code[8] = "\e[?25l";
if (isterminalinarticulate()) return 0;
if (IsTerminalInarticulate()) return 0;
if (visible) code[5] = 'h';
if (SupportsWindows()) {
GetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor);
Expand Down
6 changes: 0 additions & 6 deletions dsp/tty/tty.mk
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,6 @@ o/$(MODE)/dsp/tty/ttyraster.o: \
OVERRIDE_CFLAGS += \
$(MATHEMATICAL)

# ifeq (,$(MODE))
# $(DSP_TTY_OBJS): \
# OVERRIDE_CFLAGS += \
# -fsanitize=address
# endif

DSP_TTY_LIBS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)))
DSP_TTY_SRCS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)_SRCS))
DSP_TTY_HDRS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)_HDRS))
Expand Down
2 changes: 1 addition & 1 deletion dsp/tty/windex.S
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ windex: .quad 0
ezlea windex$sse4,dx
testb X86_HAVE(AVX2)+kCpuids(%rip)
cmovz %rdx,%rax
#endif /* AVX */
#endif /* AVX2 */
#if !X86_NEED(SSE4_2)
ezlea windex$k8,dx
testb X86_HAVE(SSE4_2)+kCpuids(%rip)
Expand Down
6 changes: 3 additions & 3 deletions examples/crashreport.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ int main(int argc, char *argv[]) {
"movd\t%rax,%xmm14\n\t"
"mov\t$0xffffffffffffffff,%rax\n\t"
"movd\t%rax,%xmm15\n\t"
"fldpi\n\t");

res = *(int *)(intptr_t)boo / boo;
"fldpi\n\t"
"xor\t%eax,%eax\n\t"
"div\t%eax\n\t");

return res;
}
1 change: 0 additions & 1 deletion examples/examples.mk
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ EXAMPLES_DIRECTDEPS = \
LIBC_FMT \
LIBC_INTRIN \
LIBC_LOG \
LIBC_LOG_ASAN \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_NT_KERNEL32 \
Expand Down
2 changes: 0 additions & 2 deletions libc/calls/chdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/dce.h"
#include "libc/sysv/errfuns.h"

/**
* Sets current directory.
Expand Down
3 changes: 2 additions & 1 deletion libc/calls/creat.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/consts/o.h"

/**
Expand All @@ -35,5 +36,5 @@
* @asyncsignalsafe
*/
nodiscard int creat(const char *file, uint32_t mode) {
return open(file, O_CREAT | O_WRONLY | O_TRUNC, mode);
return openat(AT_FDCWD, file, O_CREAT | O_WRONLY | O_TRUNC, mode);
}
2 changes: 0 additions & 2 deletions libc/calls/dup3.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@
* unless it's equal to oldfd, in which case dup2() is a no-op
* @flags can have O_CLOEXEC
* @see dup(), dup2()
* @syscall
*/
int dup3(int oldfd, int newfd, int flags) {
if (oldfd == newfd) return einval();
if (!IsWindows()) {
return dup3$sysv(oldfd, newfd, flags);
} else {
Expand Down
39 changes: 39 additions & 0 deletions libc/calls/getppid-nt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2021 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/internal.h"
#include "libc/dce.h"
#include "libc/nt/nt/process.h"
#include "libc/nt/ntdll.h"
#include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/nt/struct/processbasicinformation.h"

textwindows int getppid$nt(void) {
struct NtProcessBasicInformation ProcessInformation;
uint32_t gotsize = 0;
if (!NtError(
NtQueryInformationProcess(GetCurrentProcess(), 0, &ProcessInformation,
sizeof(ProcessInformation), &gotsize)) &&
gotsize >= sizeof(ProcessInformation) &&
ProcessInformation.InheritedFromUniqueProcessId) {
/* TODO(jart): Fix type mismatch and do we need to close this? */
return ProcessInformation.InheritedFromUniqueProcessId;
}
return GetCurrentProcessId();
}
21 changes: 0 additions & 21 deletions libc/calls/getppid.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/dce.h"
#include "libc/nt/nt/process.h"
#include "libc/nt/ntdll.h"
#include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/nt/struct/processbasicinformation.h"

static textwindows noinline int32_t getppid$nt(void) {
struct NtProcessBasicInformation ProcessInformation;
uint32_t gotsize = 0;
if (!NtError(
NtQueryInformationProcess(GetCurrentProcess(), 0, &ProcessInformation,
sizeof(ProcessInformation), &gotsize)) &&
gotsize >= sizeof(ProcessInformation) &&
ProcessInformation.InheritedFromUniqueProcessId) {
/* TODO(jart): Fix type mismatch and do we need to close this? */
return ProcessInformation.InheritedFromUniqueProcessId;
}
return GetCurrentProcessId();
}

/**
* Returns parent process id.
Expand Down
1 change: 1 addition & 0 deletions libc/calls/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ int fork$nt(void) hidden;
int fstat$nt(i64, struct stat *) hidden;
int fstatat$nt(int, const char *, struct stat *, uint32_t) hidden;
int ftruncate$nt(int, u64) hidden;
int getppid$nt(void) hidden;
int getpriority$nt(int) hidden;
int getrusage$nt(int, struct rusage *) hidden;
int gettimeofday$nt(struct timeval *, struct timezone *) hidden;
Expand Down
2 changes: 1 addition & 1 deletion libc/crt/crt.S
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ _start: test %rdi,%rdi
repnz scasq
mov %rdi,%rcx # auxv
mov %ebx,%edi
call _executive
call cosmo
9: ud2
.endfn _start,weak,hidden

Expand Down
Loading

0 comments on commit 1ff9ab9

Please sign in to comment.