Commit d475e278 authored by Adam Blank's avatar Adam Blank
Browse files

Initial commit

parents
No related merge requests found
Pipeline #74627 failed with stage
in 22 seconds
Showing with 472 additions and 0 deletions
+472 -0
---
# We'll use defaults from the Google style, but with 4 columns indentation.
BasedOnStyle: Google
# Never allow single-line functions
AllowShortFunctionsOnASingleLine: None
# Put "else" on a new line
BreakBeforeBraces: Custom
BraceWrapping:
BeforeElse: true
# Allow lines up to 90 characters
ColumnLimit: 90
# Indent each block by 4 spaces
IndentWidth: 4
TabWidth: 4
# Require 1 space before a comment on the same line
SpacesBeforeTrailingComments: 1
# Put a space after a cast, e.g. `(void) arg;`
SpaceAfterCStyleCast: true
---
#!/bin/bash
if loc="$(type -p "clang-format")" && [[ -x $loc ]]; then
for name in $(git diff --cached --name-only --diff-filter=ACM); do
if echo $name | grep -Eq "\.[ch]$"; then
echo "Formatting ${name}..."
clang-format -i $name
fi
done
else
echo "You do not have clang-format installed; so, we were unable to unify the formatting in your files."
fi
bin
tests/*.txt
asan1:
script: "/testers/cs24/final/asan1/test"
asan2:
script: "/testers/cs24/final/asan2/test"
asan3:
script: "/testers/cs24/final/asan3/test"
asan4:
script: "/testers/cs24/final/asan4/test"
asan5:
script: "/testers/cs24/final/asan5/test"
CC = clang
CFLAGS = -Wall -Wextra -g -fno-omit-frame-pointer
TESTS_1 = hello_no_malloc hello_malloc_free hello_free_null random_trace
TESTS_2 = $(TESTS_1) hello_double_free random_trace_double_free
TESTS_3 = $(TESTS_2) hello_invalid_free1 hello_invalid_free2 hello_invalid_free3 \
hello_invalid_free4 hello_invalid_free5 \
hello_invalid_free6 hello_invalid_free7
TESTS_4 = $(TESTS_3) hello_leak random_trace_leak1 random_trace_leak10
TESTS_5 = $(TESTS_4) hello_access_null \
hello_overflow1 hello_overflow2 hello_overflow3 hello_overflow4 \
hello_use_after_free1 hello_use_after_free2 hello_use_after_free3 \
hello_use_after_free4 hello_use_after_free5 random_trace_use_after_free \
hello_access_header1 hello_access_header2 hello_access_footer \
hello_access_before_heap hello_access_after_heap hello_header_after_free
test: test5
test1: $(TESTS_1:=-result)
test2: $(TESTS_2:=-result)
test3: $(TESTS_3:=-result)
test4: $(TESTS_4:=-result)
test5: $(TESTS_5:=-result)
bin/%.o: %.c
$(CC) $(CFLAGS) -c -fpic $^ -o $@
bin/%.o: tests/%.c
$(CC) $(CFLAGS) -c $^ -o $@
bin/libmyasan.so: bin/myasan.o bin/util.o
$(CC) $(CFLAGS) -shared -fpic $^ -o $@
bin/%: bin/%.o bin/libmyasan.so
$(CC) $(CFLAGS) -rdynamic $^ -o $@
tests/%-expected-code.txt: tests/%.c
grep -E '// [0-9]+' $^ | sed 's/\/\/ //' > $@
tests/%-expected-stdout.txt: tests/%.c
grep '// stdout: ' $^ | sed 's/\/\/ stdout: //' > $@
tests/%-expected-stderr.txt: tests/%.c
grep '// stderr: ' $^ | sed 's/\/\/ stderr: //' | head --lines=1 > $@
tests/%-actual-code.txt: bin/%
$^ > $(@:code.txt=stdout.txt) 2> $(@:code.txt=stderr.txt); \
code=$$?; \
if [ $$code -gt 30 ]; then \
cat $(@:code.txt=stdout.txt) $(@:code.txt=stderr.txt); \
exit $$code; \
fi; \
echo $$code > $@
%-result: tests/%-actual-code.txt tests/%-expected-code.txt tests/%-expected-stdout.txt tests/%-expected-stderr.txt
head --lines=1 $(<:code.txt=stderr.txt) > tmp; \
mv tmp $(<:code.txt=stderr.txt); \
diff -u $(word 3,$^) $(<:code.txt=stdout.txt) && \
diff -u $(word 4,$^) $(<:code.txt=stderr.txt) && \
diff -u $(word 2,$^) $< && \
echo "\e[32mPASSED test $(@:-result=)!\e[39m" || \
(echo "\e[31mFAILED test $(@:-result=)\e[39m"; false)
clean:
rm -f bin/* tests/*.txt
.PRECIOUS: bin/%.o bin/libmyasan.so bin/% \
tests/%-expected-code.txt tests/%-expected-stdout.txt tests/%-expected-stderr.txt \
tests/%-actual-code.txt
#define _GNU_SOURCE 1
#include <inttypes.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include "util.h"
static const size_t PAGE_SIZE = 4096;
typedef uint8_t page_t[PAGE_SIZE];
static void *const START_PAGE = (void *) ((size_t) 1 << 32);
static const size_t MAX_HEAP_SIZE = (size_t) 1 << 30;
static const int HEAP_MMAP_FLAGS = MAP_ANONYMOUS | MAP_PRIVATE;
static const size_t HEADER_MAGIC = 0x0123456789ABCDEF;
typedef struct {
size_t magic;
size_t size;
bool is_allocated;
} header_t;
static bool is_initialized = false;
static page_t *current_page;
static size_t pages_round_up(size_t size) {
return (size + PAGE_SIZE - 1) / PAGE_SIZE;
}
static void set_header(page_t *header_page, size_t size, bool is_allocated) {
// TODO: Edit this in stage 1
(void) header_page;
(void) size;
(void) is_allocated;
(void) HEADER_MAGIC;
}
static void *get_payload(page_t *header_page, size_t size) {
// TODO: Edit this in stage 1
(void) header_page;
(void) size;
return NULL;
}
static void check_for_leaks(void) {
// Prevent memory leaks from stdout
fclose(stdout);
// TODO: Edit this in stage 4
}
static void asan_init(void) {
if (is_initialized) {
return;
}
// Avoid buffering on stdout
setbuf(stdout, NULL);
current_page = mmap(START_PAGE, MAX_HEAP_SIZE,
PROT_READ | PROT_WRITE, // TODO: Edit this in stage 5
HEAP_MMAP_FLAGS, -1, 0);
assert(current_page == START_PAGE);
atexit(check_for_leaks);
is_initialized = true;
}
void *malloc(size_t size) {
asan_init();
size_t pages_necessary = pages_round_up(size);
// Store the size of the allocation at the beginning of the page before the payload
page_t *header_page = current_page;
set_header(header_page, size, true);
current_page += 1 + pages_necessary;
// Provide the user with the END of the first page
return get_payload(header_page, size);
}
void free(void *ptr) {
asan_init();
if (ptr == NULL) {
return;
}
// TODO: Edit this in stages 2 & 3
(void) ptr;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
void *x1 = malloc(1);
void *x2 = malloc(2);
printf("Hello World!\n");
*(volatile char *) (x2 + 4098);
printf("Hello World!\n");
free(x1);
free(x2);
}
// 10
// stdout: Hello World!
// stderr: Segmentation fault: unknown address 0x100005000
// stderr: at bin/hello_access_after_heap(main+0x39)
// stderr: main
// stderr: hello_access_after_heap.c:8
#include <stdio.h>
#include <stdlib.h>
int main() {
void *x1 = malloc(1);
void *x2 = malloc(2);
printf("Hello World!\n");
*(volatile char *) (x1 - 8192);
printf("Hello World!\n");
free(x1);
free(x2);
}
// 10
// stdout: Hello World!
// stderr: Segmentation fault: unknown address 0xffffffff
// stderr: at bin/hello_access_before_heap(main+0x39)
// stderr: main
// stderr: hello_access_before_heap.c:8
#include <stdio.h>
#include <stdlib.h>
int main() {
void *x1 = malloc(1);
void *x2 = malloc(2);
printf("Hello World!\n");
*(volatile char *) (x2 + 4097);
printf("Hello World!\n");
free(x1);
free(x2);
}
// 11
// stdout: Hello World!
// stderr: Invalid heap access: address 0x100004fff is not in an allocation or was already freed
// stderr: at bin/hello_access_footer(main+0x39)
// stderr: main
// stderr: hello_access_footer.c:8
#include <stdio.h>
#include <stdlib.h>
int main() {
void *x1 = malloc(1);
void *x2 = malloc(2);
printf("Hello World!\n");
*(volatile char *) (x1 - 8191);
printf("Hello World!\n");
free(x1);
free(x2);
}
// 11
// stdout: Hello World!
// stderr: Invalid heap access: address 0x100000000 is not in an allocation or was already freed
// stderr: at bin/hello_access_header1(main+0x39)
// stderr: main
// stderr: hello_access_header1.c:8
#include <stdio.h>
#include <stdlib.h>
int main() {
void *x1 = malloc(1);
void *x2 = malloc(2);
printf("Hello World!\n");
*(volatile char *) (x2 - 4096);
printf("Hello World!\n");
free(x1);
free(x2);
}
// 11
// stdout: Hello World!
// stderr: Invalid heap access: address 0x100002ffe is not in an allocation or was already freed
// stderr: at bin/hello_access_header2(main+0x39)
// stderr: main
// stderr: hello_access_header2.c:8
#include <stdlib.h>
int main() {
void *x = malloc(100);
free(x);
*(volatile char *) NULL = 5;
}
// 10
// stderr: Segmentation fault: unknown address (nil)
// stderr: at bin/hello_access_null(main+0x25)
// stderr: main
// stderr: hello_access_null.c:6
#include <stdio.h>
#include <stdlib.h>
int main() {
char *x = malloc(100);
printf("Hello World!\n");
free(x);
printf("Hello World!\n");
free(x);
printf("Hello World!\n");
}
// 21
// stdout: Hello World!
// stdout: Hello World!
// stderr: Double free(): allocation of 100 bytes at 0x100001f9c was already freed
// stderr: at bin/hello_double_free(main+0x50)
// stderr: main
// stderr: hello_double_free.c:10
#include <stdio.h>
#include <stdlib.h>
int main() {
free(NULL);
printf("Hello World!\n");
}
// 0
// stdout: Hello World!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *x = malloc(sizeof("Hello World!"));
strcpy(x, "Hello World!");
printf("%s\n", x);
free(x);
*(volatile char *) (x - 4096);
}
// 11
// stdout: Hello World!
// stderr: Invalid heap access: address 0x100000ff3 is not in an allocation or was already freed
// stderr: at bin/hello_header_after_free(main+0x4f)
// stderr: main
// stderr: hello_header_after_free.c:10
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *x = malloc(8192);
strcpy(x, "Hello World!");
printf("%s\n", x);
free(x + 4096);
}
// 20
// stdout: Hello World!
// stderr: Invalid free(): 0x100002000 is not an allocation
// stderr: at bin/hello_invalid_free1(main+0x53)
// stderr: main
// stderr: hello_invalid_free1.c:9
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *x = malloc(100);
strcpy(x, "Hello World!");
printf("%s\n", x);
free(x + 1);
}
// 20
// stdout: Hello World!
// stderr: Invalid free(): 0x100001f9d is not an allocation
// stderr: at bin/hello_invalid_free2(main+0x53)
// stderr: main
// stderr: hello_invalid_free2.c:9
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *x = malloc(100);
strcpy(x, "Hello World!");
printf("%s\n", x);
free(x - 10);
}
// 20
// stdout: Hello World!
// stderr: Invalid free(): 0x100001f92 is not an allocation
// stderr: at bin/hello_invalid_free3(main+0x53)
// stderr: main
// stderr: hello_invalid_free3.c:9
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
void *x = malloc(10);
(void) x;
free((void *) 0x12345678);
}
// 20
// stderr: Invalid free(): 0x12345678 is not an allocation
// stderr: at bin/hello_invalid_free4(main+0x20)
// stderr: main
// stderr: hello_invalid_free4.c:8
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *x = malloc(100);
strcpy(x, "Hello World!");
printf("%s\n", x);
free(x - 4096);
}
// 20
// stdout: Hello World!
// stderr: Invalid free(): 0x100000f9c is not an allocation
// stderr: at bin/hello_invalid_free5(main+0x53)
// stderr: main
// stderr: hello_invalid_free5.c:9
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment