diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -2020,5 +2020,50 @@ return sec; } +template +SyscallReturn +tgkillFunc(SyscallDesc *desc, int num, Process *process, ThreadContext *tc) +{ + int index = 0; + int tgid = process->getSyscallArg(tc, index); + int tid = process->getSyscallArg(tc, index); + int sig = process->getSyscallArg(tc, index); + + // This system call is intended to allow killing a specific thread + // within an arbitrary thread group if sanctioned with permission checks. + // It's usually true that threads share the termination signal as pointed + // out by the pthread_kill man page and this seems to be the intended + // usage. Due to this being an emulated environment, assume the following: + // Threads are allowed to call tgkill because the EUID for all threads + // should be the same. There is no signal handling mechanism for kernel + // registration of signal handlers since signals are poorly supported in + // emulation mode. Since signal handlers cannot be registered, all + // threads within in a thread group must share the termination signal. + // We never exhaust PIDs so there's no chance of finding the wrong one + // due to PID rollover. + + System *sys = tc->getSystemPtr(); + Process *tgt_proc = nullptr; + for (int i = 0; tgt_proc == nullptr && i < sys->numContexts(); i++) { + Process *temp = sys->threadContexts[i]->getProcessPtr(); + if (temp->pid() == tid) + tgt_proc = temp; + } + + if (sig != 0 || sig != OS::TGT_SIGABRT) + return -EINVAL; + + if (tgt_proc == nullptr) + return -ESRCH; + + if (tgid != -1 && tgt_proc->tgid() != tgid) + return -ESRCH; + + if (sig == OS::TGT_SIGABRT) + exitGroupFunc(desc, 252, process, tc); + + return 0; +} + #endif // __SIM_SYSCALL_EMUL_HH__ # Node ID 616cb12be937b290767c2b8a76ba8c6351088684 # Parent 7339faceb7bfeb701029c836a7b7cc028ee30eba diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc --- a/src/arch/x86/linux/process.cc +++ b/src/arch/x86/linux/process.cc @@ -454,7 +454,7 @@ /* 231 */ SyscallDesc("exit_group", exitGroupFunc), /* 232 */ SyscallDesc("epoll_wait", unimplementedFunc), /* 233 */ SyscallDesc("epoll_ctl", unimplementedFunc), - /* 234 */ SyscallDesc("tgkill", unimplementedFunc), + /* 234 */ SyscallDesc("tgkill", tgkillFunc), /* 235 */ SyscallDesc("utimes", unimplementedFunc), /* 236 */ SyscallDesc("vserver", unimplementedFunc), /* 237 */ SyscallDesc("mbind", unimplementedFunc), @@ -819,7 +819,7 @@ /* 267 */ SyscallDesc("clock_nanosleep", unimplementedFunc), /* 268 */ SyscallDesc("statfs64", unimplementedFunc), /* 269 */ SyscallDesc("fstatfs64", unimplementedFunc), - /* 270 */ SyscallDesc("tgkill", unimplementedFunc), + /* 270 */ SyscallDesc("tgkill", tgkillFunc), /* 271 */ SyscallDesc("utimes", unimplementedFunc), /* 272 */ SyscallDesc("fadvise64_64", unimplementedFunc), /* 273 */ SyscallDesc("vserver", unimplementedFunc),