Commit 1bb31e79 authored by Adam Blank's avatar Adam Blank
Browse files

Merge branch 'master' into 'master'

Simplify starter code

See merge request cs24-20fa/project06!1
No related merge requests found
Showing with 122 additions and 126 deletions
+122 -126
---
# We'll use defaults from the Google style, but with 4 columns indentation.
BasedOnStyle: Google
# Never allow single-line functions
AllowShortFunctionsOnASingleLine: None
# 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
...@@ -3,22 +3,8 @@ CFLAGS = -O3 -Wall -Wextra -Iinclude ...@@ -3,22 +3,8 @@ CFLAGS = -O3 -Wall -Wextra -Iinclude
all: bin/cache_timing bin/index_guesser bin/recover_local_secret bin/recover_protected_local_secret bin/exploit all: bin/cache_timing bin/index_guesser bin/recover_local_secret bin/recover_protected_local_secret bin/exploit
bin/cache_timing: src/cache_timing.c lib/util.c bin/%: src/%.c lib/util.c
$(CC) $(CFLAGS) $^ -o $@ $(CC) $(CFLAGS) $^ -o $@
bin/index_guesser: src/index_guesser.c lib/util.c
$(CC) $(CFLAGS) $^ -o $@
bin/recover_local_secret: src/recover_local_secret.c lib/util.c
$(CC) $(CFLAGS) $^ -o $@
bin/recover_protected_local_secret: src/recover_protected_local_secret.c lib/util.c
$(CC) $(CFLAGS) $^ -o $@
bin/exploit: src/exploit.c lib/util.c
$(CC) $(CFLAGS) $^ -o $@
clean: clean:
rm -f bin/cache_timing src/index_guesser bin/recover_local_secret bin/recover_protected_local_secret bin/exploit rm -f bin/*
void do_access(page_t *pages) { void do_access(page_t *pages) {
force_read(&pages[24]); force_read(pages[24]);
} }
#include <inttypes.h> const uint8_t SECRET[] = "CLOCK";
#include <stdlib.h>
#include <string.h>
static inline uint8_t access_secret(size_t i) {
char *SECRET = "CLOCK";
static inline char access_secret(size_t i) {
return SECRET[i]; return SECRET[i];
} }
#include <inttypes.h> const uint8_t SECRET[] = "CACHE";
#include <stdlib.h>
#include <string.h>
static inline void cache_secret(void) {
char *SECRET = "CACHE"; volatile const uint8_t *secret = SECRET;
while (*secret != '\0') {
static inline void cache_secret() { secret++;
for (size_t i = 0; i < strlen(SECRET); i++) {
*(volatile char *)(SECRET + i);
} }
} }
static inline char access_secret(size_t i) { static inline uint8_t access_secret(size_t i) {
*(volatile char *)(0xFFFF|(i << 10)); *(volatile uint8_t *) (i << 16 | 0xFFFF);
return SECRET[i]; return SECRET[i];
} }
...@@ -7,14 +7,23 @@ ...@@ -7,14 +7,23 @@
typedef uint8_t page_t[PAGE_SIZE]; typedef uint8_t page_t[PAGE_SIZE];
// Forces a memory read of the byte at address p. This will result in the byte /**
// being loaded into cache. * Forces a memory read of the byte at the given address.
void force_read(const void *p); * This will load the byte at the address into the cache.
*/
void force_read(const void *address);
// Flushes the cache line containing the provided address /**
void flush_cache_line(const void *memory); * Evicts any cache line currently storing the given address.
* This ensures that the byte at the address is no longer in the cache.
*/
void flush_cache_line(const void *address);
// Returns the number of clocks taken to read the provided byte of memory. /**
uint64_t time_read(const void *memory); * Counts the number of processor clocks elapsed when reading a byte at the given address.
* Note that the number of clocks can be quite large
* if the process happens to be interrupted in this function.
*/
uint64_t time_read(const void *address);
#endif /* _UTIL_H */ #endif /* _UTIL_H */
...@@ -2,20 +2,21 @@ ...@@ -2,20 +2,21 @@
#include "util.h" #include "util.h"
void force_read(const void *p) { void force_read(const void *address) {
*(volatile char *) p; *(volatile uint8_t *) address;
} }
void flush_cache_line(const void *memory) { void flush_cache_line(const void *address) {
_mm_clflush(memory); _mm_clflush(address);
_mm_mfence(); _mm_mfence();
for (volatile int i = 0; i < 10000; i++) {} for (volatile int i = 0; i < 10000; i++) {
}
} }
uint64_t time_read(const void *memory) { uint64_t time_read(const void *address) {
uint64_t start = __rdtsc(); uint64_t start = __rdtsc();
_mm_lfence(); _mm_lfence();
force_read(memory); force_read(address);
_mm_mfence(); _mm_mfence();
_mm_lfence(); _mm_lfence();
uint64_t result = __rdtsc() - start; uint64_t result = __rdtsc() - start;
......
#include <inttypes.h> #include <inttypes.h>
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <stdlib.h>
#include "util.h" #include "util.h"
const uint64_t REPEATS = 100000; const size_t REPEATS = 100000;
int main() { int main() {
uint64_t min_miss = INT64_MAX; uint64_t min_miss = UINT64_MAX;
uint64_t max_hit = 0.0; uint64_t max_hit = 0;
// TODO: Implement the algorithm as described in the specification here // TODO: Implement the algorithm as described in the specification here
printf("min miss = %ld\n", min_miss); printf("min miss = %" PRIu64 "\n", min_miss);
printf("max hit = %ld\n", max_hit); printf("max hit = %" PRIu64 "\n", max_hit);
} }
#include <assert.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h> #include <stdio.h>
#include <unistd.h> #include <stdlib.h>
#define __USE_GNU #define __USE_GNU
#include <signal.h> #include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "util.h" #include "util.h"
static inline void *get_kernel_data_address() { static inline void *get_kernel_data_address(void) {
FILE *address_file; FILE *address_file = fopen("/sys/kernel/kernel_data/address", "r");
address_file = fopen("/sys/kernel/kernel_data/address", "r"); assert(address_file != NULL);
if (address_file != NULL) {
uint64_t address;
if (fscanf(address_file, "%lx\n", &address) == 1) {
fclose(address_file);
return (void *) address;
}
fclose(address_file);
}
return 0;
}
size_t address;
int scanned = fscanf(address_file, "%zx\n", &address);
assert(scanned == 1);
fclose(address_file);
return (void *) address;
}
// TODO: Copy your code from the previous stage and make the necessary edits to do_access() /* TODO: Copy your code from the previous stage and edit do_access().
// Note that this code WILL NOT WORK on compute-cpu2. You must push it to gitlab to get it to run * Note that this code WILL NOT WORK on compute-cpu2.
// on one of the meltdown machines. * You must push it to GitLab to run it on one of the meltdown machines.
*/
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <stdlib.h>
#include "util.h" #include "util.h"
#include "stage2.h" #include "stage2.h"
const uint64_t MIN_CHOICE = 1; const size_t MIN_CHOICE = 1;
const uint64_t MAX_CHOICE = 256; const size_t MAX_CHOICE = 255;
static inline page_t *init_pages() { static inline page_t *init_pages(void) {
return calloc(MAX_CHOICE, sizeof(page_t)); return calloc(MAX_CHOICE + 1, sizeof(page_t));
} }
static inline void flush_all_pages(page_t *pages) { static inline void flush_all_pages(page_t *pages) {
...@@ -22,7 +18,7 @@ static inline void flush_all_pages(page_t *pages) { ...@@ -22,7 +18,7 @@ static inline void flush_all_pages(page_t *pages) {
} }
static inline size_t guess_accessed_page(page_t *pages) { static inline size_t guess_accessed_page(page_t *pages) {
// TODO: Implement me! // TODO: Implement me!
return 0; return 0;
} }
...@@ -33,9 +29,10 @@ int main() { ...@@ -33,9 +29,10 @@ int main() {
flush_all_pages(pages); flush_all_pages(pages);
do_access(pages); do_access(pages);
size_t guess = guess_accessed_page(pages); size_t guess = guess_accessed_page(pages);
if (guess) { if (guess > 0) {
printf("%zu\n", guess); printf("%zu\n", guess);
} }
free(pages);
} }
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <stdlib.h>
#include "util.h" #include "util.h"
#include "stage3.h" #include "stage3.h"
const uint64_t MIN_CHOICE = 'A' - 1; const size_t MIN_CHOICE = 'A' - 1;
const uint64_t MAX_CHOICE = 'Z' + 1; const size_t MAX_CHOICE = 'Z' + 1;
const uint64_t SECRET_LENGTH = 5; const size_t SECRET_LENGTH = 5;
static inline page_t *init_pages() { static inline page_t *init_pages(void) {
return calloc(MAX_CHOICE, sizeof(page_t)); return calloc(MAX_CHOICE + 1, sizeof(page_t));
} }
static inline void flush_all_pages(page_t *pages) { static inline void flush_all_pages(page_t *pages) {
...@@ -27,14 +23,16 @@ static inline size_t guess_accessed_page(page_t *pages) { ...@@ -27,14 +23,16 @@ static inline size_t guess_accessed_page(page_t *pages) {
return 0; return 0;
} }
static inline void do_access(page_t *probe_array, size_t idx) { static inline void do_access(page_t *pages, size_t secret_index) {
// TODO: Implement me using force_read. I am a very short function. // TODO: Implement me using force_read(). I am a very short function.
} }
int main() { int main() {
page_t *probe_array = init_pages(); page_t *pages = init_pages();
// TODO: Copy me from the previous stage and edit me so I loop over SECRET_LENGTH characters. /* TODO: Copy me from the previous stage and edit me
* to loop over SECRET_LENGTH characters. */
printf("\n"); printf("\n");
free(pages);
} }
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h> #include <stdio.h>
#include <unistd.h> #include <stdlib.h>
#define __USE_GNU #define __USE_GNU
#include <signal.h> #include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "util.h" #include "util.h"
#include "stage4.h" #include "stage4.h"
extern char label[]; extern uint8_t label[];
const uint64_t MIN_CHOICE = 'A' - 1; const size_t MIN_CHOICE = 'A' - 1;
const uint64_t MAX_CHOICE = 'Z' + 1; const size_t MAX_CHOICE = 'Z' + 1;
const uint64_t SECRET_LENGTH = 5; const size_t SECRET_LENGTH = 5;
static inline page_t *init_pages() { static inline page_t *init_pages(void) {
return calloc(MAX_CHOICE, sizeof(page_t)); return calloc(MAX_CHOICE + 1, sizeof(page_t));
} }
static inline void flush_all_pages(page_t *pages) { static inline void flush_all_pages(page_t *pages) {
// TODO: Copy me from the previous stage // TODO: Copy me from the previous stage
} }
...@@ -33,19 +28,18 @@ static inline size_t guess_accessed_page(page_t *pages) { ...@@ -33,19 +28,18 @@ static inline size_t guess_accessed_page(page_t *pages) {
return 0; return 0;
} }
static inline void do_access(page_t *probe_array, size_t idx) { static inline void do_access(page_t *pages, size_t secret_index) {
// TODO: Copy me from the previous stage. // TODO: Copy me from the previous stage.
// Don't forget to call cache_secret() to ensure the secret is in memory. // Don't forget to call cache_secret() to ensure the secret is in memory.
} }
// TODO: Implement a SIGSEGV handler // TODO: Implement a SIGSEGV handler
int main() { int main() {
// TODO: Implement install your SIGSEGV handler // TODO: Install your SIGSEGV handler
// TODO: For the remainder of the function, copy from the previous stage and edit the following:
// 1. Add asm volatile("label:") to the location you want the SIGSEGV handler to return to. /* TODO: Copy the code from the previous stage and edit the following:
// 2. For each letter, it might take more than one attempt to get a valid guess. Throw all the logic in an inner loop. * 1. Add `asm volatile("label:")` where you want the SIGSEGV handler to return to.
* 2. For each letter, it might take more than one attempt to get a cache hit.
* Throw all the logic in an inner loop. */
} }
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