Pass address of sigreturn as an arugment of signal and sigaction functions.
This commit is contained in:
@@ -35,8 +35,3 @@ int __libc_start_main(int (*main)(int, char **, char **), int argc, char *argv[]
|
||||
//dbg_print("== END %-30s =======================================\n", argv[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
// WARNING: This declaration must be here, because libc_start is compiled
|
||||
// with all the programs, and all the programs NEED to have the `sigreturn`
|
||||
// symbol. It must be this way, period.
|
||||
_syscall0(int, sigreturn)
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
#include "signal.h"
|
||||
#include "sys/bitops.h"
|
||||
|
||||
_syscall0(int, sigreturn)
|
||||
|
||||
_syscall3(int, sigprocmask, int, how, const sigset_t *, set, sigset_t *, oldset)
|
||||
|
||||
static const char *sys_siglist[] = {
|
||||
"HUP",
|
||||
"INT",
|
||||
@@ -45,11 +49,19 @@ static const char *sys_siglist[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
_syscall2(sighandler_t, signal, int, signum, sighandler_t, handler)
|
||||
sighandler_t signal(int signum, sighandler_t handler)
|
||||
{
|
||||
long __res;
|
||||
__inline_syscall3(__res, signal, signum, handler, (unsigned int)sigreturn);
|
||||
__syscall_return(sighandler_t, __res);
|
||||
}
|
||||
|
||||
_syscall3(int, sigaction, int, signum, const sigaction_t *, act, sigaction_t *, oldact)
|
||||
|
||||
_syscall3(int, sigprocmask, int, how, const sigset_t *, set, sigset_t *, oldset)
|
||||
int sigaction(int signum, const sigaction_t *act, sigaction_t *oldact)
|
||||
{
|
||||
long __res;
|
||||
__inline_syscall4(__res, sigaction, signum, act, oldact, (unsigned int)sigreturn);
|
||||
__syscall_return(int, __res);
|
||||
}
|
||||
|
||||
const char *strsignal(int sig)
|
||||
{
|
||||
|
||||
@@ -119,9 +119,8 @@ typedef struct task_struct {
|
||||
/// The current working directory.
|
||||
char cwd[PATH_MAX];
|
||||
|
||||
// struct signal_struct *signal;
|
||||
/// Instruction Pointer of the LIBC Signal Handler.
|
||||
uint32_t sigreturn_eip;
|
||||
/// Address of the LIBC sigreturn function.
|
||||
uint32_t sigreturn_addr;
|
||||
/// Pointer to the process’s signal handler descriptor
|
||||
sighand_t sighand;
|
||||
/// Mask of blocked signals.
|
||||
|
||||
@@ -269,14 +269,14 @@ int sys_kill(pid_t pid, int sig);
|
||||
/// @param signum The signal number.
|
||||
/// @param handler The handler for the signal.
|
||||
/// @return The previous value of the signal handler, or SIG_ERR on error.
|
||||
sighandler_t sys_signal(int signum, sighandler_t handler);
|
||||
sighandler_t sys_signal(int signum, sighandler_t handler, uint32_t sigreturn_addr);
|
||||
|
||||
/// @brief Examine and change a signal action.
|
||||
/// @param signum Specifies the signal and can be any valid signal except SIGKILL and SIGSTOP.
|
||||
/// @param act If non-NULL, the new action for signal signum is installed from act.
|
||||
/// @param oldact If non-NULL, the previous action is saved in oldact.
|
||||
/// @return returns 0 on success; on error, -1 is returned, and errno is set to indicate the error.
|
||||
int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact);
|
||||
int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact, uint32_t sigreturn_addr);
|
||||
|
||||
/// @brief Examine and change blocked signals.
|
||||
/// @param how Determines the behavior of the call.
|
||||
|
||||
@@ -222,17 +222,6 @@ static inline void elf_dump_symbol_table(elf_header_t *header)
|
||||
// EXEC-RELATED FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
static inline int elf_set_sigreturn(elf_header_t *header, task_struct *task)
|
||||
{
|
||||
elf_symbol_t *sigreturn = elf_find_symbol(header, "sigreturn");
|
||||
if (sigreturn == NULL) {
|
||||
pr_err("Failed to find `sigreturn`!\n");
|
||||
return false;
|
||||
}
|
||||
task->sigreturn_eip = sigreturn->value;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief Loads an ELF executable.
|
||||
/// @param task The task for which we load the ELF.
|
||||
/// @param file The ELF file.
|
||||
@@ -311,11 +300,6 @@ int elf_load_file(task_struct *task, vfs_file_t *file, uint32_t *entry)
|
||||
pr_err("Elf file is not an executable.\n");
|
||||
goto return_error_free_buffer;
|
||||
}
|
||||
// Set the sigreturn of the task.
|
||||
if (!elf_set_sigreturn(header, task)) {
|
||||
pr_err("Failed to set `sigreturn` for the executable.\n");
|
||||
goto return_error_free_buffer;
|
||||
}
|
||||
if (!elf_load_exec(header, task)) {
|
||||
pr_err("Failed to load the executable.\n");
|
||||
goto return_error_free_buffer;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
/// Change the header.
|
||||
#define __DEBUG_HEADER__ "[EXT2 ]"
|
||||
/// Set the log level.
|
||||
#define __DEBUG_LEVEL__ LOGLEVEL_DEBUG
|
||||
#define __DEBUG_LEVEL__ LOGLEVEL_NOTICE
|
||||
|
||||
#include "process/scheduler.h"
|
||||
#include "process/process.h"
|
||||
|
||||
@@ -300,7 +300,7 @@ static inline int __handle_signal(int signr, siginfo_t *info, sigaction_t *ka, s
|
||||
PUSH_VALUE_ON_STACK(regs->useresp, signr);
|
||||
|
||||
// Push on the stack the function required to handle the signal return.
|
||||
PUSH_VALUE_ON_STACK(regs->useresp, current->sigreturn_eip);
|
||||
PUSH_VALUE_ON_STACK(regs->useresp, current->sigreturn_addr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -631,9 +631,9 @@ int sys_kill(pid_t pid, int sig)
|
||||
return __send_sig_info(sig, &info, current);
|
||||
}
|
||||
|
||||
sighandler_t sys_signal(int signum, sighandler_t handler)
|
||||
sighandler_t sys_signal(int signum, sighandler_t handler, uint32_t sigreturn_addr)
|
||||
{
|
||||
pr_debug("sys_signal(%d, %p)\n", signum, handler);
|
||||
pr_debug("sys_signal(%d, %p, %p)\n", signum, handler, sigreturn_ptr);
|
||||
// Check the signal that we want to send.
|
||||
if ((signum < 0) || (signum >= NSIG)) {
|
||||
pr_err("sys_signal(%d, %p): Wrong signal number!\n", signum, handler);
|
||||
@@ -658,6 +658,8 @@ sighandler_t sys_signal(int signum, sighandler_t handler)
|
||||
sigemptyset(&new_sigaction.sa_mask);
|
||||
// Lock the signal handling for the given task.
|
||||
__lock_task_sighand(current);
|
||||
// Set the address of the sigreturn.
|
||||
current->sigreturn_addr = sigreturn_addr;
|
||||
// Get the old sigaction.
|
||||
sigaction_t *old_sigaction = ¤t->sighand.action[signum - 1];
|
||||
pr_err("sys_signal(%d, %p): Signal action ptr %p\n", signum, handler, old_sigaction);
|
||||
@@ -672,9 +674,9 @@ sighandler_t sys_signal(int signum, sighandler_t handler)
|
||||
return old_handler;
|
||||
}
|
||||
|
||||
int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact)
|
||||
int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact, uint32_t sigreturn_addr)
|
||||
{
|
||||
pr_debug("sys_sigaction(%d, %p, %p)\n", signum, act, oldact);
|
||||
pr_debug("sys_sigaction(%d, %p, %p, %p)\n", signum, act, oldact, sigreturn_ptr);
|
||||
// Check the signal that we want to send.
|
||||
if ((signum < 0) || (signum >= NSIG)) {
|
||||
pr_err("sys_sigaction(%d, %p, %p): Wrong signal number!\n", signum, act, oldact);
|
||||
@@ -691,6 +693,8 @@ int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact)
|
||||
}
|
||||
// Lock the signal handling for the given task.
|
||||
__lock_task_sighand(current);
|
||||
// Set the address of the sigreturn.
|
||||
current->sigreturn_addr = sigreturn_addr;
|
||||
// Get a pointer to the entry in the sighand.action array.
|
||||
sigaction_t *current_sigaction = ¤t->sighand.action[signum - 1];
|
||||
pr_debug("sys_sigaction(%d, %p, %p): : Signal old action ptr %p\n", signum, act, oldact, current_sigaction);
|
||||
|
||||
Reference in New Issue
Block a user