Make C memory safe like Rust

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.
This commit is contained in:
Justine Tunney 2021-02-01 03:33:13 -08:00
parent fdc3fa9148
commit 1ff9ab95ac
153 changed files with 2545 additions and 2077 deletions

View file

@ -1,308 +0,0 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
Copyright 2020 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/notice.inc"
#include "libc/macros.h"
.source __FILE__
/ Embeds ASCII names for errno constants into binary.
.section .rodata,"aS",@progbits
kErrnoNames:
/ <SORTED-ORDER-C>
.asciz "2BIG"
.asciz "ACCES"
.asciz "ADDRINUSE"
.asciz "ADDRNOTAVAIL"
.asciz "ADV"
.asciz "AFNOSUPPORT"
.asciz "AGAIN"
.asciz "ALREADY"
.asciz "BADE"
.asciz "BADF"
.asciz "BADFD"
.asciz "BADMSG"
.asciz "BADR"
.asciz "BADRQC"
.asciz "BADSLT"
.asciz "BFONT"
.asciz "BUSY"
.asciz "CANCELED"
.asciz "CHILD"
.asciz "CHRNG"
.asciz "COMM"
.asciz "CONNABORTED"
.asciz "CONNREFUSED"
.asciz "CONNRESET"
.asciz "DEADLK"
.asciz "DESTADDRREQ"
.asciz "DOM"
.asciz "DOTDOT"
.asciz "DQUOT"
.asciz "EXIST"
.asciz "FAULT"
.asciz "FBIG"
.asciz "HOSTDOWN"
.asciz "HOSTUNREACH"
.asciz "HWPOISON"
.asciz "IDRM"
.asciz "ILSEQ"
.asciz "INPROGRESS"
.asciz "INTR"
.asciz "INVAL"
.asciz "IO"
.asciz "ISCONN"
.asciz "ISDIR"
.asciz "ISNAM"
.asciz "KEYEXPIRED"
.asciz "KEYREJECTED"
.asciz "KEYREVOKED"
.asciz "L2HLT"
.asciz "L2NSYNC"
.asciz "L3HLT"
.asciz "L3RST"
.asciz "LIBACC"
.asciz "LIBBAD"
.asciz "LIBEXEC"
.asciz "LIBMAX"
.asciz "LIBSCN"
.asciz "LNRNG"
.asciz "LOOP"
.asciz "MEDIUMTYPE"
.asciz "MFILE"
.asciz "MLINK"
.asciz "MSGSIZE"
.asciz "MULTIHOP"
.asciz "NAMETOOLONG"
.asciz "NAVAIL"
.asciz "NETDOWN"
.asciz "NETRESET"
.asciz "NETUNREACH"
.asciz "NFILE"
.asciz "NOANO"
.asciz "NOBUFS"
.asciz "NOCSI"
.asciz "NODATA"
.asciz "NODEV"
.asciz "NOENT"
.asciz "NOEXEC"
.asciz "NOKEY"
.asciz "NOLCK"
.asciz "NOLINK"
.asciz "NOMEDIUM"
.asciz "NOMEM"
.asciz "NOMSG"
.asciz "NONET"
.asciz "NOPKG"
.asciz "NOPROTOOPT"
.asciz "NOSPC"
.asciz "NOSR"
.asciz "NOSTR"
.asciz "NOSYS"
.asciz "NOTBLK"
.asciz "NOTCONN"
.asciz "NOTDIR"
.asciz "NOTEMPTY"
.asciz "NOTNAM"
.asciz "NOTRECOVERABLE"
.asciz "NOTSOCK"
.asciz "NOTSUP"
.asciz "NOTTY"
.asciz "NOTUNIQ"
.asciz "NXIO"
.asciz "OPNOTSUPP"
.asciz "OVERFLOW"
.asciz "OWNERDEAD"
.asciz "PERM"
.asciz "PFNOSUPPORT"
.asciz "PIPE"
.asciz "PROTO"
.asciz "PROTONOSUPPORT"
.asciz "PROTOTYPE"
.asciz "RANGE"
.asciz "REMCHG"
.asciz "REMOTE"
.asciz "REMOTEIO"
.asciz "RESTART"
.asciz "RFKILL"
.asciz "ROFS"
.asciz "SHUTDOWN"
.asciz "SOCKTNOSUPPORT"
.asciz "SPIPE"
.asciz "SRCH"
.asciz "SRMNT"
.asciz "STALE"
.asciz "STRPIPE"
.asciz "TIME"
.asciz "TIMEDOUT"
.asciz "TOOMANYREFS"
.asciz "TXTBSY"
.asciz "UCLEAN"
.asciz "UNATCH"
.asciz "USERS"
.asciz "XDEV"
.asciz "XFULL"
/ </SORTED-ORDER-C>
.byte 0
.endobj kErrnoNames,globl,hidden
.previous
/ Pulls errno constants into linkage.
/
/ @assume linker relocates these in sorted order
/ @assume linker invoked as LC_ALL=C ld ...
/ @see libc/sysv/systemfive.S
/ @see libc/sysv/consts/syscon.h
.yoink E2BIG
.yoink EACCES
.yoink EADDRINUSE
.yoink EADDRNOTAVAIL
.yoink EADV
.yoink EAFNOSUPPORT
.yoink EAGAIN
.yoink EALREADY
.yoink EBADE
.yoink EBADF
.yoink EBADFD
.yoink EBADMSG
.yoink EBADR
.yoink EBADRQC
.yoink EBADSLT
.yoink EBFONT
.yoink EBUSY
.yoink ECANCELED
.yoink ECHILD
.yoink ECHRNG
.yoink ECOMM
.yoink ECONNABORTED
.yoink ECONNREFUSED
.yoink ECONNRESET
.yoink EDEADLK
.yoink EDESTADDRREQ
.yoink EDOM
.yoink EDOTDOT
.yoink EDQUOT
.yoink EEXIST
.yoink EFAULT
.yoink EFBIG
.yoink EHOSTDOWN
.yoink EHOSTUNREACH
.yoink EHWPOISON
.yoink EIDRM
.yoink EILSEQ
.yoink EINPROGRESS
.yoink EINTR
.yoink EINVAL
.yoink EIO
.yoink EISCONN
.yoink EISDIR
.yoink EISNAM
.yoink EKEYEXPIRED
.yoink EKEYREJECTED
.yoink EKEYREVOKED
.yoink EL2HLT
.yoink EL2NSYNC
.yoink EL3HLT
.yoink EL3RST
.yoink ELIBACC
.yoink ELIBBAD
.yoink ELIBEXEC
.yoink ELIBMAX
.yoink ELIBSCN
.yoink ELNRNG
.yoink ELOOP
.yoink EMEDIUMTYPE
.yoink EMFILE
.yoink EMLINK
.yoink EMSGSIZE
.yoink EMULTIHOP
.yoink ENAMETOOLONG
.yoink ENAVAIL
.yoink ENETDOWN
.yoink ENETRESET
.yoink ENETUNREACH
.yoink ENFILE
.yoink ENOANO
.yoink ENOBUFS
.yoink ENOCSI
.yoink ENODATA
.yoink ENODEV
.yoink ENOENT
.yoink ENOEXEC
.yoink ENOKEY
.yoink ENOLCK
.yoink ENOLINK
.yoink ENOMEDIUM
.yoink ENOMEM
.yoink ENOMSG
.yoink ENONET
.yoink ENOPKG
.yoink ENOPROTOOPT
.yoink ENOSPC
.yoink ENOSR
.yoink ENOSTR
.yoink ENOSYS
.yoink ENOTBLK
.yoink ENOTCONN
.yoink ENOTDIR
.yoink ENOTEMPTY
.yoink ENOTNAM
.yoink ENOTRECOVERABLE
.yoink ENOTSOCK
.yoink ENOTSUP
.yoink ENOTTY
.yoink ENOTUNIQ
.yoink ENXIO
.yoink EOPNOTSUPP
.yoink EOVERFLOW
.yoink EOWNERDEAD
.yoink EPERM
.yoink EPFNOSUPPORT
.yoink EPIPE
.yoink EPROTO
.yoink EPROTONOSUPPORT
.yoink EPROTOTYPE
.yoink ERANGE
.yoink EREMCHG
.yoink EREMOTE
.yoink EREMOTEIO
.yoink ERESTART
.yoink ERFKILL
.yoink EROFS
.yoink ESHUTDOWN
.yoink ESOCKTNOSUPPORT
.yoink ESPIPE
.yoink ESRCH
.yoink ESRMNT
.yoink ESTALE
.yoink ESTRPIPE
.yoink ETIME
.yoink ETIMEDOUT
.yoink ETOOMANYREFS
.yoink ETXTBSY
.yoink EUCLEAN
.yoink EUNATCH
.yoink EUSERS
.yoink EXDEV
.yoink EXFULL
.type kErrnoStart,@object
.type kErrnoEnd,@object
.globl kErrnoStart, kErrnoEnd, EXFULL, E2BIG
.hidden kErrnoStart, kErrnoEnd
kErrnoStart = E2BIG
kErrnoEnd = EXFULL + 8

View file

@ -26,8 +26,275 @@
#include "libc/nt/runtime.h"
#include "libc/str/str.h"
const char *geterrname(int code) {
extern const char kErrnoNames[];
STATIC_YOINK("E2BIG");
STATIC_YOINK("EACCES");
STATIC_YOINK("EADDRINUSE");
STATIC_YOINK("EADDRNOTAVAIL");
STATIC_YOINK("EADV");
STATIC_YOINK("EAFNOSUPPORT");
STATIC_YOINK("EAGAIN");
STATIC_YOINK("EALREADY");
STATIC_YOINK("EBADE");
STATIC_YOINK("EBADF");
STATIC_YOINK("EBADFD");
STATIC_YOINK("EBADMSG");
STATIC_YOINK("EBADR");
STATIC_YOINK("EBADRQC");
STATIC_YOINK("EBADSLT");
STATIC_YOINK("EBFONT");
STATIC_YOINK("EBUSY");
STATIC_YOINK("ECANCELED");
STATIC_YOINK("ECHILD");
STATIC_YOINK("ECHRNG");
STATIC_YOINK("ECOMM");
STATIC_YOINK("ECONNABORTED");
STATIC_YOINK("ECONNREFUSED");
STATIC_YOINK("ECONNRESET");
STATIC_YOINK("EDEADLK");
STATIC_YOINK("EDESTADDRREQ");
STATIC_YOINK("EDOM");
STATIC_YOINK("EDOTDOT");
STATIC_YOINK("EDQUOT");
STATIC_YOINK("EEXIST");
STATIC_YOINK("EFAULT");
STATIC_YOINK("EFBIG");
STATIC_YOINK("EHOSTDOWN");
STATIC_YOINK("EHOSTUNREACH");
STATIC_YOINK("EHWPOISON");
STATIC_YOINK("EIDRM");
STATIC_YOINK("EILSEQ");
STATIC_YOINK("EINPROGRESS");
STATIC_YOINK("EINTR");
STATIC_YOINK("EINVAL");
STATIC_YOINK("EIO");
STATIC_YOINK("EISCONN");
STATIC_YOINK("EISDIR");
STATIC_YOINK("EISNAM");
STATIC_YOINK("EKEYEXPIRED");
STATIC_YOINK("EKEYREJECTED");
STATIC_YOINK("EKEYREVOKED");
STATIC_YOINK("EL2HLT");
STATIC_YOINK("EL2NSYNC");
STATIC_YOINK("EL3HLT");
STATIC_YOINK("EL3RST");
STATIC_YOINK("ELIBACC");
STATIC_YOINK("ELIBBAD");
STATIC_YOINK("ELIBEXEC");
STATIC_YOINK("ELIBMAX");
STATIC_YOINK("ELIBSCN");
STATIC_YOINK("ELNRNG");
STATIC_YOINK("ELOOP");
STATIC_YOINK("EMEDIUMTYPE");
STATIC_YOINK("EMFILE");
STATIC_YOINK("EMLINK");
STATIC_YOINK("EMSGSIZE");
STATIC_YOINK("EMULTIHOP");
STATIC_YOINK("ENAMETOOLONG");
STATIC_YOINK("ENAVAIL");
STATIC_YOINK("ENETDOWN");
STATIC_YOINK("ENETRESET");
STATIC_YOINK("ENETUNREACH");
STATIC_YOINK("ENFILE");
STATIC_YOINK("ENOANO");
STATIC_YOINK("ENOBUFS");
STATIC_YOINK("ENOCSI");
STATIC_YOINK("ENODATA");
STATIC_YOINK("ENODEV");
STATIC_YOINK("ENOENT");
STATIC_YOINK("ENOEXEC");
STATIC_YOINK("ENOKEY");
STATIC_YOINK("ENOLCK");
STATIC_YOINK("ENOLINK");
STATIC_YOINK("ENOMEDIUM");
STATIC_YOINK("ENOMEM");
STATIC_YOINK("ENOMSG");
STATIC_YOINK("ENONET");
STATIC_YOINK("ENOPKG");
STATIC_YOINK("ENOPROTOOPT");
STATIC_YOINK("ENOSPC");
STATIC_YOINK("ENOSR");
STATIC_YOINK("ENOSTR");
STATIC_YOINK("ENOSYS");
STATIC_YOINK("ENOTBLK");
STATIC_YOINK("ENOTCONN");
STATIC_YOINK("ENOTDIR");
STATIC_YOINK("ENOTEMPTY");
STATIC_YOINK("ENOTNAM");
STATIC_YOINK("ENOTRECOVERABLE");
STATIC_YOINK("ENOTSOCK");
STATIC_YOINK("ENOTSUP");
STATIC_YOINK("ENOTTY");
STATIC_YOINK("ENOTUNIQ");
STATIC_YOINK("ENXIO");
STATIC_YOINK("EOPNOTSUPP");
STATIC_YOINK("EOVERFLOW");
STATIC_YOINK("EOWNERDEAD");
STATIC_YOINK("EPERM");
STATIC_YOINK("EPFNOSUPPORT");
STATIC_YOINK("EPIPE");
STATIC_YOINK("EPROTO");
STATIC_YOINK("EPROTONOSUPPORT");
STATIC_YOINK("EPROTOTYPE");
STATIC_YOINK("ERANGE");
STATIC_YOINK("EREMCHG");
STATIC_YOINK("EREMOTE");
STATIC_YOINK("EREMOTEIO");
STATIC_YOINK("ERESTART");
STATIC_YOINK("ERFKILL");
STATIC_YOINK("EROFS");
STATIC_YOINK("ESHUTDOWN");
STATIC_YOINK("ESOCKTNOSUPPORT");
STATIC_YOINK("ESPIPE");
STATIC_YOINK("ESRCH");
STATIC_YOINK("ESRMNT");
STATIC_YOINK("ESTALE");
STATIC_YOINK("ESTRPIPE");
STATIC_YOINK("ETIME");
STATIC_YOINK("ETIMEDOUT");
STATIC_YOINK("ETOOMANYREFS");
STATIC_YOINK("ETXTBSY");
STATIC_YOINK("EUCLEAN");
STATIC_YOINK("EUNATCH");
STATIC_YOINK("EUSERS");
STATIC_YOINK("EXDEV");
STATIC_YOINK("EXFULL");
_Alignas(char) static const char kErrnoNames[] = "\
2BIG\000\
ACCES\000\
ADDRINUSE\000\
ADDRNOTAVAIL\000\
ADV\000\
AFNOSUPPORT\000\
AGAIN\000\
ALREADY\000\
BADE\000\
BADF\000\
BADFD\000\
BADMSG\000\
BADR\000\
BADRQC\000\
BADSLT\000\
BFONT\000\
BUSY\000\
CANCELED\000\
CHILD\000\
CHRNG\000\
COMM\000\
CONNABORTED\000\
CONNREFUSED\000\
CONNRESET\000\
DEADLK\000\
DESTADDRREQ\000\
DOM\000\
DOTDOT\000\
DQUOT\000\
EXIST\000\
FAULT\000\
FBIG\000\
HOSTDOWN\000\
HOSTUNREACH\000\
HWPOISON\000\
IDRM\000\
ILSEQ\000\
INPROGRESS\000\
INTR\000\
INVAL\000\
IO\000\
ISCONN\000\
ISDIR\000\
ISNAM\000\
KEYEXPIRED\000\
KEYREJECTED\000\
KEYREVOKED\000\
L2HLT\000\
L2NSYNC\000\
L3HLT\000\
L3RST\000\
LIBACC\000\
LIBBAD\000\
LIBEXEC\000\
LIBMAX\000\
LIBSCN\000\
LNRNG\000\
LOOP\000\
MEDIUMTYPE\000\
MFILE\000\
MLINK\000\
MSGSIZE\000\
MULTIHOP\000\
NAMETOOLONG\000\
NAVAIL\000\
NETDOWN\000\
NETRESET\000\
NETUNREACH\000\
NFILE\000\
NOANO\000\
NOBUFS\000\
NOCSI\000\
NODATA\000\
NODEV\000\
NOENT\000\
NOEXEC\000\
NOKEY\000\
NOLCK\000\
NOLINK\000\
NOMEDIUM\000\
NOMEM\000\
NOMSG\000\
NONET\000\
NOPKG\000\
NOPROTOOPT\000\
NOSPC\000\
NOSR\000\
NOSTR\000\
NOSYS\000\
NOTBLK\000\
NOTCONN\000\
NOTDIR\000\
NOTEMPTY\000\
NOTNAM\000\
NOTRECOVERABLE\000\
NOTSOCK\000\
NOTSUP\000\
NOTTY\000\
NOTUNIQ\000\
NXIO\000\
OPNOTSUPP\000\
OVERFLOW\000\
OWNERDEAD\000\
PERM\000\
PFNOSUPPORT\000\
PIPE\000\
PROTO\000\
PROTONOSUPPORT\000\
PROTOTYPE\000\
RANGE\000\
REMCHG\000\
REMOTE\000\
REMOTEIO\000\
RESTART\000\
RFKILL\000\
ROFS\000\
SHUTDOWN\000\
SOCKTNOSUPPORT\000\
SPIPE\000\
SRCH\000\
SRMNT\000\
STALE\000\
STRPIPE\000\
TIME\000\
TIMEDOUT\000\
TOOMANYREFS\000\
TXTBSY\000\
UCLEAN\000\
UNATCH\000\
USERS\000\
XDEV\000\
XFULL\000\
\000";
const char *geterrname(long code) {
const long *e;
size_t i, n;
e = &E2BIG;

View file

@ -43,6 +43,7 @@ static const int kCp437iMultimappings[] = {
u'' << 8 | 0xEE, // ELEMENT-OF SIGN
u'β' << 8 | 0xE1, // GREEK SMALL BETA
u'ſ' << 8 | 0xF4, // LATIN SMALL LETTER LONG S
u'·' << 8 | 0xFA // MIDDLE DOT
};
static int g_cp437i[256 + ARRAYLEN(kCp437iMultimappings)];