Compare commits

...

2 Commits

Author SHA1 Message Date
5f5b58a2c0
apps: Add a syscall fuzzer
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-08 19:58:00 +02:00
d0b65674e6
kernel: Fix 0-delay sleeps blocking the thread forever 2023-06-08 19:57:38 +02:00
4 changed files with 78 additions and 1 deletions

View File

@ -30,3 +30,4 @@ luna_app(ps.cpp ps)
luna_app(time.cpp time)
luna_app(ln.cpp ln)
luna_app(mktemp.cpp mktemp)
luna_app(sysfuzz.cpp sysfuzz)

73
apps/sysfuzz.cpp Normal file
View File

@ -0,0 +1,73 @@
#include <luna/Syscall.h>
#include <os/ArgumentParser.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
static const char* syscall_list[] = {
#undef __enumerate
#define __enumerate(name) #name,
enumerate_syscalls(__enumerate)
#undef __enumerate
};
int random_syscall()
{
int sys;
while (true)
{
sys = rand() % Syscalls::__count;
if (sys == SYS_exit || sys == SYS_usleep || sys == SYS_fork) continue;
break;
}
return sys;
}
void random_args(int args[5])
{
for (int i = 0; i < 5; i++) { args[i] = rand(); }
}
int main(int argc, char** argv)
{
StringView times_sv = "20"_sv;
StringView interval_sv = "1000"_sv;
os::ArgumentParser parser;
parser.add_description("System call fuzzer (invokes system calls with random arguments to test system stability)");
parser.add_system_program_info("sysfuzz"_sv);
parser.add_value_argument(times_sv, 't', "times"_sv, true, "the number of syscalls to invoke"_sv);
parser.add_value_argument(interval_sv, 'i', "interval"_sv, true,
"the interval between system calls (in milliseconds)"_sv);
parser.parse(argc, argv);
srand((unsigned)time(nullptr));
int times = atoi(times_sv.chars());
int interval = atoi(interval_sv.chars());
while (times--)
{
int args[5];
int sys = random_syscall();
random_args(args);
printf("%s(%d, %d, %d, %d, %d) -> ", syscall_list[sys], args[0], args[1], args[2], args[3], args[4]);
long rc = syscall(sys, args[0], args[1], args[2], args[3], args[4]);
if (rc < 0)
{
int error = (int)-rc;
printf("%ld (%s)\n", rc, strerror(error));
}
else
printf("%ld\n", rc);
usleep(interval * 1000);
}
}

View File

@ -6,6 +6,9 @@ Result<u64> sys_usleep(Registers*, SyscallArgs args)
{
useconds_t us = (useconds_t)args[0];
// FIXME: Allow usleep() to use a more precise resolution.
if (us < 1000) return 0;
kernel_sleep(us / 1000);
return 0;

View File

@ -271,7 +271,7 @@ namespace Scheduler
{
if (thread->state == ThreadState::Sleeping)
{
if (--thread->sleep_ticks_left == 0) thread->wake_up();
if (thread->sleep_ticks_left == 0 || --thread->sleep_ticks_left == 0) thread->wake_up();
}
}