mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-12 05:59:10 +00:00
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:
parent
fdc3fa9148
commit
1ff9ab95ac
153 changed files with 2545 additions and 2077 deletions
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/dnsheader.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
@ -28,20 +29,20 @@ TEST(serializednsheader, test) {
|
|||
header.id = 255;
|
||||
header.bf1 = true;
|
||||
header.qdcount = 1;
|
||||
uint8_t *buf = tmalloc(12);
|
||||
uint8_t *buf = malloc(12);
|
||||
ASSERT_EQ(12, serializednsheader(buf, 12, header));
|
||||
EXPECT_BINEQ(u" λ☺ ☺ ", buf);
|
||||
tfree(buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
TEST(serializednsheader, fuzzSymmetry) {
|
||||
uint8_t *buf = tmalloc(12);
|
||||
struct DnsHeader *in = tmalloc(sizeof(struct DnsHeader));
|
||||
struct DnsHeader *out = tmalloc(sizeof(struct DnsHeader));
|
||||
uint8_t *buf = malloc(12);
|
||||
struct DnsHeader *in = malloc(sizeof(struct DnsHeader));
|
||||
struct DnsHeader *out = malloc(sizeof(struct DnsHeader));
|
||||
ASSERT_EQ(12, serializednsheader(buf, 12, *in));
|
||||
ASSERT_EQ(12, deserializednsheader(out, buf, 12));
|
||||
ASSERT_EQ(0, memcmp(in, out, 12));
|
||||
tfree(out);
|
||||
tfree(in);
|
||||
tfree(buf);
|
||||
free(out);
|
||||
free(in);
|
||||
free(buf);
|
||||
}
|
||||
|
|
|
@ -17,21 +17,22 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(dnsnamecmp, testEmpty) {
|
||||
char *A = strcpy(tmalloc(1), "");
|
||||
char *B = strcpy(tmalloc(1), "");
|
||||
char *A = strcpy(malloc(1), "");
|
||||
char *B = strcpy(malloc(1), "");
|
||||
EXPECT_EQ(dnsnamecmp(A, B), 0);
|
||||
EXPECT_EQ(dnsnamecmp(A, A), 0);
|
||||
tfree(B);
|
||||
tfree(A);
|
||||
free(B);
|
||||
free(A);
|
||||
}
|
||||
|
||||
TEST(dnsnamecmp, testDotless_caseInsensitiveBehavior) {
|
||||
char *A = tmalloc(2);
|
||||
char *B = tmalloc(2);
|
||||
char *A = malloc(2);
|
||||
char *B = malloc(2);
|
||||
EXPECT_EQ(dnsnamecmp(strcpy(A, "a"), strcpy(B, "a")), 0);
|
||||
EXPECT_EQ(dnsnamecmp(A, A), 0);
|
||||
EXPECT_EQ(dnsnamecmp(strcpy(A, "a"), strcpy(B, "A")), 0);
|
||||
|
@ -39,13 +40,13 @@ TEST(dnsnamecmp, testDotless_caseInsensitiveBehavior) {
|
|||
EXPECT_LT(dnsnamecmp(strcpy(A, "a"), strcpy(B, "b")), 0);
|
||||
EXPECT_LT(dnsnamecmp(strcpy(A, "a"), strcpy(B, "B")), 0);
|
||||
EXPECT_GT(dnsnamecmp(strcpy(A, "d"), strcpy(B, "a")), 0);
|
||||
tfree(B);
|
||||
tfree(A);
|
||||
free(B);
|
||||
free(A);
|
||||
}
|
||||
|
||||
TEST(dnsnamecmp, testMultiLabel_lexiReverse) {
|
||||
char *A = tmalloc(16);
|
||||
char *B = tmalloc(16);
|
||||
char *A = malloc(16);
|
||||
char *B = malloc(16);
|
||||
EXPECT_EQ(dnsnamecmp(strcpy(A, "a.example"), strcpy(B, "a.example")), 0);
|
||||
EXPECT_GT(dnsnamecmp(strcpy(A, "b.example"), strcpy(B, "a.example")), 0);
|
||||
EXPECT_LT(dnsnamecmp(strcpy(A, "b.example"), strcpy(B, "a.examplz")), 0);
|
||||
|
@ -53,48 +54,48 @@ TEST(dnsnamecmp, testMultiLabel_lexiReverse) {
|
|||
EXPECT_EQ(dnsnamecmp(strcpy(A, "c.a.example"), strcpy(B, "c.a.example")), 0);
|
||||
EXPECT_GT(dnsnamecmp(strcpy(A, "d.a.example"), strcpy(B, "c.a.example")), 0);
|
||||
EXPECT_LT(dnsnamecmp(strcpy(A, "cat.example"), strcpy(B, "lol.example")), 0);
|
||||
tfree(B);
|
||||
tfree(A);
|
||||
free(B);
|
||||
free(A);
|
||||
}
|
||||
|
||||
TEST(dnsnamecmp, testTldDotQualifier_canBeEqualToDottedNames) {
|
||||
char *A = tmalloc(16);
|
||||
char *B = tmalloc(16);
|
||||
char *A = malloc(16);
|
||||
char *B = malloc(16);
|
||||
EXPECT_EQ(dnsnamecmp(strcpy(B, "aaa.example."), strcpy(A, "aaa.example")), 0);
|
||||
tfree(B);
|
||||
tfree(A);
|
||||
free(B);
|
||||
free(A);
|
||||
}
|
||||
|
||||
TEST(dnsnamecmp, testFullyQualified_alwaysComesFirst) {
|
||||
char *A = tmalloc(16);
|
||||
char *B = tmalloc(16);
|
||||
char *A = malloc(16);
|
||||
char *B = malloc(16);
|
||||
EXPECT_LT(dnsnamecmp(strcpy(B, "aaa.example."), strcpy(A, "zzz")), 0);
|
||||
EXPECT_LT(dnsnamecmp(strcpy(B, "zzz.example."), strcpy(A, "aaa")), 0);
|
||||
EXPECT_GT(dnsnamecmp(strcpy(A, "zzz"), strcpy(B, "aaa.example.")), 0);
|
||||
EXPECT_GT(dnsnamecmp(strcpy(A, "aaa"), strcpy(B, "zzz.example.")), 0);
|
||||
tfree(B);
|
||||
tfree(A);
|
||||
free(B);
|
||||
free(A);
|
||||
}
|
||||
|
||||
TEST(dnsnamecmp, testLikelySld_alwaysComesBeforeLocalName) {
|
||||
char *A = tmalloc(16);
|
||||
char *B = tmalloc(16);
|
||||
char *A = malloc(16);
|
||||
char *B = malloc(16);
|
||||
EXPECT_LT(dnsnamecmp(strcpy(B, "z.e"), strcpy(A, "a")), 0);
|
||||
EXPECT_LT(dnsnamecmp(strcpy(B, "aaa.example"), strcpy(A, "zzz")), 0);
|
||||
EXPECT_LT(dnsnamecmp(strcpy(B, "zzz.example"), strcpy(A, "aaa")), 0);
|
||||
EXPECT_GT(dnsnamecmp(strcpy(A, "zzz"), strcpy(B, "aaa.example")), 0);
|
||||
EXPECT_GT(dnsnamecmp(strcpy(A, "aaa"), strcpy(B, "zzz.example")), 0);
|
||||
tfree(B);
|
||||
tfree(A);
|
||||
free(B);
|
||||
free(A);
|
||||
}
|
||||
|
||||
TEST(dnsnamecmp, testLikelySubdomain_alwaysComesAfterSld) {
|
||||
char *A = tmalloc(16);
|
||||
char *B = tmalloc(16);
|
||||
char *A = malloc(16);
|
||||
char *B = malloc(16);
|
||||
EXPECT_LT(dnsnamecmp(strcpy(B, "a.e"), strcpy(A, "z.a.e")), 0);
|
||||
EXPECT_GT(dnsnamecmp(strcpy(A, "z.a.e"), strcpy(B, "a.e")), 0);
|
||||
EXPECT_LT(dnsnamecmp(strcpy(B, "b.e"), strcpy(A, "a.b.e")), 0);
|
||||
EXPECT_GT(dnsnamecmp(strcpy(A, "a.b.e"), strcpy(B, "b.e")), 0);
|
||||
tfree(B);
|
||||
tfree(A);
|
||||
free(B);
|
||||
free(A);
|
||||
}
|
||||
|
|
|
@ -19,11 +19,12 @@
|
|||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/dnsquestion.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(serializednsquestion, test) {
|
||||
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1 + 4);
|
||||
char *name = tstrdup("foo.bar");
|
||||
uint8_t *buf = malloc(1 + 3 + 1 + 3 + 1 + 4);
|
||||
char *name = strdup("foo.bar");
|
||||
struct DnsQuestion dq;
|
||||
dq.qname = name;
|
||||
dq.qtype = 0x0201;
|
||||
|
@ -31,19 +32,19 @@ TEST(serializednsquestion, test) {
|
|||
EXPECT_EQ(1 + 3 + 1 + 3 + 1 + 4,
|
||||
serializednsquestion(buf, 1 + 3 + 1 + 3 + 1 + 4, dq));
|
||||
EXPECT_BINEQ(u"♥foo♥bar ☻☺☺☻", buf);
|
||||
tfree(name);
|
||||
tfree(buf);
|
||||
free(name);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
TEST(serializednsquestion, testNoSpace) {
|
||||
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1 + 3);
|
||||
char *name = tstrdup("foo.bar");
|
||||
uint8_t *buf = malloc(1 + 3 + 1 + 3 + 1 + 3);
|
||||
char *name = strdup("foo.bar");
|
||||
struct DnsQuestion dq;
|
||||
dq.qname = name;
|
||||
dq.qtype = 0x0201;
|
||||
dq.qclass = 0x0102;
|
||||
EXPECT_EQ(-1, serializednsquestion(buf, 1 + 3 + 1 + 3 + 1 + 3, dq));
|
||||
EXPECT_EQ(ENOSPC, errno);
|
||||
tfree(name);
|
||||
tfree(buf);
|
||||
free(name);
|
||||
free(buf);
|
||||
}
|
||||
|
|
|
@ -18,61 +18,62 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(pascalifydnsname, testEmpty) {
|
||||
uint8_t *buf = tmalloc(1);
|
||||
char *name = tstrdup("");
|
||||
uint8_t *buf = malloc(1);
|
||||
char *name = strdup("");
|
||||
EXPECT_EQ(0, pascalifydnsname(buf, 1, name));
|
||||
EXPECT_BINEQ(u" ", buf);
|
||||
tfree(name);
|
||||
tfree(buf);
|
||||
free(name);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
TEST(pascalifydnsname, testOneLabel) {
|
||||
uint8_t *buf = tmalloc(1 + 3 + 1);
|
||||
char *name = tstrdup("foo");
|
||||
uint8_t *buf = malloc(1 + 3 + 1);
|
||||
char *name = strdup("foo");
|
||||
EXPECT_EQ(1 + 3, pascalifydnsname(buf, 1 + 3 + 1, name));
|
||||
EXPECT_BINEQ(u"♥foo ", buf);
|
||||
tfree(name);
|
||||
tfree(buf);
|
||||
free(name);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
TEST(pascalifydnsname, testTwoLabels) {
|
||||
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1);
|
||||
char *name = tstrdup("foo.bar");
|
||||
uint8_t *buf = malloc(1 + 3 + 1 + 3 + 1);
|
||||
char *name = strdup("foo.bar");
|
||||
EXPECT_EQ(1 + 3 + 1 + 3, pascalifydnsname(buf, 1 + 3 + 1 + 3 + 1, name));
|
||||
EXPECT_BINEQ(u"♥foo♥bar ", buf);
|
||||
tfree(name);
|
||||
tfree(buf);
|
||||
free(name);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
TEST(pascalifydnsname, testFqdnDot_isntIncluded) {
|
||||
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1);
|
||||
char *name = tstrdup("foo.bar.");
|
||||
uint8_t *buf = malloc(1 + 3 + 1 + 3 + 1);
|
||||
char *name = strdup("foo.bar.");
|
||||
EXPECT_EQ(1 + 3 + 1 + 3, pascalifydnsname(buf, 1 + 3 + 1 + 3 + 1, name));
|
||||
EXPECT_BINEQ(u"♥foo♥bar ", buf);
|
||||
tfree(name);
|
||||
tfree(buf);
|
||||
free(name);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
TEST(pascalifydnsname, testTooLong) {
|
||||
uint8_t *buf = tmalloc(1);
|
||||
char *name = tmalloc(1000);
|
||||
uint8_t *buf = malloc(1);
|
||||
char *name = malloc(1000);
|
||||
memset(name, '.', 999);
|
||||
name[999] = '\0';
|
||||
EXPECT_EQ(-1, pascalifydnsname(buf, 1, name));
|
||||
EXPECT_EQ(ENAMETOOLONG, errno);
|
||||
tfree(name);
|
||||
tfree(buf);
|
||||
free(name);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
TEST(pascalifydnsname, testNoSpace) {
|
||||
uint8_t *buf = tmalloc(1);
|
||||
char *name = tstrdup("foo");
|
||||
uint8_t *buf = malloc(1);
|
||||
char *name = strdup("foo");
|
||||
EXPECT_EQ(-1, pascalifydnsname(buf, 1, name));
|
||||
EXPECT_EQ(ENOSPC, errno);
|
||||
tfree(name);
|
||||
tfree(buf);
|
||||
free(name);
|
||||
free(buf);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue