mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 09:48:11 +00:00
LibC: Ignore signals that don't have a name in getsignalbyname()
This prevents a segfault in `kill` and `killall` when an invalid signal name is given.
This commit is contained in:
parent
f0edf00dc0
commit
a041f1671c
2 changed files with 58 additions and 73 deletions
|
@ -128,39 +128,53 @@ int sigpending(sigset_t* set)
|
||||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Signal 0 (the null signal) and Signal 32 (SIGCANCEL) are deliberately set to null here.
|
||||||
|
// They are not intended to be resolved by strsignal(), getsignalname() or getsignalbyname().
|
||||||
|
#define ENUMERATE_SIGNALS \
|
||||||
|
__ENUMERATE_SIGNAL(nullptr, nullptr) \
|
||||||
|
__ENUMERATE_SIGNAL("HUP", "Hangup") \
|
||||||
|
__ENUMERATE_SIGNAL("INT", "Interrupt") \
|
||||||
|
__ENUMERATE_SIGNAL("QUIT", "Quit") \
|
||||||
|
__ENUMERATE_SIGNAL("ILL", "Illegal instruction") \
|
||||||
|
__ENUMERATE_SIGNAL("TRAP", "Trap") \
|
||||||
|
__ENUMERATE_SIGNAL("ABRT", "Aborted") \
|
||||||
|
__ENUMERATE_SIGNAL("BUS", "Bus error") \
|
||||||
|
__ENUMERATE_SIGNAL("FPE", "Division by zero") \
|
||||||
|
__ENUMERATE_SIGNAL("KILL", "Killed") \
|
||||||
|
__ENUMERATE_SIGNAL("USR1", "User signal 1") \
|
||||||
|
__ENUMERATE_SIGNAL("SEGV", "Segmentation violation") \
|
||||||
|
__ENUMERATE_SIGNAL("USR2", "User signal 2") \
|
||||||
|
__ENUMERATE_SIGNAL("PIPE", "Broken pipe") \
|
||||||
|
__ENUMERATE_SIGNAL("ALRM", "Alarm clock") \
|
||||||
|
__ENUMERATE_SIGNAL("TERM", "Terminated") \
|
||||||
|
__ENUMERATE_SIGNAL("STKFLT", "Stack fault") \
|
||||||
|
__ENUMERATE_SIGNAL("CHLD", "Child exited") \
|
||||||
|
__ENUMERATE_SIGNAL("CONT", "Continued") \
|
||||||
|
__ENUMERATE_SIGNAL("STOP", "Stopped (signal)") \
|
||||||
|
__ENUMERATE_SIGNAL("TSTP", "Stopped") \
|
||||||
|
__ENUMERATE_SIGNAL("TTIN", "Stopped (tty input)") \
|
||||||
|
__ENUMERATE_SIGNAL("TTOU", "Stopped (tty output)") \
|
||||||
|
__ENUMERATE_SIGNAL("URG", "Urgent I/O condition)") \
|
||||||
|
__ENUMERATE_SIGNAL("XCPU", "CPU limit exceeded") \
|
||||||
|
__ENUMERATE_SIGNAL("XFSZ", "File size limit exceeded") \
|
||||||
|
__ENUMERATE_SIGNAL("VTALRM", "Virtual timer expired") \
|
||||||
|
__ENUMERATE_SIGNAL("PROF", "Profiling timer expired") \
|
||||||
|
__ENUMERATE_SIGNAL("WINCH", "Window changed") \
|
||||||
|
__ENUMERATE_SIGNAL("IO", "I/O possible") \
|
||||||
|
__ENUMERATE_SIGNAL("INFO", "Power failure") \
|
||||||
|
__ENUMERATE_SIGNAL("SYS", "Bad system call") \
|
||||||
|
__ENUMERATE_SIGNAL(nullptr, nullptr)
|
||||||
|
|
||||||
char const* sys_siglist[NSIG] = {
|
char const* sys_siglist[NSIG] = {
|
||||||
"Invalid signal number",
|
#define __ENUMERATE_SIGNAL(name, description) description,
|
||||||
"Hangup",
|
ENUMERATE_SIGNALS
|
||||||
"Interrupt",
|
#undef __ENUMERATE_SIGNAL
|
||||||
"Quit",
|
};
|
||||||
"Illegal instruction",
|
|
||||||
"Trap",
|
char const* sys_signame[NSIG] = {
|
||||||
"Aborted",
|
#define __ENUMERATE_SIGNAL(name, description) name,
|
||||||
"Bus error",
|
ENUMERATE_SIGNALS
|
||||||
"Division by zero",
|
#undef __ENUMERATE_SIGNAL
|
||||||
"Killed",
|
|
||||||
"User signal 1",
|
|
||||||
"Segmentation violation",
|
|
||||||
"User signal 2",
|
|
||||||
"Broken pipe",
|
|
||||||
"Alarm clock",
|
|
||||||
"Terminated",
|
|
||||||
"Stack fault",
|
|
||||||
"Child exited",
|
|
||||||
"Continued",
|
|
||||||
"Stopped (signal)",
|
|
||||||
"Stopped",
|
|
||||||
"Stopped (tty input)",
|
|
||||||
"Stopped (tty output)",
|
|
||||||
"Urgent I/O condition)",
|
|
||||||
"CPU limit exceeded",
|
|
||||||
"File size limit exceeded",
|
|
||||||
"Virtual timer expired",
|
|
||||||
"Profiling timer expired",
|
|
||||||
"Window changed",
|
|
||||||
"I/O possible",
|
|
||||||
"Power failure",
|
|
||||||
"Bad system call",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/siglongjmp.html
|
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/siglongjmp.html
|
||||||
|
@ -210,48 +224,14 @@ int sigtimedwait(sigset_t const* set, siginfo_t* info, struct timespec const* ti
|
||||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char const* sys_signame[] = {
|
|
||||||
"INVAL",
|
|
||||||
"HUP",
|
|
||||||
"INT",
|
|
||||||
"QUIT",
|
|
||||||
"ILL",
|
|
||||||
"TRAP",
|
|
||||||
"ABRT",
|
|
||||||
"BUS",
|
|
||||||
"FPE",
|
|
||||||
"KILL",
|
|
||||||
"USR1",
|
|
||||||
"SEGV",
|
|
||||||
"USR2",
|
|
||||||
"PIPE",
|
|
||||||
"ALRM",
|
|
||||||
"TERM",
|
|
||||||
"STKFLT",
|
|
||||||
"CHLD",
|
|
||||||
"CONT",
|
|
||||||
"STOP",
|
|
||||||
"TSTP",
|
|
||||||
"TTIN",
|
|
||||||
"TTOU",
|
|
||||||
"URG",
|
|
||||||
"XCPU",
|
|
||||||
"XFSZ",
|
|
||||||
"VTALRM",
|
|
||||||
"PROF",
|
|
||||||
"WINCH",
|
|
||||||
"IO",
|
|
||||||
"INFO",
|
|
||||||
"SYS",
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(sys_signame) == sizeof(char const*) * NSIG);
|
|
||||||
|
|
||||||
int getsignalbyname(char const* name)
|
int getsignalbyname(char const* name)
|
||||||
{
|
{
|
||||||
VERIFY(name);
|
VERIFY(name);
|
||||||
StringView name_sv { name, strlen(name) };
|
StringView name_sv { name, strlen(name) };
|
||||||
for (size_t i = 0; i < NSIG; ++i) {
|
for (size_t i = 1; i < NSIG; ++i) {
|
||||||
|
if (!sys_signame[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
StringView signal_name { sys_signame[i], strlen(sys_signame[i]) };
|
StringView signal_name { sys_signame[i], strlen(sys_signame[i]) };
|
||||||
if (signal_name == name_sv || (name_sv.starts_with("SIG"sv) && signal_name == name_sv.substring_view(3)))
|
if (signal_name == name_sv || (name_sv.starts_with("SIG"sv) && signal_name == name_sv.substring_view(3)))
|
||||||
return i;
|
return i;
|
||||||
|
@ -262,10 +242,15 @@ int getsignalbyname(char const* name)
|
||||||
|
|
||||||
char const* getsignalname(int signal)
|
char const* getsignalname(int signal)
|
||||||
{
|
{
|
||||||
if (signal < 0 || signal >= NSIG) {
|
if (signal <= 0 || signal >= NSIG) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return sys_signame[signal];
|
|
||||||
|
auto const* result = sys_signame[signal];
|
||||||
|
if (!result)
|
||||||
|
errno = EINVAL;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -340,7 +340,7 @@ char* strerror(int errnum)
|
||||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/strsignal.html
|
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/strsignal.html
|
||||||
char* strsignal(int signum)
|
char* strsignal(int signum)
|
||||||
{
|
{
|
||||||
if (signum >= NSIG) {
|
if (signum <= 0 || signum >= NSIG || !sys_siglist[signum]) {
|
||||||
dbgln("strsignal() missing string for signum={}", signum);
|
dbgln("strsignal() missing string for signum={}", signum);
|
||||||
return const_cast<char*>("Unknown signal");
|
return const_cast<char*>("Unknown signal");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue