vfs: check userland buffers before reading them.
[haiku.git] / src / system / kernel / arch / x86 / 32 / signals.cpp
blobfe3913f95ea6b1e46ba1a4d0b5b1b26ba5116b09
1 /*
2 * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "x86_signals.h"
9 #include <string.h>
11 #include <KernelExport.h>
13 #include <commpage.h>
14 #include <cpu.h>
15 #include <elf.h>
16 #include <smp.h>
18 #include "syscall_numbers.h"
21 // implemented in assembly
22 extern "C" void x86_signal_frame_function_beos(signal_frame_data* frameData);
25 extern "C" void
26 x86_signal_frame_function(signal_frame_data* frameData)
28 // Note: This function is copied to the commpage. Hence it needs to be
29 // position independent. We don't build this source file with the respective
30 // flags, but the code the compiler generates for this function is position
31 // independent anyway. It simply doesn't contain constructs that could
32 // result in position dependent code. The potentially problematic jumps
33 // needed due to the "if" statement are all harmless relative jumps.
35 if (frameData->siginfo_handler) {
36 // SA_SIGINFO style handler function -- we additionally pass the user
37 // data pointer
38 void (*handler)(int, siginfo_t*, void*, void*)
39 = (void (*)(int, siginfo_t*, void*, void*))frameData->handler;
40 handler(frameData->info.si_signo, &frameData->info,
41 &frameData->context, frameData->user_data);
42 } else {
43 // Simple handler function -- we call it with additional user data
44 // pointer and vregs parameters. Note that unlike in BeOS the last
45 // parameter is a pointer to a vregs structure, while in BeOS the
46 // structure was passed be value. For setting up a BeOS binary
47 // compatible signal handler call x86_signal_frame_function_beos() is
48 // used instead.
49 void (*handler)(int, void*, vregs*)
50 = (void (*)(int, void*, vregs*))frameData->handler;
51 handler(frameData->info.si_signo, frameData->user_data,
52 &frameData->context.uc_mcontext);
55 #define TO_STRING_LITERAL_HELPER(number) #number
56 #define TO_STRING_LITERAL(number) TO_STRING_LITERAL_HELPER(number)
58 // call the restore_signal_frame() syscall -- does not return (here)
59 asm volatile(
60 // push frameData -- the parameter to restore_signal_frame()
61 "pushl %0;"
62 // push a dummy return value
63 "pushl $0;"
64 // syscall number to eax
65 "movl $" TO_STRING_LITERAL(SYSCALL_RESTORE_SIGNAL_FRAME) ", %%eax;"
66 // syscall
67 "int $99;"
68 :: "r"(frameData)
71 #undef TO_STRING_LITERAL_HELPER
72 #undef TO_STRING_LITERAL
76 static void
77 register_signal_handler_function(const char* functionName, int32 commpageIndex,
78 const char* commpageSymbolName, addr_t expectedAddress)
80 // look up the x86_signal_frame_function() symbol -- we have its address,
81 // but also need its size
82 elf_symbol_info symbolInfo;
83 if (elf_lookup_kernel_symbol(functionName, &symbolInfo)
84 != B_OK) {
85 panic("x86_initialize_commpage_signal_handler(): Failed to find "
86 "signal frame function \"%s\"!", functionName);
89 ASSERT(expectedAddress == symbolInfo.address);
91 // fill in the commpage table entry
92 addr_t position = fill_commpage_entry(commpageIndex,
93 (void*)symbolInfo.address, symbolInfo.size);
95 // add symbol to the commpage image
96 image_id image = get_commpage_image();
97 elf_add_memory_image_symbol(image, commpageSymbolName, position,
98 symbolInfo.size, B_SYMBOL_TYPE_TEXT);
102 void
103 x86_initialize_commpage_signal_handler()
105 // standard handler
106 register_signal_handler_function("x86_signal_frame_function",
107 COMMPAGE_ENTRY_X86_SIGNAL_HANDLER, "commpage_signal_handler",
108 (addr_t)&x86_signal_frame_function);
110 // handler for BeOS backwards compatibility
111 register_signal_handler_function("x86_signal_frame_function_beos",
112 COMMPAGE_ENTRY_X86_SIGNAL_HANDLER_BEOS, "commpage_signal_handler_beos",
113 (addr_t)&x86_signal_frame_function_beos);
117 addr_t
118 x86_get_user_signal_handler_wrapper(bool beosHandler, void* commPageAdddress)
120 int32 index = beosHandler
121 ? COMMPAGE_ENTRY_X86_SIGNAL_HANDLER_BEOS
122 : COMMPAGE_ENTRY_X86_SIGNAL_HANDLER;
123 return ((addr_t*)commPageAdddress)[index] + (addr_t)commPageAdddress;