LF OS
Hobby operating system for amd64 with high ambitions
Loading...
Searching...
No Matches
syscall-stack.cxx
Go to the documentation of this file.
1#include <wchar.h>
2#include <stdint.h>
3
4#include <sys/syscalls.h>
5
6#include <gtest/gtest.h>
7
8TEST(StackCorruption, Syscall) {
9 static const wchar_t pattern = 0x1F05;
10 volatile wchar_t data_on_stack[512];
11 wmemset((wchar_t*)data_on_stack, pattern, sizeof(data_on_stack) / sizeof(wchar_t));
12
13 // make sure the array is filled as expected
14 for(size_t i = 0; i < sizeof(data_on_stack) / sizeof(wchar_t); ++i) {
15 EXPECT_EQ(data_on_stack[i], pattern);
16 }
17
18 // static to make them life in .data instead of the stack
19 static uint64_t rsp_before, rsp_after;
20 static uint64_t rbp_before, rbp_after;
21
22 asm volatile(" \n\
23 mov %%rsp, %0 \n\
24 mov %%rbp, %1 \n\
25 "
26 :
27 "=m"(rsp_before),
28 "=m"(rbp_before)
29 );
30
31 sc_do_scheduler_sleep(0);
32
33 asm volatile(" \n\
34 mov %%rsp, %0 \n\
35 mov %%rbp, %1 \n\
36 "
37 :
38 "=m"(rsp_after),
39 "=m"(rbp_after)
40 );
41
42 EXPECT_EQ(rsp_before, rsp_after);
43 EXPECT_EQ(rbp_before, rbp_after);
44
45 for(size_t i = 0; i < sizeof(data_on_stack) / sizeof(wchar_t); ++i) {
46 EXPECT_EQ(data_on_stack[i], pattern);
47 }
48}
49
50TEST(StackCorruption, Interrupts) {
51 uint64_t error = 0;
52 sc_do_hardware_interrupt_notify(0, true, 0, &error);
53 EXPECT_EQ(error, 0);
54
55 static const wchar_t pattern = 0x1F05;
56 volatile wchar_t data_on_stack[512];
57 wmemset((wchar_t*)data_on_stack, pattern, sizeof(data_on_stack) / sizeof(wchar_t));
58
59 // make sure the array is filled as expected
60 for(size_t i = 0; i < sizeof(data_on_stack) / sizeof(wchar_t); ++i) {
61 EXPECT_EQ(data_on_stack[i], pattern);
62 }
63
64 // static to make them life in .data instead of the stack
65 static uint64_t rsp_before, rsp_after;
66 static uint64_t rbp_before, rbp_after;
67
68 asm volatile(" \n\
69 mov %%rsp, %0 \n\
70 mov %%rbp, %1 \n\
71 "
72 :
73 "=m"(rsp_before),
74 "=m"(rbp_before)
75 );
76
77 bool received = false;
78
79 Message* msg = (Message*)malloc(sizeof(Message));
80 memset(msg, 0, sizeof(Message));
81 msg->size = sizeof(Message);
82
83 while(!received) {
84 sc_do_ipc_mq_poll(0, true, msg, &error);
85
86 if(error == EMSGSIZE) {
87 size_t size = msg->size;
88 msg = (Message*)realloc(msg, size);
89 memset(msg, 0, size);
90 msg->size = size;
91 }
92 else if(error == 0) {
93 EXPECT_EQ(msg->type, MT_HardwareInterrupt);
94 EXPECT_EQ(msg->user_data.HardwareInterrupt.interrupt, 0);
95
96 received = true;
97 }
98 else if(error != EAGAIN) {
99 FAIL();
100 }
101 }
102
103 asm volatile(" \n\
104 mov %%rsp, %0 \n\
105 mov %%rbp, %1 \n\
106 "
107 :
108 "=m"(rsp_after),
109 "=m"(rbp_after)
110 );
111
112 EXPECT_EQ(rsp_before, rsp_after);
113 EXPECT_EQ(rbp_before, rbp_after);
114
115 for(size_t i = 0; i < sizeof(data_on_stack) / sizeof(wchar_t); ++i) {
116 EXPECT_EQ(data_on_stack[i], pattern);
117 }
118}
unsigned long uint64_t
Definition arch.h:14
#define EMSGSIZE
Definition errno-defs.h:33
#define EAGAIN
Definition errno-defs.h:10
void * memset(void *dest, int c, size_t size)
Definition string.c:72
void * malloc(size_t size)
Definition string.c:169
void * realloc(void *ptr, size_t size)
Definition string.c:184
uint16_t size
Size of the loaded file.
Definition loader.h:5
struct Message::UserData::HardwareInterruptUserData HardwareInterrupt
size_t size
Size of the message, including metadata.
union Message::UserData user_data
@ MT_HardwareInterrupt
enum MessageType type
Type of the message.
TEST(StackCorruption, Syscall)
static uint16_t bool uint64_t * error
Definition syscalls.h:126