Pass address of sigreturn as an arugment of signal and sigaction functions.

This commit is contained in:
Enrico Fraccaroli
2022-09-22 11:31:23 -04:00
parent 5e5b9ba370
commit 5a461aabb0
7 changed files with 30 additions and 36 deletions
-5
View File
@@ -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)
+16 -4
View File
@@ -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)
{
+2 -3
View File
@@ -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 processs signal handler descriptor
sighand_t sighand;
/// Mask of blocked signals.
+2 -2
View File
@@ -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.
-16
View File
@@ -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;
+1 -1
View File
@@ -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"
+9 -5
View File
@@ -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 = &current->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 = &current->sighand.action[signum - 1];
pr_debug("sys_sigaction(%d, %p, %p): : Signal old action ptr %p\n", signum, act, oldact, current_sigaction);