Skip to content

Commit

Permalink
[signal] Handle corner case: setting up user stack faults
Browse files Browse the repository at this point in the history
  • Loading branch information
vvaltchev committed Jun 12, 2022
1 parent e7df2c4 commit 0a3159d
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 17 deletions.
10 changes: 5 additions & 5 deletions include/tilck/kernel/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ void process_set_cwd2_nolock(struct vfs_path *tp);
void process_set_cwd2_nolock_raw(struct process *pi, struct vfs_path *tp);
void terminate_process(int exit_code, int term_sig);
void close_cloexec_handles(struct process *pi);
void setup_sig_handler(struct task *ti,
enum sig_state sig_state,
regs_t *r,
ulong user_func,
int signum);
int setup_sig_handler(struct task *ti,
enum sig_state sig_state,
regs_t *r,
ulong user_func,
int signum);
void setup_pause_trampoline(regs_t *r);
25 changes: 14 additions & 11 deletions kernel/arch/i386/process32.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ push_args_on_user_stack(regs_t *r,
return 0;
}

static void save_regs_on_user_stack(regs_t *r)
static int save_regs_on_user_stack(regs_t *r)
{
ulong new_useresp = r->useresp;
int rc;
Expand All @@ -155,14 +155,13 @@ static void save_regs_on_user_stack(regs_t *r)
rc = copy_to_user(TO_PTR(new_useresp), r, sizeof(*r));

if (rc) {
/* Oops, stack overflow: terminate the process */
enable_preemption();
terminate_process(0, SIGSEGV);
NOT_REACHED();
/* Oops, stack overflow */
return -EFAULT;
}

/* Now, after we saved the registers, update r->useresp */
r->useresp = new_useresp;
return 0;
}

static void restore_regs_from_user_stack(regs_t *r)
Expand Down Expand Up @@ -200,18 +199,21 @@ void setup_pause_trampoline(regs_t *r)
) % USERMODE_STACK_ALIGN \
)

void setup_sig_handler(struct task *ti,
enum sig_state sig_state,
regs_t *r,
ulong user_func,
int signum)
int setup_sig_handler(struct task *ti,
enum sig_state sig_state,
regs_t *r,
ulong user_func,
int signum)
{
if (ti->nested_sig_handlers == 0) {

int rc;

if (sig_state == sig_pre_syscall)
r->eax = (ulong) -EINTR;

save_regs_on_user_stack(r);
if ((rc = save_regs_on_user_stack(r)) < 0)
return rc;
}

r->eip = user_func;
Expand All @@ -233,6 +235,7 @@ void setup_sig_handler(struct task *ti,
* 0xbfffce20 # it's already aligned at 16
*/
ASSERT(((r->useresp + sizeof(ulong)) & (USERMODE_STACK_ALIGN - 1)) == 0);
return 0;
}

ulong sys_rt_sigreturn(void)
Expand Down
8 changes: 7 additions & 1 deletion kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,13 @@ bool process_signals(void *__ti, enum sig_state sig_state, void *regs)
handler, ti->tid, get_signal_name(sig), sig);

del_pending_sig(ti, sig);
setup_sig_handler(ti, sig_state, regs, (ulong)handler, sig);

if (setup_sig_handler(ti, sig_state, regs, (ulong)handler, sig) < 0) {

/* We got a FAULT while trying to setup the user stack */
printk("WARNING: can't setup stack for task %d: kill\n", ti->tid);
kill_task_now_or_later(ti, regs, SIGKILL, sig_state);
}

} else {

Expand Down

0 comments on commit 0a3159d

Please sign in to comment.